From gitlab at gitlab.haskell.org Mon Apr 1 00:03:55 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 31 Mar 2024 20:03:55 -0400 Subject: [Git][ghc/ghc][master] EPA: Extend StringLiteral range to include trailing commas Message-ID: <6609f9ebe9a10_23d1488b27482416a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - 2 changed files: - compiler/GHC/Parser.y - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -4559,7 +4559,8 @@ addTrailingCommaN (L anns a) span = do return (L anns' a) addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral -addTrailingCommaS (L l sl) span = L l (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) +addTrailingCommaS (L l sl) span + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) -- ------------------------------------- ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -652,6 +652,10 @@ printSourceText :: (Monad m, Monoid w) => SourceText -> String -> EP w m () printSourceText (NoSourceText) txt = printStringAdvance txt >> return () printSourceText (SourceText txt) _ = printStringAdvance (unpackFS txt) >> return () +printSourceTextAA :: (Monad m, Monoid w) => SourceText -> String -> EP w m () +printSourceTextAA (NoSourceText) txt = printStringAtAA (EpaDelta (SameLine 0) []) txt >> return () +printSourceTextAA (SourceText txt) _ = printStringAtAA (EpaDelta (SameLine 0) []) (unpackFS txt) >> return () + -- --------------------------------------------------------------------- printStringAtSs :: (Monad m, Monoid w) => SrcSpan -> String -> EP w m () @@ -2099,7 +2103,7 @@ instance ExactPrint StringLiteral where setAnnotationAnchor a _ _ _ = a exact l@(StringLiteral src fs mcomma) = do - printSourceText src (show (unpackFS fs)) + printSourceTextAA src (show (unpackFS fs)) mapM_ (\r -> printStringAtRs r ",") mcomma return l View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00d3ecf0775c1a3f1ab8495e5e125f21d450394e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00d3ecf0775c1a3f1ab8495e5e125f21d450394e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 00:04:36 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 31 Mar 2024 20:04:36 -0400 Subject: [Git][ghc/ghc][master] clarify Note [Preproccesing invocations] Message-ID: <6609fa1471933_23d148a7cab0272d8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - 1 changed file: - compiler/GHC/SysTools/Cpp.hs Changes: ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -63,7 +63,22 @@ underlying program (the C compiler), the set of flags passed determines the behaviour of the preprocessor, and Cpp and HsCpp behave differently. Specifically, we rely on "traditional" (pre-standard) preprocessing semantics (which most compilers expose via the `-traditional` flag) when preprocessing -Haskell source. This avoids, e.g., the preprocessor removing C-style comments. +Haskell source. This avoids the following situations: + + * Removal of C-style comments, which are not comments in Haskell but valid + operators; + + * Errors due to an ANSI C preprocessor lexing the source and failing on + names with single quotes (TH quotes, ticked promoted constructors, + names with primes in them). + + Both of those cases may be subtle: gcc and clang permit C++-style // + comments in C code, and Data.Array and Data.Vector both export a // + operator whose type is such that a removed "comment" may leave code that + typechecks but does the wrong thing. Another example is that, since ANSI + C permits long character constants, an expression involving multiple + functions with primes in their names may not expand macros properly when + they occur between the primed functions. -} -- | Run either the Haskell preprocessor or the C preprocessor, as per the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efab3649b685d92b1856a62532b343ef70777612 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efab3649b685d92b1856a62532b343ef70777612 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 01:26:40 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Sun, 31 Mar 2024 21:26:40 -0400 Subject: [Git][ghc/ghc][wip/T23490-part2] Try replacing "req_th" with "req_interp" for T11462, T11525 Message-ID: <660a0d50a8a8c_23d1481488478303fb@gitlab.mail> Matthew Craven pushed to branch wip/T23490-part2 at Glasgow Haskell Compiler / GHC Commits: 45062519 by Matthew Craven at 2024-03-31T21:24:13-04:00 Try replacing "req_th" with "req_interp" for T11462, T11525 (A guess based on the test options used in the main plugins testdir.) - - - - - 1 changed file: - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -491,7 +491,7 @@ test('T10592', normal, compile, ['']) test('T11305', normal, compile, ['']) test('T11254', normal, compile, ['']) test('T11379', normal, compile, ['']) -test('T11462', [js_broken(22261), req_th], multi_compile, +test('T11462', [js_broken(22261), req_interp], multi_compile, [None, [('T11462_Plugin.hs', '-package ghc'), ('T11462.hs', '')], '-dynamic' if have_dynamic() else '']) test('T11480', normal, compile, ['']) @@ -559,7 +559,7 @@ test('T11723', normal, compile, ['']) test('T12987', normal, compile, ['']) test('T11736', normal, compile, ['']) test('T13248', expect_broken(13248), compile, ['']) -test('T11525', [js_broken(22261), req_th], multi_compile, +test('T11525', [js_broken(22261), req_interp], multi_compile, [None, [('T11525_Plugin.hs', '-package ghc'), ('T11525.hs', '')], '-dynamic' if have_dynamic() else '']) test('T12923_1', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4506251910cbc38296d9c014b4942fae18ff301b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4506251910cbc38296d9c014b4942fae18ff301b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 07:28:01 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 03:28:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24463 Message-ID: <660a62018b3e5_23d1483c792205255f@gitlab.mail> Simon Peyton Jones pushed new branch wip/T24463 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24463 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 08:38:30 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 04:38:30 -0400 Subject: [Git][ghc/ghc][wip/simplifier-tweaks] 14 commits: EPA: Extend StringLiteral range to include trailing commas Message-ID: <660a7286707c2_174ee1282850795cb@gitlab.mail> Simon Peyton Jones pushed to branch wip/simplifier-tweaks at Glasgow Haskell Compiler / GHC Commits: 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - ac55fe7a by Simon Peyton Jones at 2024-04-01T09:37:28+01:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 3e4ac7b3 by Simon Peyton Jones at 2024-04-01T09:37:28+01:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - f1b36c74 by Simon Peyton Jones at 2024-04-01T09:37:28+01:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 346a21f7 by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Spelling, layout, pretty-printing only - - - - - fae6aa6a by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 84236391 by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - 8e4bc1d5 by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - 54c038a8 by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - 42b4a18d by Simon Peyton Jones at 2024-04-01T09:37:29+01:00 Remove a long-commented-out line Pure refactoring - - - - - af913d6a by Simon Peyton Jones at 2024-04-01T09:37:32+01:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.1% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -4.0% PmSeriesV(normal) -1.7% T11195(normal) -1.3% T12227(normal) -20.5% GOOD T12545(normal) -3.2% T12707(normal) -2.2% GOOD T13253(normal) -1.5% T13253-spj(normal) +8.1% BAD T13386(normal) -3.0% GOOD T14766(normal) -2.7% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15703(normal) -14.8% GOOD T16577(normal) -2.3% GOOD T16875(normal) -0.1% T17516(normal) -39.7% GOOD T18140(normal) +1.1% T18223(normal) -17.2% GOOD T18282(normal) -5.1% GOOD T18304(normal) +10.8% BAD T18923(normal) -3.0% GOOD T19695(normal) -1.5% T20049(normal) -12.8% GOOD T21839c(normal) -4.3% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.9% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.8% GOOD T9961(normal) +1.8% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.4% parsing001(normal) +1.4% geo. mean -2.1% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T3294 T9961 - - - - - 616c0d4a by Simon Peyton Jones at 2024-04-01T09:38:19+01:00 Testsuite message changes from simplifier improvements - - - - - c556cf6d by Simon Peyton Jones at 2024-04-01T09:38:20+01:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 14 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6483e76a896546107d6323c9d43d9c63af3bf08b...c556cf6d71e096eb62851503fc04266d1e32895b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6483e76a896546107d6323c9d43d9c63af3bf08b...c556cf6d71e096eb62851503fc04266d1e32895b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 09:24:10 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 05:24:10 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 13 commits: EPA: Fix FamDecl range Message-ID: <660a7d3ab6f7b_174ee18f751487683@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - aa7f3683 by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 loader: Note down suggestion for needed_mods The associated ticket is #24600 - - - - - 83dad9ba by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - ea6384ca by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 Start writing test - - - - - 4e9433f7 by Alexis King at 2024-04-01T10:24:00+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym Write Note [Looking up symbols in the relevant objects] Write Note [Symbols may not be found in pkgs_loaded] Use lookupHsSymbol for PrimOps too - - - - - f0b8606f by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 wip: make addDLL wrapper around loadNativeObj - - - - - 089d1983 by Alexis King at 2024-04-01T10:24:00+01:00 wip: use loadNativeObj to implement addDLL - - - - - cd8e1bca by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 797b857c by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - a9e42fa9 by Rodrigo Mesquita at 2024-04-01T10:24:00+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 30 changed files: - + T23415/Makefile - + T23415/main.hs - + T23415/make_shared_libs.sh - + T23415/new-main.hs - + T23415/run_test.sh - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Runtime/Utils.hs - compiler/GHC/SysTools/Cpp.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/573b9729cabfbbc4810ae894ec7a6932ab24dcd3...a9e42fa9107949fd33a9fa91ffcdfe5369c51656 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/573b9729cabfbbc4810ae894ec7a6932ab24dcd3...a9e42fa9107949fd33a9fa91ffcdfe5369c51656 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 10:20:06 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 06:20:06 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a8a562961e_174ee1f3e8dc90130@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 223a1536 by Rodrigo Mesquita at 2024-04-01T11:19:19+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 22437881 by Rodrigo Mesquita at 2024-04-01T11:19:19+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - fdf78387 by Rodrigo Mesquita at 2024-04-01T11:19:19+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -419,9 +423,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; static regex_t re_invalid; static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ ===================================== rts/linker/Elf.c ===================================== @@ -32,6 +32,8 @@ #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2071,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2120,70 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex) + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a9e42fa9107949fd33a9fa91ffcdfe5369c51656...fdf783879bf9acc7af10e5c56b9cf84185e933fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a9e42fa9107949fd33a9fa91ffcdfe5369c51656...fdf783879bf9acc7af10e5c56b9cf84185e933fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 10:33:09 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 06:33:09 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a8d6526719_174ee111887789347f@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 96457f26 by Rodrigo Mesquita at 2024-04-01T11:32:51+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 6d4f7cb7 by Rodrigo Mesquita at 2024-04-01T11:32:51+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - eb6a101f by Rodrigo Mesquita at 2024-04-01T11:32:51+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -419,9 +423,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; static regex_t re_invalid; static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ ===================================== rts/linker/Elf.c ===================================== @@ -1,4 +1,5 @@ #include "Rts.h" +#include "rts/PosixSource.h" #if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) \ || defined(linux_android_HOST_OS) \ @@ -28,10 +29,13 @@ #include "linker/util.h" #include "linker/elf_util.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2122,73 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex) + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdf783879bf9acc7af10e5c56b9cf84185e933fb...eb6a101f293d4d2cfb976a1a37cb32b32722f26e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdf783879bf9acc7af10e5c56b9cf84185e933fb...eb6a101f293d4d2cfb976a1a37cb32b32722f26e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 10:33:56 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 06:33:56 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a8d948dad0_174ee1127c5d093749@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 4381c150 by Rodrigo Mesquita at 2024-04-01T11:33:40+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 7fa524ab by Rodrigo Mesquita at 2024-04-01T11:33:40+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - ab309fc8 by Rodrigo Mesquita at 2024-04-01T11:33:40+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -419,9 +423,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; static regex_t re_invalid; static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ ===================================== rts/linker/Elf.c ===================================== @@ -28,10 +28,13 @@ #include "linker/util.h" #include "linker/elf_util.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2072,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2121,73 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex) + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb6a101f293d4d2cfb976a1a37cb32b32722f26e...ab309fc8032173bcfa993778a0cc73e0a34e641b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb6a101f293d4d2cfb976a1a37cb32b32722f26e...ab309fc8032173bcfa993778a0cc73e0a34e641b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 10:38:03 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 06:38:03 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a8e8b4822d_174ee113a45709403d@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 78684d22 by Rodrigo Mesquita at 2024-04-01T11:37:46+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 6af9ab1c by Rodrigo Mesquita at 2024-04-01T11:37:46+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 5d3fbb9f by Rodrigo Mesquita at 2024-04-01T11:37:46+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -419,9 +423,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; static regex_t re_invalid; static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2122,73 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab309fc8032173bcfa993778a0cc73e0a34e641b...5d3fbb9f2d132e1a30f0c37f8af4f42b8c95e201 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab309fc8032173bcfa993778a0cc73e0a34e641b...5d3fbb9f2d132e1a30f0c37f8af4f42b8c95e201 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 10:57:57 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 06:57:57 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a9335c3e4_174ee1162a5c496539@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 2064e541 by Rodrigo Mesquita at 2024-04-01T11:57:38+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 181ae677 by Rodrigo Mesquita at 2024-04-01T11:57:38+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 09389a68 by Rodrigo Mesquita at 2024-04-01T11:57:38+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -419,9 +423,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; static regex_t re_invalid; static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -451,6 +447,11 @@ typedef struct _RtsSymbolInfo { #include "BeginPrivate.h" +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +extern static regex_t re_invalid; +extern static regex_t re_realso; +#endif + void exitLinker( void ); void freeObjectCode (ObjectCode *oc); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2122,70 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d3fbb9f2d132e1a30f0c37f8af4f42b8c95e201...09389a68224b1c01da226ebeb2359194d96c4293 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d3fbb9f2d132e1a30f0c37f8af4f42b8c95e201...09389a68224b1c01da226ebeb2359194d96c4293 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 11:02:45 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 01 Apr 2024 07:02:45 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] WIP Message-ID: <660a9455673c0_174ee117796649681a@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: 2459bcd9 by Jade at 2024-04-01T13:07:20+02:00 WIP - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs ===================================== @@ -1645,15 +1645,8 @@ Further improved using a four-way merge, with an additional performance increase https://gitlab.haskell.org/ghc/ghc/issues/24280 -} -{-# INLINEABLE sort #-} -sort = actualSort (>) - -{-# INLINEABLE sortBy #-} -sortBy cmp = actualSort (\x y -> cmp x y == GT) - -{-# INLINE actualSort #-} -actualSort :: (a -> a -> Bool) -> [a] -> [a] -actualSort gt ns +sort = sortBy compare +sortBy cmp ns | [] <- ns = [] | [a] <- ns = [a] | [a,b] <- ns = merge [a] [b] @@ -1661,6 +1654,8 @@ actualSort gt ns | [a,b,c,d] <- ns = merge4 [a] [b] [c] [d] | otherwise = merge_all (sequences ns) where + x `gt` y = x `cmp` y == GT + sequences (a:b:xs) | a `gt` b = descending b [a] xs | otherwise = ascending b (a:) xs @@ -1668,7 +1663,7 @@ actualSort gt ns descending a as (b:bs) | a `gt` b = descending b (a:as) bs - descending a as bs = (a:as) : sequences bs + descending a as bs = (a:as): sequences bs ascending a as (b:bs) | not (a `gt` b) = ascending b (\ys -> as (a:ys)) bs @@ -1676,16 +1671,16 @@ actualSort gt ns in x : sequences bs merge_all [x] = x - merge_all xs = merge_all (reduce_once xs) - - reduce_once [] = [] - reduce_once [a] = [a] - reduce_once [a,b] = [merge a b] - reduce_once [a,b,c] = [merge3 a b c] - reduce_once [a,b,c,d,e] = [merge a b, merge3 c d e] - reduce_once [a,b,c,d,e,f] = [merge3 a b c, merge3 d e f] - reduce_once (a:b:c:d:xs) = let !x = merge4 a b c d - in x : reduce_once xs + merge_all xs = merge_all (reduce xs) + + reduce [] = [] + reduce [a] = [a] + reduce [a,b] = [merge a b] + reduce [a,b,c] = [merge3 a b c] + reduce [a,b,c,d,e] = [merge a b, merge3 c d e] + reduce [a,b,c,d,e,f] = [merge3 a b c, merge3 d e f] + reduce (a:b:c:d:xs) = let !x = merge4 a b c d + in x : reduce xs merge as@(a:as') bs@(b:bs') | a `gt` b = b : merge as bs' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2459bcd9e6ae00359491d9f71a15be45e566c890 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2459bcd9e6ae00359491d9f71a15be45e566c890 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 11:03:12 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 07:03:12 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex Message-ID: <660a94701ea65_174ee1181369c974bb@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: ec24c9f7 by Rodrigo Mesquita at 2024-04-01T12:02:55+01:00 Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 9b7b7fca by Rodrigo Mesquita at 2024-04-01T12:02:55+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 62cb1b8e by Rodrigo Mesquita at 2024-04-01T12:02:55+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 12 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/LinkerInternals.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = putMVar (interpLookupSymbolCache interp) emptyUFM -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -578,8 +573,8 @@ static void * internal_dlsym(const char *symbol) { void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -587,7 +582,6 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } @@ -597,12 +591,10 @@ internal_dlsym(const char *symbol) { v = dlsym(nc->dlopen_handle, symbol); if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -645,14 +637,13 @@ internal_dlsym(const char *symbol) { void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ASSERT_LOCK_HELD(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); return result; } # endif @@ -1101,9 +1092,10 @@ void freeObjectCode (ObjectCode *oc) if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); + // ROMES:TODO: This previously acquired dl_mutex. Check that acquiring linker_mutex here is fine. + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1868,73 +1860,20 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); - if (r) { - RELEASE_LOCK(&linker_mutex); - return r; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - -#define NMATCH 5 - regmatch_t match[NMATCH]; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); - result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (*errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - RELEASE_LOCK(&linker_mutex); - // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)*errmsg); // Free old message before creating new one - r = loadNativeObj_ELF(line+match[2].rm_so, errmsg); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); } +#endif RELEASE_LOCK(&linker_mutex); return r; @@ -1982,7 +1921,7 @@ static HsInt unloadNativeObj_(void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,191 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - - /* If we load the same object multiple times, just return the - * already-loaded handle. Note that this is broken if unloadNativeObj - * is used, as we don’t do any reference counting; see #24345. - */ - ObjectCode *existing_oc = lookupObjectByPath(path); - if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { - if (existing_oc->type == DYNAMIC_OBJECT) { - retval = existing_oc->dlopen_handle; - goto success; - } - copyErrmsg(errmsg, "loadNativeObj_ELF: already loaded as non-dynamic object"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - // We want to use RTLD_NOW rather than RTLD_LAZY because in the case that - // DLINFO is available we want to learn eagerly about all symbols, however, - // there is no ldinfo on macos in which case we prefer using RTLD_LAZY. - // ROMES:TODO: ^ - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - nc->dlopen_handle = hdl; - nc->status = OBJECT_READY; - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - foreignExportsFinishedLoadingObject(); - - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2303,4 +2122,73 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + // ROMES:TODO: NO GOOD, this is almost recursive? no, as long we + // move the loadNativeObj_ELF to a shared impl + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09389a68224b1c01da226ebeb2359194d96c4293...62cb1b8e5ea5b790daa622e9b7b654dd4701d1ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09389a68224b1c01da226ebeb2359194d96c4293...62cb1b8e5ea5b790daa622e9b7b654dd4701d1ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 12:00:20 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 01 Apr 2024 08:00:20 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] WIP Message-ID: <660aa1d492d1f_3a933914c79c8653@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: 7607624a by Jade at 2024-04-01T14:04:48+02:00 WIP - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs ===================================== @@ -1645,15 +1645,8 @@ Further improved using a four-way merge, with an additional performance increase https://gitlab.haskell.org/ghc/ghc/issues/24280 -} -{-# INLINEABLE sort #-} -sort = actualSort (>) - -{-# INLINEABLE sortBy #-} -sortBy cmp = actualSort (\x y -> cmp x y == GT) - -{-# INLINE actualSort #-} -actualSort :: (a -> a -> Bool) -> [a] -> [a] -actualSort gt ns +sort = sortBy compare +sortBy cmp ns | [] <- ns = [] | [a] <- ns = [a] | [a,b] <- ns = merge [a] [b] @@ -1661,6 +1654,8 @@ actualSort gt ns | [a,b,c,d] <- ns = merge4 [a] [b] [c] [d] | otherwise = merge_all (sequences ns) where + x `gt` y = x `cmp` y == GT + sequences (a:b:xs) | a `gt` b = descending b [a] xs | otherwise = ascending b (a:) xs @@ -1668,7 +1663,7 @@ actualSort gt ns descending a as (b:bs) | a `gt` b = descending b (a:as) bs - descending a as bs = (a:as) : sequences bs + descending a as bs = (a:as): sequences bs ascending a as (b:bs) | not (a `gt` b) = ascending b (\ys -> as (a:ys)) bs @@ -1676,16 +1671,16 @@ actualSort gt ns in x : sequences bs merge_all [x] = x - merge_all xs = merge_all (reduce_once xs) - - reduce_once [] = [] - reduce_once [a] = [a] - reduce_once [a,b] = [merge a b] - reduce_once [a,b,c] = [merge3 a b c] - reduce_once [a,b,c,d,e] = [merge a b, merge3 c d e] - reduce_once [a,b,c,d,e,f] = [merge3 a b c, merge3 d e f] - reduce_once (a:b:c:d:xs) = let !x = merge4 a b c d - in x : reduce_once xs + merge_all xs = merge_all (reduce xs) + + reduce [] = [] + reduce [a] = [a] + reduce [a,b] = [merge a b] + reduce [a,b,c] = [merge3 a b c] + reduce [a,b,c,d,e] = [merge a b, merge3 c d e] + reduce [a,b,c,d,e,f] = [merge3 a b c, merge3 d e f] + reduce (a:b:c:d:xs) = let !x = merge4 a b c d + in x : reduce xs merge as@(a:as') bs@(b:bs') | a `gt` b = b : merge as bs' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7607624a41b395b0003d279b5164c18b54d231ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7607624a41b395b0003d279b5164c18b54d231ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 12:41:45 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 08:41:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mco-in-exprIsConApp Message-ID: <660aab89e34_3a933960eb5417515@gitlab.mail> Simon Peyton Jones pushed new branch wip/mco-in-exprIsConApp at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mco-in-exprIsConApp You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 12:43:43 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 01 Apr 2024 08:43:43 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] WIP Message-ID: <660aabff4428b_3a93396f5cc01934e@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: 6da36b2e by Jade at 2024-04-01T14:48:11+02:00 WIP - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs ===================================== @@ -1645,15 +1645,8 @@ Further improved using a four-way merge, with an additional performance increase https://gitlab.haskell.org/ghc/ghc/issues/24280 -} -{-# INLINEABLE sort #-} -sort = actualSort (>) - -{-# INLINEABLE sortBy #-} -sortBy cmp = actualSort (\x y -> cmp x y == GT) - -{-# INLINE actualSort #-} -actualSort :: (a -> a -> Bool) -> [a] -> [a] -actualSort gt ns +sort = sortBy compare +sortBy cmp ns | [] <- ns = [] | [a] <- ns = [a] | [a,b] <- ns = merge [a] [b] @@ -1661,6 +1654,8 @@ actualSort gt ns | [a,b,c,d] <- ns = merge4 [a] [b] [c] [d] | otherwise = merge_all (sequences ns) where + x `gt` y = x `cmp` y == GT + sequences (a:b:xs) | a `gt` b = descending b [a] xs | otherwise = ascending b (a:) xs @@ -1668,7 +1663,7 @@ actualSort gt ns descending a as (b:bs) | a `gt` b = descending b (a:as) bs - descending a as bs = (a:as) : sequences bs + descending a as bs = (a:as): sequences bs ascending a as (b:bs) | not (a `gt` b) = ascending b (\ys -> as (a:ys)) bs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6da36b2e1355abaec6fae1e1d6bbb470e0e43397 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6da36b2e1355abaec6fae1e1d6bbb470e0e43397 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 13:55:11 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Mon, 01 Apr 2024 09:55:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sand-witch/invis-pats-change-ast Message-ID: <660abcbf8947a_3a9339eddc0831380@gitlab.mail> Andrei Borzenkov pushed new branch wip/sand-witch/invis-pats-change-ast at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sand-witch/invis-pats-change-ast You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 14:41:54 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 10:41:54 -0400 Subject: [Git][ghc/ghc][wip/mco-in-exprIsConApp] Wibble Message-ID: <660ac7b242ba7_3a933914a14f0348d1@gitlab.mail> Simon Peyton Jones pushed to branch wip/mco-in-exprIsConApp at Glasgow Haskell Compiler / GHC Commits: 70b12b2c by Simon Peyton Jones at 2024-04-01T15:41:40+01:00 Wibble - - - - - 2 changed files: - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/SimpleOpt.hs Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -3033,20 +3033,20 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion -- where co :: (T t1 .. tn) ~ to_ty -- The left-hand one must be a T, because exprIsConApp returned True -- but the right-hand one might not be. (Though it usually will.) -pushCoDataCon dc dc_args MRefl = Just (push_dc_refl dc dc_args) +pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args) pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co) push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr]) push_dc_refl dc dc_args = (dc, map exprToType univ_ty_args, rest_args) where - (univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args + !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type -> Maybe (DataCon, [Type], [CoreExpr]) push_dc_gen dc dc_args co (Pair from_ty to_ty) | from_ty `eqType` to_ty -- try cheap test first - = Just (push_dc_refl dc dc_args) + = Just $! (push_dc_refl dc dc_args) | Just (to_tc, to_tc_arg_tys) <- splitTyConApp_maybe to_ty , to_tc == dataConTyCon dc ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1251,7 +1251,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- See Note [Push coercions in exprIsConApp_maybe] = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2)) - go subst floats (App fun arg) (CC args co) + go subst floats (App fun arg) (CC args mco) | let arg_type = exprType arg , not (isTypeArg arg) && needsCaseBinding arg_type arg -- An unlifted argument that’s not ok for speculation must not simply be @@ -1274,17 +1274,17 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) float = FloatCase arg' bndr DEFAULT [] subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) co) + in go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise - = go subst floats fun (CC (subst_expr subst arg : args) co) + = go subst floats fun (CC (subst_expr subst arg : args) mco) - go subst floats (Lam bndr body) (CC (arg:args) co) + go subst floats (Lam bndr body) (CC (arg:args) mco) | do_beta_by_substitution bndr arg - = go (extend subst bndr arg) floats body (CC args co) + = go (extend subst bndr arg) floats body (CC args mco) | otherwise = let (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' arg) - in go subst' (float:floats) body (CC args co) + in go subst' (float:floats) body (CC args mco) go subst floats (Let (NonRec bndr rhs) expr) cont | not (isJoinId bndr) @@ -1309,12 +1309,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr (lookupIdSubst sub v) cont - go (Left in_scope) floats (Var fun) cont@(CC args co) + go (Left in_scope) floats (Var fun) cont@(CC args mco) | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun = succeedWith in_scope floats $ - pushCoDataCon con args co + pushCoDataCon con args mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1334,7 +1334,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplOptExpr initialises the in-scope set with exprFreeVars, -- but that doesn't account for DFun unfoldings = succeedWith in_scope floats $ - pushCoDataCon con (map (substExpr subst) dfun_args) co + pushCoDataCon con (map (substExpr subst) dfun_args) mco -- Look through unfoldings, but only arity-zero one; -- if arity > 0 we are effectively inlining a function call, @@ -1352,7 +1352,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr , [arg] <- args , Just (LitString str) <- exprIsLiteral_maybe ise arg = succeedWith in_scope floats $ - dealWithStringLiteral fun str co + dealWithStringLiteral fun str mco where unfolding = id_unf fun extend_in_scope unf_fvs @@ -1408,9 +1408,9 @@ dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion -- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS -- turns those into [] automatically, but just in case something else in GHC -- generates a string literal directly. -dealWithStringLiteral fun str co = +dealWithStringLiteral fun str mco = case utf8UnconsByteString str of - Nothing -> pushCoDataCon nilDataCon [Type charTy] co + Nothing -> pushCoDataCon nilDataCon [Type charTy] mco Just (char, charTail) -> let char_expr = mkConApp charDataCon [mkCharLit char] -- In singleton strings, just add [] instead of unpackCstring# ""#. @@ -1419,7 +1419,7 @@ dealWithStringLiteral fun str co = else App (Var fun) (Lit (LitString charTail)) - in pushCoDataCon consDataCon [Type charTy, char_expr, rest] co + in pushCoDataCon consDataCon [Type charTy, char_expr, rest] mco {- Note [Unfolding DFuns] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70b12b2c7b2ec36c87ed4e19afcbaae687d703fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70b12b2c7b2ec36c87ed4e19afcbaae687d703fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 15:52:40 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 11:52:40 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 5 commits: linker: Avoid linear search when looking up Haskell symbols via dlsym Message-ID: <660ad8488f57b_3a93391c5893c50074@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 1a8f3b4b by Alexis King at 2024-04-01T12:19:39+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from 35 seconds down to 2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 1bbfd7d7 by Rodrigo Mesquita at 2024-04-01T16:51:56+01:00 wip: make addDLL wrapper around loadNativeObj wip: use loadNativeObj to implement addDLL Refactor loadNativeObj_ELF to _POSIX and delete dl_mutex CPP Support loadNativeObj in MachO - - - - - 65397d7f by Rodrigo Mesquita at 2024-04-01T16:51:57+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 3bba675c by Rodrigo Mesquita at 2024-04-01T16:51:58+01:00 Implement lookupSymbolInDLL for ExternalInterp - - - - - 2d86193a by Rodrigo Mesquita at 2024-04-01T16:51:58+01:00 hwere to - - - - - 23 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -24,6 +24,7 @@ import GHCi.RemoteTypes import GHCi.ResolvedBCO import GHC.Builtin.PrimOps +import GHC.Builtin.PrimOps.Ids import GHC.Builtin.Names import GHC.Unit.Types @@ -38,6 +39,8 @@ import GHC.Utils.Outputable import GHC.Types.Name import GHC.Types.Name.Env +import qualified GHC.Types.Id as Id +import GHC.Types.Unique.DFM import Language.Haskell.Syntax.Module.Name @@ -52,31 +55,32 @@ import GHC.Exts linkBCO :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO -linkBCO interp le bco_ix +linkBCO interp pkgs_loaded le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) - ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0) + lits <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le) (ssElts lits0) + ptrs <- mapM (resolvePtr interp pkgs_loaded le bco_ix) (ssElts ptrs0) return (ResolvedBCO isLittleEndian arity insns bitmap (listArray (0, fromIntegral (sizeSS lits0)-1) lits) (addListToSS emptySS ptrs)) -lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word -lookupLiteral interp le ptr = case ptr of +lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> BCONPtr -> IO Word +lookupLiteral interp pkgs_loaded le ptr = case ptr of BCONPtrWord lit -> return lit BCONPtrLbl sym -> do Ptr a# <- lookupStaticPtr interp sym return (W# (int2Word# (addr2Int# a#))) BCONPtrItbl nm -> do - Ptr a# <- lookupIE interp (itbl_env le) nm + Ptr a# <- lookupIE interp pkgs_loaded (itbl_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrAddr nm -> do - Ptr a# <- lookupAddr interp (addr_env le) nm + Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrStr _ -> -- should be eliminated during assembleBCOs @@ -90,19 +94,19 @@ lookupStaticPtr interp addr_of_label_string = do Nothing -> linkFail "GHC.ByteCode.Linker: can't find label" (unpackFS addr_of_label_string) -lookupIE :: Interp -> ItblEnv -> Name -> IO (Ptr ()) -lookupIE interp ie con_nm = +lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ()) +lookupIE interp pkgs_loaded ie con_nm = case lookupNameEnv ie con_nm of Just (_, ItblPtr a) -> return (fromRemotePtr (castRemotePtr a)) Nothing -> do -- try looking up in the object files. let sym_to_find1 = nameToCLabel con_nm "con_info" - m <- lookupSymbol interp sym_to_find1 + m <- lookupHsSymbol interp pkgs_loaded con_nm "con_info" case m of Just addr -> return addr Nothing -> do -- perhaps a nullary constructor? let sym_to_find2 = nameToCLabel con_nm "static_info" - n <- lookupSymbol interp sym_to_find2 + n <- lookupHsSymbol interp pkgs_loaded con_nm "static_info" case n of Just addr -> return addr Nothing -> linkFail "GHC.ByteCode.Linker.lookupIE" @@ -110,34 +114,35 @@ lookupIE interp ie con_nm = unpackFS sym_to_find2) -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode -lookupAddr :: Interp -> AddrEnv -> Name -> IO (Ptr ()) -lookupAddr interp ae addr_nm = do +lookupAddr :: Interp -> PkgsLoaded -> AddrEnv -> Name -> IO (Ptr ()) +lookupAddr interp pkgs_loaded ae addr_nm = do case lookupNameEnv ae addr_nm of Just (_, AddrPtr ptr) -> return (fromRemotePtr ptr) Nothing -> do -- try looking up in the object files. let sym_to_find = nameToCLabel addr_nm "bytes" -- see Note [Bytes label] in GHC.Cmm.CLabel - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded addr_nm "bytes" case m of Just ptr -> return ptr Nothing -> linkFail "GHC.ByteCode.Linker.lookupAddr" (unpackFS sym_to_find) -lookupPrimOp :: Interp -> PrimOp -> IO (RemotePtr ()) -lookupPrimOp interp primop = do +lookupPrimOp :: Interp -> PkgsLoaded -> PrimOp -> IO (RemotePtr ()) +lookupPrimOp interp pkgs_loaded primop = do let sym_to_find = primopToCLabel primop "closure" - m <- lookupSymbol interp (mkFastString sym_to_find) + m <- lookupHsSymbol interp pkgs_loaded (Id.idName $ primOpId primop) "closure" case m of Just p -> return (toRemotePtr p) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" sym_to_find resolvePtr :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> BCOPtr -> IO ResolvedBCOPtr -resolvePtr interp le bco_ix ptr = case ptr of +resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of BCOPtrName nm | Just ix <- lookupNameEnv bco_ix nm -> return (ResolvedBCORef ix) -- ref to another BCO in this group @@ -149,20 +154,38 @@ resolvePtr interp le bco_ix ptr = case ptr of -> assertPpr (isExternalName nm) (ppr nm) $ do let sym_to_find = nameToCLabel nm "closure" - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded nm "closure" case m of Just p -> return (ResolvedBCOStaticPtr (toRemotePtr p)) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (unpackFS sym_to_find) BCOPtrPrimOp op - -> ResolvedBCOStaticPtr <$> lookupPrimOp interp op + -> ResolvedBCOStaticPtr <$> lookupPrimOp interp pkgs_loaded op BCOPtrBCO bco - -> ResolvedBCOPtrBCO <$> linkBCO interp le bco_ix bco + -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco BCOPtrBreakArray breakarray -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba) +lookupHsSymbol :: Interp -> PkgsLoaded -> Name -> String -> IO (Maybe (Ptr ())) +lookupHsSymbol interp pkgs_loaded nm sym_suffix = do + massertPpr (isExternalName nm) (ppr nm) + let sym_to_find = nameToCLabel nm sym_suffix + pkg_id = moduleUnitId $ nameModule nm + loaded_dlls = maybe [] loaded_pkg_hs_dlls $ lookupUDFM pkgs_loaded pkg_id + + go (dll:dlls) = do + mb_ptr <- lookupSymbolInDLL interp dll sym_to_find + case mb_ptr of + Just ptr -> pure (Just ptr) + Nothing -> go dlls + go [] = + -- See Note [Symbols may not be found in pkgs_loaded] in GHC.Linker.Types + lookupSymbol interp sym_to_find + + go loaded_dlls + linkFail :: String -> String -> IO a linkFail who what = throwGhcExceptionIO (ProgramError $ ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Driver/Plugins.hs ===================================== @@ -420,12 +420,12 @@ loadExternalPluginLib :: FilePath -> IO () loadExternalPluginLib path = do -- load library loadDLL path >>= \case - Just errmsg -> pprPanic "loadExternalPluginLib" - (vcat [ text "Can't load plugin library" - , text " Library path: " <> text path - , text " Error : " <> text errmsg - ]) - Nothing -> do + Left errmsg -> pprPanic "loadExternalPluginLib" + (vcat [ text "Can't load plugin library" + , text " Library path: " <> text path + , text " Error : " <> text errmsg + ]) + Right _ -> do -- TODO: use returned LoadedDLL? -- resolve objects resolveObjs >>= \case True -> return () ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Tc.Utils.Monad import GHC.Runtime.Interpreter import GHCi.RemoteTypes import GHC.Iface.Load +import GHCi.Message (LoadedDLL) import GHC.ByteCode.Linker import GHC.ByteCode.Asm @@ -172,7 +173,7 @@ emptyLoaderState = LoaderState -- -- The linker's symbol table is populated with RTS symbols using an -- explicit list. See rts/Linker.c for details. - where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] emptyUniqDSet) + where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet) extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO () extendLoadedEnv interp new_bindings = @@ -221,8 +222,8 @@ loadDependencies -> SrcSpan -> [Module] -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required +-- When called, the loader state must have been initialized (see `initLoaderState`) loadDependencies interp hsc_env pls span needed_mods = do --- initLoaderState (hsc_dflags hsc_env) dl let opts = initLinkDepsOpts hsc_env -- Find what packages and linkables are required @@ -512,25 +513,25 @@ preloadLib interp hsc_env lib_paths framework_paths pls lib_spec = do DLL dll_unadorned -> do maybe_errstr <- loadDLL interp (platformSOName platform dll_unadorned) case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm | platformOS platform /= OSDarwin -> + Right _ -> maybePutStrLn logger "done" + Left mm | platformOS platform /= OSDarwin -> preloadFailed mm lib_paths lib_spec - Just mm | otherwise -> do + Left mm | otherwise -> do -- As a backup, on Darwin, try to also load a .so file -- since (apparently) some things install that way - see -- ticket #8770. let libfile = ("lib" ++ dll_unadorned) <.> "so" err2 <- loadDLL interp libfile case err2 of - Nothing -> maybePutStrLn logger "done" - Just _ -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left _ -> preloadFailed mm lib_paths lib_spec return pls DLLPath dll_path -> do do maybe_errstr <- loadDLL interp dll_path case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left mm -> preloadFailed mm lib_paths lib_spec return pls Framework framework -> @@ -614,7 +615,7 @@ loadExpr interp hsc_env span root_ul_bco = do -- Load the necessary packages and linkables let le = linker_env pls bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)] - resolved <- linkBCO interp le bco_ix root_ul_bco + resolved <- linkBCO interp (pkgs_loaded pls) le bco_ix root_ul_bco [root_hvref] <- createBCOs interp [resolved] fhv <- mkFinalizedHValue interp root_hvref return (pls, fhv) @@ -678,7 +679,7 @@ loadDecls interp hsc_env span cbc at CompiledByteCode{..} = do , addr_env = plusNameEnv (addr_env le) bc_strs } -- Link the necessary packages and linkables - new_bindings <- linkSomeBCOs interp le2 [cbc] + new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 [cbc] nms_fhvs <- makeForeignNamedHValueRefs interp new_bindings let ce2 = extendClosureEnv (closure_env le2) nms_fhvs !pls2 = pls { linker_env = le2 { closure_env = ce2 } } @@ -860,8 +861,8 @@ dynLoadObjs interp hsc_env pls at LoaderState{..} objs = do changeTempFilesLifetime tmpfs TFL_GhcSession [soFile] m <- loadDLL interp soFile case m of - Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos } - Just err -> linkFail msg err + Right _ -> return $! pls { temp_sos = (libPath, libName) : temp_sos } + Left err -> linkFail msg err where msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed" @@ -901,7 +902,7 @@ dynLinkBCOs interp pls bcos = do ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs) le2 = le1 { itbl_env = ie2, addr_env = ae2 } - names_and_refs <- linkSomeBCOs interp le2 cbcs + names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs -- We only want to add the external ones to the ClosureEnv let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs @@ -916,6 +917,7 @@ dynLinkBCOs interp pls bcos = do -- Link a bunch of BCOs and return references to their values linkSomeBCOs :: Interp + -> PkgsLoaded -> LinkerEnv -> [CompiledByteCode] -> IO [(Name,HValueRef)] @@ -923,7 +925,7 @@ linkSomeBCOs :: Interp -- the incoming unlinked BCOs. Each gives the -- value of the corresponding unlinked BCO -linkSomeBCOs interp le mods = foldr fun do_link mods [] +linkSomeBCOs interp pkgs_loaded le mods = foldr fun do_link mods [] where fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) @@ -932,7 +934,7 @@ linkSomeBCOs interp le mods = foldr fun do_link mods [] let flat = [ bco | bcos <- mods, bco <- bcos ] names = map unlinkedBCOName flat bco_ix = mkNameEnv (zip names [0..]) - resolved <- sequence [ linkBCO interp le bco_ix bco | bco <- flat ] + resolved <- sequence [ linkBCO interp pkgs_loaded le bco_ix bco | bco <- flat ] hvrefs <- createBCOs interp resolved return (zip names hvrefs) @@ -1094,18 +1096,18 @@ loadPackages' interp hsc_env new_pks pls = do -- Link dependents first ; pkgs' <- link pkgs deps -- Now link the package itself - ; (hs_cls, extra_cls) <- loadPackage interp hsc_env pkg_cfg + ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg | dep_pkg <- deps , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg) ] - ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls trans_deps)) } + ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) } | otherwise = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg))) -loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec]) +loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL]) loadPackage interp hsc_env pkg = do let dflags = hsc_dflags hsc_env @@ -1147,7 +1149,9 @@ loadPackage interp hsc_env pkg let classifieds = hs_classifieds ++ extra_classifieds -- Complication: all the .so's must be loaded before any of the .o's. - let known_dlls = [ dll | DLLPath dll <- classifieds ] + let known_hs_dlls = [ dll | DLLPath dll <- hs_classifieds ] + known_extra_dlls = [ dll | DLLPath dll <- extra_classifieds ] + known_dlls = known_hs_dlls ++ known_extra_dlls #if defined(CAN_LOAD_DLL) dlls = [ dll | DLL dll <- classifieds ] #endif @@ -1168,10 +1172,13 @@ loadPackage interp hsc_env pkg loadFrameworks interp platform pkg -- See Note [Crash early load_dyn and locateLib] -- Crash early if can't load any of `known_dlls` - mapM_ (load_dyn interp hsc_env True) known_dlls + mapM_ (load_dyn interp hsc_env True) known_extra_dlls + loaded_dlls <- mapMaybeM (load_dyn interp hsc_env True) known_hs_dlls -- For remaining `dlls` crash early only when there is surely -- no package's DLL around ... (not is_dyn) mapM_ (load_dyn interp hsc_env (not is_dyn) . platformSOName platform) dlls +#else + let loaded_dlls = [] #endif -- After loading all the DLLs, we can load the static objects. -- Ordering isn't important here, because we do one final link @@ -1191,7 +1198,7 @@ loadPackage interp hsc_env pkg if succeeded ok then do maybePutStrLn logger "done." - return (hs_classifieds, extra_classifieds) + return (hs_classifieds, extra_classifieds, loaded_dlls) else let errmsg = text "unable to load unit `" <> pprUnitInfoForUser pkg <> text "'" in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg)) @@ -1244,19 +1251,20 @@ restriction very easily. -- can be passed directly to loadDLL. They are either fully-qualified -- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so"). In the latter case, -- loadDLL is going to search the system paths to find the library. -load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO () +load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO (Maybe (RemotePtr LoadedDLL)) load_dyn interp hsc_env crash_early dll = do r <- loadDLL interp dll case r of - Nothing -> return () - Just err -> + Right loaded_dll -> pure (Just loaded_dll) + Left err -> if crash_early then cmdLineErrorIO err - else + else do when (diag_wopt Opt_WarnMissedExtraSharedLib diag_opts) $ logMsg logger (mkMCDiagnostic diag_opts (WarningWithFlag Opt_WarnMissedExtraSharedLib) Nothing) noSrcSpan $ withPprStyle defaultUserStyle (note err) + pure Nothing where diag_opts = initDiagOpts (hsc_dflags hsc_env) logger = hsc_logger hsc_env ===================================== compiler/GHC/Linker/MacOS.hs ===================================== @@ -172,6 +172,6 @@ loadFramework interp extraPaths rootname findLoadDLL (p:ps) errs = do { dll <- loadDLL interp (p fwk_file) ; case dll of - Nothing -> return Nothing - Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs) + Right _ -> return Nothing + Left err -> findLoadDLL ps ((p ++ ": " ++ err):errs) } ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -40,7 +40,8 @@ import GHC.Prelude import GHC.Unit ( UnitId, Module ) import GHC.ByteCode.Types ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type ( Fingerprint ) -import GHCi.RemoteTypes ( ForeignHValue ) +import GHCi.RemoteTypes ( ForeignHValue, RemotePtr ) +import GHCi.Message ( LoadedDLL ) import GHC.Types.Var ( Id ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnvList, filterNameEnv ) @@ -75,6 +76,57 @@ initialised. The LinkerEnv maps Names to actual closures (for interpreted code only), for use during linking. + +Note [Looking up symbols in the relevant objects] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In #23415, we determined that a lot of time (>10s, or even up to >35s!) was +being spent on dynamically loading symbols before actually interpreting code +when `:main` was run in GHCi. The root cause was that for each symbol we wanted +to lookup, we would traverse the list of loaded objects and try find the symbol +in each of them with dlsym (i.e. looking up a symbol was, worst case, linear in +the amount of loaded objects). + +To drastically improve load time (XXX(TODO:get better measure against 10s +baseline rather than 35second one) to <3s), we now: + +1. For every of the native objects loaded for a given unit, store the handles returned by `dlopen`. + - In `pkgs_loaded` of the `LoaderState`, which maps `UnitId`s to + `LoadedPkgInfo`s, where the handles live in its field `loaded_pkg_hs_dlls`. + +2. When looking up a Name (e.g. `lookupHsSymbol`), find that name's `UnitId` in + the `pkgs_loaded` mapping, + +3. And only look for the symbol (with `dlsym`) on the /handles relevant to that + unit/, rather than in every loaded object. + +Note [Symbols may not be found in pkgs_loaded] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Despite storing and looking for symbols in the relevant loaded libraries +handles for a given unit-id, as described in the note above, we may still have +to fallback to the "slow" `lookupSymbol` function (see its "fallback" call in +`lookupHsSymbol`). + +TODO: Ben: my understanding here is flawed; could you make this clearer?. + +This fallback is still needed because a given unit may be associated with +static objects (`loaded_pkg_hs_objs`) only and no dynamic libraries, but we +only `lookupSymbolInDLL` for loaded dynamic libraries. In that case, +`lookupSymbol` will do the right thing because, besides looking up the symbol +in every loaded dylib, it will end up searching the static name table and find those symbols. + +Arguably, we should rather generalise `lookupSymbolInDLL` to +`lookupSymbolInObject`, where an object may be a DLL/native object (as in +`loadNativeObj`), or e.g. a static archive, instead of having a special case +for dynamic libraries. + +This fallback is further needed because we don't look in the haskell objects +loaded for the home units (see the call to `loadModuleLinkables` in +`loadDependencies`, as opposed to the call to `loadPackages'` in the same +function which updates `pkgs_loaded`). We should ultimately keep track of the +objects loaded (probably in `objs_loaded`, for which `LinkableSet` is a bit +unsatisfactory, see a suggestion in 51c5c4eb1f2a33e4dc88e6a37b7b7c135234ce9b) +and be able to lookup symbols specifically in them too (similarly to +`lookupSymbolInDLL`). -} newtype Loader = Loader { loader_state :: MVar (Maybe LoaderState) } @@ -146,11 +198,13 @@ data LoadedPkgInfo { loaded_pkg_uid :: !UnitId , loaded_pkg_hs_objs :: ![LibrarySpec] , loaded_pkg_non_hs_objs :: ![LibrarySpec] + , loaded_pkg_hs_dlls :: ![RemotePtr LoadedDLL] + -- ^ See Note [Looking up symbols in the relevant objects] , loaded_pkg_trans_deps :: UniqDSet UnitId } instance Outputable LoadedPkgInfo where - ppr (LoadedPkgInfo uid hs_objs non_hs_objs trans_deps) = + ppr (LoadedPkgInfo uid hs_objs non_hs_objs _ trans_deps) = vcat [ppr uid , ppr hs_objs , ppr non_hs_objs @@ -159,10 +213,10 @@ instance Outputable LoadedPkgInfo where -- | Information we can use to dynamically link modules into the compiler data Linkable = LM { - linkableTime :: !UTCTime, -- ^ Time at which this linkable was built + linkableTime :: !UTCTime, -- ^ Time at which this linkable was built -- (i.e. when the bytecodes were produced, -- or the mod date on the files) - linkableModule :: !Module, -- ^ The linkable module itself + linkableModule :: !Module, -- ^ The linkable module itself linkableUnlinked :: [Unlinked] -- ^ Those files and chunks of code we have yet to link. -- ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -35,6 +35,7 @@ module GHC.Runtime.Interpreter -- * The object-code linker , initObjLinker , lookupSymbol + , lookupSymbolInDLL , lookupClosure , loadDLL , loadArchive @@ -151,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -440,57 +441,78 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + +lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of +#if defined(HAVE_INTERNAL_INTERPRETER) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) +#endif + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either -- an absolute pathname to the file, or a relative filename -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. --- --- Returns: --- --- Nothing => success --- Just err_msg => failure -loadDLL :: Interp -> String -> IO (Maybe String) +loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL)) loadDLL interp str = interpCmd interp (LoadDLL str) loadArchive :: Interp -> String -> IO () @@ -549,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/Message.hs ===================================== @@ -23,6 +23,7 @@ module GHCi.Message , getMessage, putMessage, getTHMessage, putTHMessage , Pipe(..), remoteCall, remoteTHCall, readPipe, writePipe , BreakModule + , LoadedDLL ) where import Prelude -- See note [Why do we import Prelude here?] @@ -73,8 +74,9 @@ data Message a where -- These all invoke the corresponding functions in the RTS Linker API. InitLinker :: Message () LookupSymbol :: String -> Message (Maybe (RemotePtr ())) + LookupSymbolInDLL :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ())) LookupClosure :: String -> Message (Maybe HValueRef) - LoadDLL :: String -> Message (Maybe String) + LoadDLL :: String -> Message (Either String (RemotePtr LoadedDLL)) LoadArchive :: String -> Message () -- error? LoadObj :: String -> Message () -- error? UnloadObj :: String -> Message () -- error? @@ -415,6 +417,9 @@ instance Binary a => Binary (EvalResult a) -- that type isn't available here. data BreakModule +-- | A dummy type that tags pointers returned by 'LoadDLL'. +data LoadedDLL + -- SomeException can't be serialized because it contains dynamic -- types. However, we do very limited things with the exceptions that -- are thrown by interpreted computations: @@ -544,6 +549,7 @@ getMessage = do 37 -> Msg <$> return RtsRevertCAFs 38 -> Msg <$> (ResumeSeq <$> get) 39 -> Msg <$> (NewBreakModule <$> get) + 40 -> Msg <$> (LookupSymbolInDLL <$> get <*> get) _ -> error $ "Unknown Message code " ++ (show b) putMessage :: Message a -> Put @@ -588,7 +594,8 @@ putMessage m = case m of Seq a -> putWord8 36 >> put a RtsRevertCAFs -> putWord8 37 ResumeSeq a -> putWord8 38 >> put a - NewBreakModule name -> putWord8 39 >> put name + NewBreakModule name -> putWord8 39 >> put name + LookupSymbolInDLL dll str -> putWord8 40 >> put dll >> put str {- Note [Parallelize CreateBCOs serialization] ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -18,6 +18,7 @@ module GHCi.ObjLink , unloadObj , purgeObj , lookupSymbol + , lookupSymbolInDLL , lookupClosure , resolveObjs , addLibrarySearchPath @@ -27,18 +28,17 @@ module GHCi.ObjLink import Prelude -- See note [Why do we import Prelude here?] import GHCi.RemoteTypes +import GHCi.Message (LoadedDLL) import Control.Exception (throwIO, ErrorCall(..)) import Control.Monad ( when ) import Foreign.C -import Foreign.Marshal.Alloc ( free ) -import Foreign ( nullPtr ) +import Foreign.Marshal.Alloc ( alloca, free ) +import Foreign ( nullPtr, peek ) import GHC.Exts import System.Posix.Internals ( CFilePath, withFilePath, peekFilePath ) import System.FilePath ( dropExtension, normalise ) - - -- --------------------------------------------------------------------------- -- RTS Linker Interface -- --------------------------------------------------------------------------- @@ -70,6 +70,15 @@ lookupSymbol str_in = do then return Nothing else return (Just addr) +lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) +lookupSymbolInDLL dll str_in = do + let str = prefixUnderscore str_in + withCAString str $ \c_str -> do + addr <- c_lookupSymbolInNativeObj dll c_str + if addr == nullPtr + then return Nothing + else return (Just addr) + lookupClosure :: String -> IO (Maybe HValueRef) lookupClosure str = do m <- lookupSymbol str @@ -89,7 +98,7 @@ prefixUnderscore -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. -- -loadDLL :: String -> IO (Maybe String) +loadDLL :: String -> IO (Either String (Ptr LoadedDLL)) -- Nothing => success -- Just err_msg => failure loadDLL str0 = do @@ -101,12 +110,16 @@ loadDLL str0 = do str | isWindowsHost = dropExtension str0 | otherwise = str0 -- - maybe_errmsg <- withFilePath (normalise str) $ \dll -> c_addDLL dll - if maybe_errmsg == nullPtr - then return Nothing - else do str <- peekCString maybe_errmsg - free maybe_errmsg - return (Just str) + (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> + alloca $ \errmsg_ptr -> (,) + <$> c_loadNativeObj dll errmsg_ptr + <*> peek errmsg_ptr + + if maybe_handle == nullPtr + then do str <- peekCString maybe_errmsg + free maybe_errmsg + return (Left str) + else return (Right maybe_handle) loadArchive :: String -> IO () loadArchive str = do @@ -163,7 +176,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> IO CString +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== libraries/ghci/GHCi/Run.hs ===================================== @@ -66,7 +66,7 @@ run m = case m of LookupClosure str -> lookupJSClosure str #else InitLinker -> initObjLinker RetainCAFs - LoadDLL str -> loadDLL str + LoadDLL str -> fmap toRemotePtr <$> loadDLL str LoadArchive str -> loadArchive str LoadObj str -> loadObj str UnloadObj str -> unloadObj str @@ -81,6 +81,8 @@ run m = case m of #endif RtsRevertCAFs -> rts_revertCAFs LookupSymbol str -> fmap toRemotePtr <$> lookupSymbol str + LookupSymbolInDLL dll str -> + fmap toRemotePtr <$> lookupSymbolInDLL (fromRemotePtr dll) str FreeHValueRefs rs -> mapM_ freeRemoteRef rs AddSptEntry fpr r -> localRef r >>= sptAddEntry fpr EvalStmt opts r -> evalStmt opts r ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,90 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static const char * -internal_dlopen(const char *dll_name) -{ - OpenedSO* o_so; - void *hdl; - const char *errmsg; - char *errmsg_copy; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - errmsg = NULL; - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - errmsg = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return errmsg; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -660,11 +571,10 @@ internal_dlopen(const char *dll_name) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -672,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -725,79 +634,35 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } -# endif -const char * -addDLL( pathchar *dll_name ) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; + ACQUIRE_LOCK(&linker_mutex); - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - errmsg = internal_dlopen(dll_name); +#if defined(OBJFORMAT_MACHO) + CHECK(symbol_name[0] == '_'); + symbol_name = symbol_name+1; +#endif + void *result = dlsym(handle, symbol_name); - if (errmsg == NULL) { - return NULL; - } + RELEASE_LOCK(&linker_mutex); + return result; +} +# endif - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - return errmsg; // return original error if open fails - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - errmsg = internal_dlopen(line+match[2].rm_so); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +const char *addDLL(pathchar* dll_name) +{ +# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return errmsg; # elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name, NULL); + return addDLL_PEi386(dll_name); # else barf("addDLL: not implemented on this platform"); @@ -1228,10 +1093,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1896,12 +1761,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -1988,11 +1861,21 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); + +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + RELEASE_LOCK(&linker_mutex); return r; } @@ -2006,7 +1889,7 @@ loadNativeObj (pathchar *path, char **errmsg) } #endif -HsInt unloadNativeObj (void *handle) +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2039,11 +1922,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -619,6 +619,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,8 +90,12 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); + /* load a dynamic library */ -const char *addDLL( pathchar* dll_name ); +const char *addDLL(pathchar* dll_name); + +void *lookupSymbolInDLL(void *handle, const char *symbol_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62cb1b8e5ea5b790daa622e9b7b654dd4701d1ab...2d86193a5803a7d820c30ed362e7e67a9aebd121 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62cb1b8e5ea5b790daa622e9b7b654dd4701d1ab...2d86193a5803a7d820c30ed362e7e67a9aebd121 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 16:20:52 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 01 Apr 2024 12:20:52 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Add todos Message-ID: <660adee45bd74_3a93392007df8505ab@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 61f8c7e4 by Sven Tennie at 2024-04-01T18:19:39+02:00 Add todos - - - - - 2 changed files: - compiler/GHC/CmmToAsm/RV64/Ppr.hs - compiler/GHC/CmmToAsm/RV64/Regs.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic +-- TODO: Move function down to where it is used. pprProcAlignment :: IsDoc doc => NCGConfig -> doc pprProcAlignment config = maybe empty (pprAlign platform . mkAlignment) (ncgProcAlignment config) where @@ -78,10 +79,12 @@ pprLabel platform lbl = $$ pprTypeDecl platform lbl $$ line (pprAsmLabel platform lbl <> char ':') +-- TODO: Delete unused parameter. pprAlign :: IsDoc doc => Platform -> Alignment -> doc pprAlign _platform alignment = line $ text "\t.balign " <> int (alignmentBytes alignment) +-- TODO: Delete unused parameters. -- | Print appropriate alignment for the given section type. pprAlignForSection :: IsDoc doc => Platform -> SectionType -> doc pprAlignForSection _platform _seg @@ -97,8 +100,7 @@ pprAlignForSection _platform _seg -- pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc pprSectionAlign _config (Section (OtherSection _) _) = - -- TODO: Valid for RISCV64? - panic "AArch64.Ppr.pprSectionAlign: unknown section" + panic "RV64.Ppr.pprSectionAlign: unknown section" pprSectionAlign config sec@(Section seg _) = line (pprSectionHeader config sec) $$ pprAlignForSection (ncgPlatform config) seg @@ -175,6 +177,7 @@ pprDatas config (CmmStaticsRaw lbl dats) where platform = ncgPlatform config +-- TODO: Unused parameter. pprData :: IsDoc doc => NCGConfig -> CmmStatic -> doc pprData _config (CmmString str) = line (pprString str) pprData _config (CmmFileEmbed path _) = line (pprFileEmbed path) @@ -456,6 +459,7 @@ pprInstr platform instr = case instr of -- This case is used for sign extension: SEXT.W op | OpReg W64 _ <- o1 , OpReg W32 _ <- o2, isImmOp o3 -> op3 (text "\taddiw") o1 o2 o3 | otherwise -> op3 (text "\tadd") o1 o2 o3 + -- TODO: Delete commented out code. -- CMN o1 o2 -> op2 (text "\tcmn") o1 o2 -- CMP o1 o2 -- | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 @@ -483,9 +487,12 @@ pprInstr platform instr = case instr of DIVU o1 o2 o3 -> op3 (text "\tdivu") o1 o2 o3 -- 2. Bit Manipulation Instructions ------------------------------------------ + -- TODO: Non-existant in RISCV - delete SBFM o1 o2 o3 o4 -> op4 (text "\tsbfm") o1 o2 o3 o4 + -- TODO: Non-existant in RISCV - delete UBFM o1 o2 o3 o4 -> op4 (text "\tubfm") o1 o2 o3 o4 -- signed and unsigned bitfield extract + -- TODO: Non-existant in RISCV - delete UBFX o1 o2 o3 o4 -> op4 (text "\tubfx") o1 o2 o3 o4 -- 3. Logical and Move Instructions ------------------------------------------ @@ -679,6 +686,7 @@ pprInstr platform instr = case instr of where op2 op o1 o2 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 op3 op o1 o2 o3 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 op4 op o1 o2 o3 o4 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 <> comma <+> pprOp platform o4 + -- TODO: Delete commented out code. -- op_ldr o1 rest = line $ text "\tld" <+> pprOp platform o1 <> comma <+> rest <+> text "(" <> pprOp platform o1 <> text ")" -- op_adrp o1 rest = line $ text "\tauipc" <+> pprOp platform o1 <> comma <+> rest -- op_add o1 rest = line $ text "\taddi" <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> rest ===================================== compiler/GHC/CmmToAsm/RV64/Regs.hs ===================================== @@ -121,6 +121,8 @@ allFpArgRegs = map regSingle [fa0RegNo .. fa7RegNo] -- * Addressing modes +-- TODO: AddReg seems to be just a special case of AddrRegImm. Maybe we should +-- replace it with AddrRegImm having an Imm of 0. -- | Addressing modes data AddrMode = -- | A register plus some integer, e.g. @8(sp)@ or @-16(sp)@. The offset View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61f8c7e4a06349df7fe31863ac9791abee2741db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61f8c7e4a06349df7fe31863ac9791abee2741db You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 16:26:17 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 12:26:17 -0400 Subject: [Git][ghc/ghc][wip/T24604] Improvements: handle @a binders too Message-ID: <660ae0297f193_3a933921b2310511c6@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24604 at Glasgow Haskell Compiler / GHC Commits: bf5e0858 by Simon Peyton Jones at 2024-04-01T17:25:44+01:00 Improvements: handle @a binders too - - - - - 5 changed files: - compiler/GHC/Tc/Gen/HsType.hs - testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2573,7 +2573,7 @@ kcCheckDeclHeader_sig sig_kind name flav , text "implict_nms:" <+> ppr implicit_nms , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2625,8 +2625,7 @@ kcCheckDeclHeader_sig sig_kind name flav -- Hence we need to add the visible binders into dup_chk_prs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - dup_chk_prs = implicit_prs ++ - [ (tyVarName tv, tv) | Bndr tv vis <- skol_tcbs, isVisibleTcbVis vis ] + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs ; unless (null implicit_nms) $ -- No need if no implicit tyvars checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs @@ -2697,6 +2696,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Tyvar brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2707,7 +2707,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2724,18 +2724,19 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2755,9 +2756,13 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -1,6 +1,6 @@ module T24604 where -import Data.Kind (Constraint, Type) +import Data.Kind type UF :: forall zk -> zk -> Constraint class UF kk (xb :: k) where ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -19,3 +19,4 @@ test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) test('T23739_fail_case', normal, compile_fail, ['']) test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf5e08589e240d49c50b695959d0382c4fbae47f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf5e08589e240d49c50b695959d0382c4fbae47f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 16:31:57 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 12:31:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24462 Message-ID: <660ae17d18546_3a933922b8110517dc@gitlab.mail> Simon Peyton Jones pushed new branch wip/T24462 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24462 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 16:37:12 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Mon, 01 Apr 2024 12:37:12 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/invis-pats-change-ast] Change how invisible patterns represented in haskell syntax and TH AST (#24557) Message-ID: <660ae2b8a07a6_3a933923ba644536ed@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/invis-pats-change-ast at Glasgow Haskell Compiler / GHC Commits: 349f83e7 by Andrei Borzenkov at 2024-04-01T20:36:51+04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/349f83e7989acfe19cc485fe80677ce1d94ad5b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/349f83e7989acfe19cc485fe80677ce1d94ad5b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 17:44:26 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 01 Apr 2024 13:44:26 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 4 commits: Drop me: Start writing test Message-ID: <660af27a83abe_3a93392b501ec570de@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: ba4d6428 by Rodrigo Mesquita at 2024-04-01T17:16:09+01:00 Drop me: Start writing test It works now, but is not a good test to add because it relies on timing... - - - - - ca5e00f2 by Alexis King at 2024-04-01T17:54:14+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 3fb11d24 by Rodrigo Mesquita at 2024-04-01T17:54:14+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 0ba67d90 by Rodrigo Mesquita at 2024-04-01T17:54:14+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 29 changed files: - + T23415/Makefile - + T23415/main.hs - + T23415/make_shared_libs.sh - + T23415/new-main.hs - + T23415/run_test.sh - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - testsuite/tests/rts/linker/T2615.hs Changes: ===================================== T23415/Makefile ===================================== @@ -0,0 +1,10 @@ +.PHONY: run build clean + +run: + sh run_test.sh + +build: + sh make_shared_libs.sh + +clean: + rm -f lib*.out main main.o main.hi test.o tags ===================================== T23415/main.hs ===================================== @@ -0,0 +1,20 @@ +import Control.Monad +import System.FilePath +import System.Directory +import GHCi.ObjLink + +hsLoadObjs = do + cwd <- getCurrentDirectory + forM_ [0..499] $ \i -> + loadDLL (cwd "lib" ++ show i ++ ".out") + +hsLoadSymbols = do + forM_ [0..99] $ \j -> + forM_ [0..499] $ \i -> + lookupSymbol ("lib" ++ show i ++ "_" ++ show j) + +main = do + initObjLinker RetainCAFs + hsLoadObjs + hsLoadSymbols + ===================================== T23415/make_shared_libs.sh ===================================== @@ -0,0 +1,20 @@ +#!/bin/sh + +example_dylib=$(basename -- $(find $(ghc --print-libdir) -name libHS* -not -name *.a | head -n1)) +dylib_ext="${example_dylib##*.}" +# we try .out instead of using the correct extension. + +i=0 +while [ $i -lt 500 ]; do + j=0 + while [ $j -lt 100 ]; do + echo "int lib${i}_$j(void) { return $i; }" >> "lib$i.c" + j=$(( j + 1 )) + done + cc -o "lib$i.o" -c "lib$i.c" -fPIC + cc -shared "lib$i.o" -o "lib$i.out" # "lib$i.$dylib_ext" + rm "lib$i.c" "lib$i.o" + i=$(( i + 1 )) +done + + ===================================== T23415/new-main.hs ===================================== @@ -0,0 +1,29 @@ +import Data.Either +import Data.Foldable +import Data.Map as M +import Control.Monad +import System.FilePath +import System.Directory +import GHCi.ObjLink + +libname i = "lib" ++ show i + +hsLoadObjs = do + cwd <- getCurrentDirectory + foldrM (\i acc -> do + Right handle <- loadDLL (cwd libname i ++ ".out") + return $ M.insert (libname i) handle acc + ) + M.empty [0..499] + +hsLoadSymbols handles = do + forM_ [0..499] $ \i -> + forM_ [0..99] $ \j -> do + let symbolname = libname i ++ "_" ++ show j + lookupSymbolInDLL (handles M.! libname i) symbolname + +main = do + initObjLinker RetainCAFs + handles <- hsLoadObjs + hsLoadSymbols handles + print "hi" ===================================== T23415/run_test.sh ===================================== @@ -0,0 +1,8 @@ +#!/bin/sh + +GHC1=/Users/romes/ghc-dev/ghc/_build/stage1/bin/ghc +GHC2=/Users/romes/ghc-dev/23415/_build/stage1/bin/ghc + +# $GHC1 --interactive main.hs -package directory -package ghci -package filepath +$GHC2 --interactive new-main.hs -package directory -package ghci -package filepath -package containers + ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -24,6 +24,7 @@ import GHCi.RemoteTypes import GHCi.ResolvedBCO import GHC.Builtin.PrimOps +import GHC.Builtin.PrimOps.Ids import GHC.Builtin.Names import GHC.Unit.Types @@ -38,6 +39,8 @@ import GHC.Utils.Outputable import GHC.Types.Name import GHC.Types.Name.Env +import qualified GHC.Types.Id as Id +import GHC.Types.Unique.DFM import Language.Haskell.Syntax.Module.Name @@ -52,31 +55,32 @@ import GHC.Exts linkBCO :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO -linkBCO interp le bco_ix +linkBCO interp pkgs_loaded le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) - ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0) + lits <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le) (ssElts lits0) + ptrs <- mapM (resolvePtr interp pkgs_loaded le bco_ix) (ssElts ptrs0) return (ResolvedBCO isLittleEndian arity insns bitmap (listArray (0, fromIntegral (sizeSS lits0)-1) lits) (addListToSS emptySS ptrs)) -lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word -lookupLiteral interp le ptr = case ptr of +lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> BCONPtr -> IO Word +lookupLiteral interp pkgs_loaded le ptr = case ptr of BCONPtrWord lit -> return lit BCONPtrLbl sym -> do Ptr a# <- lookupStaticPtr interp sym return (W# (int2Word# (addr2Int# a#))) BCONPtrItbl nm -> do - Ptr a# <- lookupIE interp (itbl_env le) nm + Ptr a# <- lookupIE interp pkgs_loaded (itbl_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrAddr nm -> do - Ptr a# <- lookupAddr interp (addr_env le) nm + Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrStr _ -> -- should be eliminated during assembleBCOs @@ -90,19 +94,19 @@ lookupStaticPtr interp addr_of_label_string = do Nothing -> linkFail "GHC.ByteCode.Linker: can't find label" (unpackFS addr_of_label_string) -lookupIE :: Interp -> ItblEnv -> Name -> IO (Ptr ()) -lookupIE interp ie con_nm = +lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ()) +lookupIE interp pkgs_loaded ie con_nm = case lookupNameEnv ie con_nm of Just (_, ItblPtr a) -> return (fromRemotePtr (castRemotePtr a)) Nothing -> do -- try looking up in the object files. let sym_to_find1 = nameToCLabel con_nm "con_info" - m <- lookupSymbol interp sym_to_find1 + m <- lookupHsSymbol interp pkgs_loaded con_nm "con_info" case m of Just addr -> return addr Nothing -> do -- perhaps a nullary constructor? let sym_to_find2 = nameToCLabel con_nm "static_info" - n <- lookupSymbol interp sym_to_find2 + n <- lookupHsSymbol interp pkgs_loaded con_nm "static_info" case n of Just addr -> return addr Nothing -> linkFail "GHC.ByteCode.Linker.lookupIE" @@ -110,34 +114,35 @@ lookupIE interp ie con_nm = unpackFS sym_to_find2) -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode -lookupAddr :: Interp -> AddrEnv -> Name -> IO (Ptr ()) -lookupAddr interp ae addr_nm = do +lookupAddr :: Interp -> PkgsLoaded -> AddrEnv -> Name -> IO (Ptr ()) +lookupAddr interp pkgs_loaded ae addr_nm = do case lookupNameEnv ae addr_nm of Just (_, AddrPtr ptr) -> return (fromRemotePtr ptr) Nothing -> do -- try looking up in the object files. let sym_to_find = nameToCLabel addr_nm "bytes" -- see Note [Bytes label] in GHC.Cmm.CLabel - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded addr_nm "bytes" case m of Just ptr -> return ptr Nothing -> linkFail "GHC.ByteCode.Linker.lookupAddr" (unpackFS sym_to_find) -lookupPrimOp :: Interp -> PrimOp -> IO (RemotePtr ()) -lookupPrimOp interp primop = do +lookupPrimOp :: Interp -> PkgsLoaded -> PrimOp -> IO (RemotePtr ()) +lookupPrimOp interp pkgs_loaded primop = do let sym_to_find = primopToCLabel primop "closure" - m <- lookupSymbol interp (mkFastString sym_to_find) + m <- lookupHsSymbol interp pkgs_loaded (Id.idName $ primOpId primop) "closure" case m of Just p -> return (toRemotePtr p) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" sym_to_find resolvePtr :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> BCOPtr -> IO ResolvedBCOPtr -resolvePtr interp le bco_ix ptr = case ptr of +resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of BCOPtrName nm | Just ix <- lookupNameEnv bco_ix nm -> return (ResolvedBCORef ix) -- ref to another BCO in this group @@ -149,20 +154,38 @@ resolvePtr interp le bco_ix ptr = case ptr of -> assertPpr (isExternalName nm) (ppr nm) $ do let sym_to_find = nameToCLabel nm "closure" - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded nm "closure" case m of Just p -> return (ResolvedBCOStaticPtr (toRemotePtr p)) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (unpackFS sym_to_find) BCOPtrPrimOp op - -> ResolvedBCOStaticPtr <$> lookupPrimOp interp op + -> ResolvedBCOStaticPtr <$> lookupPrimOp interp pkgs_loaded op BCOPtrBCO bco - -> ResolvedBCOPtrBCO <$> linkBCO interp le bco_ix bco + -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco BCOPtrBreakArray breakarray -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba) +lookupHsSymbol :: Interp -> PkgsLoaded -> Name -> String -> IO (Maybe (Ptr ())) +lookupHsSymbol interp pkgs_loaded nm sym_suffix = do + massertPpr (isExternalName nm) (ppr nm) + let sym_to_find = nameToCLabel nm sym_suffix + pkg_id = moduleUnitId $ nameModule nm + loaded_dlls = maybe [] loaded_pkg_hs_dlls $ lookupUDFM pkgs_loaded pkg_id + + go (dll:dlls) = do + mb_ptr <- lookupSymbolInDLL interp dll sym_to_find + case mb_ptr of + Just ptr -> pure (Just ptr) + Nothing -> go dlls + go [] = + -- See Note [Symbols may not be found in pkgs_loaded] in GHC.Linker.Types + lookupSymbol interp sym_to_find + + go loaded_dlls + linkFail :: String -> String -> IO a linkFail who what = throwGhcExceptionIO (ProgramError $ ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Driver/Plugins.hs ===================================== @@ -420,12 +420,12 @@ loadExternalPluginLib :: FilePath -> IO () loadExternalPluginLib path = do -- load library loadDLL path >>= \case - Just errmsg -> pprPanic "loadExternalPluginLib" - (vcat [ text "Can't load plugin library" - , text " Library path: " <> text path - , text " Error : " <> text errmsg - ]) - Nothing -> do + Left errmsg -> pprPanic "loadExternalPluginLib" + (vcat [ text "Can't load plugin library" + , text " Library path: " <> text path + , text " Error : " <> text errmsg + ]) + Right _ -> do -- TODO: use returned LoadedDLL? -- resolve objects resolveObjs >>= \case True -> return () ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Tc.Utils.Monad import GHC.Runtime.Interpreter import GHCi.RemoteTypes import GHC.Iface.Load +import GHCi.Message (LoadedDLL) import GHC.ByteCode.Linker import GHC.ByteCode.Asm @@ -172,7 +173,7 @@ emptyLoaderState = LoaderState -- -- The linker's symbol table is populated with RTS symbols using an -- explicit list. See rts/Linker.c for details. - where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] emptyUniqDSet) + where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet) extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO () extendLoadedEnv interp new_bindings = @@ -221,8 +222,8 @@ loadDependencies -> SrcSpan -> [Module] -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required +-- When called, the loader state must have been initialized (see `initLoaderState`) loadDependencies interp hsc_env pls span needed_mods = do --- initLoaderState (hsc_dflags hsc_env) dl let opts = initLinkDepsOpts hsc_env -- Find what packages and linkables are required @@ -512,25 +513,25 @@ preloadLib interp hsc_env lib_paths framework_paths pls lib_spec = do DLL dll_unadorned -> do maybe_errstr <- loadDLL interp (platformSOName platform dll_unadorned) case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm | platformOS platform /= OSDarwin -> + Right _ -> maybePutStrLn logger "done" + Left mm | platformOS platform /= OSDarwin -> preloadFailed mm lib_paths lib_spec - Just mm | otherwise -> do + Left mm | otherwise -> do -- As a backup, on Darwin, try to also load a .so file -- since (apparently) some things install that way - see -- ticket #8770. let libfile = ("lib" ++ dll_unadorned) <.> "so" err2 <- loadDLL interp libfile case err2 of - Nothing -> maybePutStrLn logger "done" - Just _ -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left _ -> preloadFailed mm lib_paths lib_spec return pls DLLPath dll_path -> do do maybe_errstr <- loadDLL interp dll_path case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left mm -> preloadFailed mm lib_paths lib_spec return pls Framework framework -> @@ -614,7 +615,7 @@ loadExpr interp hsc_env span root_ul_bco = do -- Load the necessary packages and linkables let le = linker_env pls bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)] - resolved <- linkBCO interp le bco_ix root_ul_bco + resolved <- linkBCO interp (pkgs_loaded pls) le bco_ix root_ul_bco [root_hvref] <- createBCOs interp [resolved] fhv <- mkFinalizedHValue interp root_hvref return (pls, fhv) @@ -678,7 +679,7 @@ loadDecls interp hsc_env span cbc at CompiledByteCode{..} = do , addr_env = plusNameEnv (addr_env le) bc_strs } -- Link the necessary packages and linkables - new_bindings <- linkSomeBCOs interp le2 [cbc] + new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 [cbc] nms_fhvs <- makeForeignNamedHValueRefs interp new_bindings let ce2 = extendClosureEnv (closure_env le2) nms_fhvs !pls2 = pls { linker_env = le2 { closure_env = ce2 } } @@ -860,8 +861,8 @@ dynLoadObjs interp hsc_env pls at LoaderState{..} objs = do changeTempFilesLifetime tmpfs TFL_GhcSession [soFile] m <- loadDLL interp soFile case m of - Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos } - Just err -> linkFail msg err + Right _ -> return $! pls { temp_sos = (libPath, libName) : temp_sos } + Left err -> linkFail msg err where msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed" @@ -901,7 +902,7 @@ dynLinkBCOs interp pls bcos = do ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs) le2 = le1 { itbl_env = ie2, addr_env = ae2 } - names_and_refs <- linkSomeBCOs interp le2 cbcs + names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs -- We only want to add the external ones to the ClosureEnv let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs @@ -916,6 +917,7 @@ dynLinkBCOs interp pls bcos = do -- Link a bunch of BCOs and return references to their values linkSomeBCOs :: Interp + -> PkgsLoaded -> LinkerEnv -> [CompiledByteCode] -> IO [(Name,HValueRef)] @@ -923,7 +925,7 @@ linkSomeBCOs :: Interp -- the incoming unlinked BCOs. Each gives the -- value of the corresponding unlinked BCO -linkSomeBCOs interp le mods = foldr fun do_link mods [] +linkSomeBCOs interp pkgs_loaded le mods = foldr fun do_link mods [] where fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) @@ -932,7 +934,7 @@ linkSomeBCOs interp le mods = foldr fun do_link mods [] let flat = [ bco | bcos <- mods, bco <- bcos ] names = map unlinkedBCOName flat bco_ix = mkNameEnv (zip names [0..]) - resolved <- sequence [ linkBCO interp le bco_ix bco | bco <- flat ] + resolved <- sequence [ linkBCO interp pkgs_loaded le bco_ix bco | bco <- flat ] hvrefs <- createBCOs interp resolved return (zip names hvrefs) @@ -1094,18 +1096,18 @@ loadPackages' interp hsc_env new_pks pls = do -- Link dependents first ; pkgs' <- link pkgs deps -- Now link the package itself - ; (hs_cls, extra_cls) <- loadPackage interp hsc_env pkg_cfg + ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg | dep_pkg <- deps , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg) ] - ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls trans_deps)) } + ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) } | otherwise = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg))) -loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec]) +loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL]) loadPackage interp hsc_env pkg = do let dflags = hsc_dflags hsc_env @@ -1147,7 +1149,9 @@ loadPackage interp hsc_env pkg let classifieds = hs_classifieds ++ extra_classifieds -- Complication: all the .so's must be loaded before any of the .o's. - let known_dlls = [ dll | DLLPath dll <- classifieds ] + let known_hs_dlls = [ dll | DLLPath dll <- hs_classifieds ] + known_extra_dlls = [ dll | DLLPath dll <- extra_classifieds ] + known_dlls = known_hs_dlls ++ known_extra_dlls #if defined(CAN_LOAD_DLL) dlls = [ dll | DLL dll <- classifieds ] #endif @@ -1168,10 +1172,13 @@ loadPackage interp hsc_env pkg loadFrameworks interp platform pkg -- See Note [Crash early load_dyn and locateLib] -- Crash early if can't load any of `known_dlls` - mapM_ (load_dyn interp hsc_env True) known_dlls + mapM_ (load_dyn interp hsc_env True) known_extra_dlls + loaded_dlls <- mapMaybeM (load_dyn interp hsc_env True) known_hs_dlls -- For remaining `dlls` crash early only when there is surely -- no package's DLL around ... (not is_dyn) mapM_ (load_dyn interp hsc_env (not is_dyn) . platformSOName platform) dlls +#else + let loaded_dlls = [] #endif -- After loading all the DLLs, we can load the static objects. -- Ordering isn't important here, because we do one final link @@ -1191,7 +1198,7 @@ loadPackage interp hsc_env pkg if succeeded ok then do maybePutStrLn logger "done." - return (hs_classifieds, extra_classifieds) + return (hs_classifieds, extra_classifieds, loaded_dlls) else let errmsg = text "unable to load unit `" <> pprUnitInfoForUser pkg <> text "'" in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg)) @@ -1244,19 +1251,20 @@ restriction very easily. -- can be passed directly to loadDLL. They are either fully-qualified -- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so"). In the latter case, -- loadDLL is going to search the system paths to find the library. -load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO () +load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO (Maybe (RemotePtr LoadedDLL)) load_dyn interp hsc_env crash_early dll = do r <- loadDLL interp dll case r of - Nothing -> return () - Just err -> + Right loaded_dll -> pure (Just loaded_dll) + Left err -> if crash_early then cmdLineErrorIO err - else + else do when (diag_wopt Opt_WarnMissedExtraSharedLib diag_opts) $ logMsg logger (mkMCDiagnostic diag_opts (WarningWithFlag Opt_WarnMissedExtraSharedLib) Nothing) noSrcSpan $ withPprStyle defaultUserStyle (note err) + pure Nothing where diag_opts = initDiagOpts (hsc_dflags hsc_env) logger = hsc_logger hsc_env ===================================== compiler/GHC/Linker/MacOS.hs ===================================== @@ -172,6 +172,6 @@ loadFramework interp extraPaths rootname findLoadDLL (p:ps) errs = do { dll <- loadDLL interp (p fwk_file) ; case dll of - Nothing -> return Nothing - Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs) + Right _ -> return Nothing + Left err -> findLoadDLL ps ((p ++ ": " ++ err):errs) } ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -40,7 +40,8 @@ import GHC.Prelude import GHC.Unit ( UnitId, Module ) import GHC.ByteCode.Types ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type ( Fingerprint ) -import GHCi.RemoteTypes ( ForeignHValue ) +import GHCi.RemoteTypes ( ForeignHValue, RemotePtr ) +import GHCi.Message ( LoadedDLL ) import GHC.Types.Var ( Id ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnvList, filterNameEnv ) @@ -75,6 +76,56 @@ initialised. The LinkerEnv maps Names to actual closures (for interpreted code only), for use during linking. + +Note [Looking up symbols in the relevant objects] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In #23415, we determined that a lot of time (>10s, or even up to >35s!) was +being spent on dynamically loading symbols before actually interpreting code +when `:main` was run in GHCi. The root cause was that for each symbol we wanted +to lookup, we would traverse the list of loaded objects and try find the symbol +in each of them with dlsym (i.e. looking up a symbol was, worst case, linear in +the amount of loaded objects). + +To drastically improve load time (from +-38 seconds down to +-2s), we now: + +1. For every of the native objects loaded for a given unit, store the handles returned by `dlopen`. + - In `pkgs_loaded` of the `LoaderState`, which maps `UnitId`s to + `LoadedPkgInfo`s, where the handles live in its field `loaded_pkg_hs_dlls`. + +2. When looking up a Name (e.g. `lookupHsSymbol`), find that name's `UnitId` in + the `pkgs_loaded` mapping, + +3. And only look for the symbol (with `dlsym`) on the /handles relevant to that + unit/, rather than in every loaded object. + +Note [Symbols may not be found in pkgs_loaded] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Despite storing and looking for symbols in the relevant loaded libraries +handles for a given unit-id, as described in the note above, we may still have +to fallback to the "slow" `lookupSymbol` function (see its "fallback" call in +`lookupHsSymbol`). + +TODO: Ben: my understanding here is flawed; could you make this clearer?. + +This fallback is still needed because a given unit may be associated with +static objects (`loaded_pkg_hs_objs`) only and no dynamic libraries, but we +only `lookupSymbolInDLL` for loaded dynamic libraries. In that case, +`lookupSymbol` will do the right thing because, besides looking up the symbol +in every loaded dylib, it will end up searching the static name table and find those symbols. + +Arguably, we should rather generalise `lookupSymbolInDLL` to +`lookupSymbolInObject`, where an object may be a DLL/native object (as in +`loadNativeObj`), or e.g. a static archive, instead of having a special case +for dynamic libraries. + +This fallback is further needed because we don't look in the haskell objects +loaded for the home units (see the call to `loadModuleLinkables` in +`loadDependencies`, as opposed to the call to `loadPackages'` in the same +function which updates `pkgs_loaded`). We should ultimately keep track of the +objects loaded (probably in `objs_loaded`, for which `LinkableSet` is a bit +unsatisfactory, see a suggestion in 51c5c4eb1f2a33e4dc88e6a37b7b7c135234ce9b) +and be able to lookup symbols specifically in them too (similarly to +`lookupSymbolInDLL`). -} newtype Loader = Loader { loader_state :: MVar (Maybe LoaderState) } @@ -146,11 +197,13 @@ data LoadedPkgInfo { loaded_pkg_uid :: !UnitId , loaded_pkg_hs_objs :: ![LibrarySpec] , loaded_pkg_non_hs_objs :: ![LibrarySpec] + , loaded_pkg_hs_dlls :: ![RemotePtr LoadedDLL] + -- ^ See Note [Looking up symbols in the relevant objects] , loaded_pkg_trans_deps :: UniqDSet UnitId } instance Outputable LoadedPkgInfo where - ppr (LoadedPkgInfo uid hs_objs non_hs_objs trans_deps) = + ppr (LoadedPkgInfo uid hs_objs non_hs_objs _ trans_deps) = vcat [ppr uid , ppr hs_objs , ppr non_hs_objs @@ -159,10 +212,10 @@ instance Outputable LoadedPkgInfo where -- | Information we can use to dynamically link modules into the compiler data Linkable = LM { - linkableTime :: !UTCTime, -- ^ Time at which this linkable was built + linkableTime :: !UTCTime, -- ^ Time at which this linkable was built -- (i.e. when the bytecodes were produced, -- or the mod date on the files) - linkableModule :: !Module, -- ^ The linkable module itself + linkableModule :: !Module, -- ^ The linkable module itself linkableUnlinked :: [Unlinked] -- ^ Those files and chunks of code we have yet to link. -- ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -35,6 +35,7 @@ module GHC.Runtime.Interpreter -- * The object-code linker , initObjLinker , lookupSymbol + , lookupSymbolInDLL , lookupClosure , loadDLL , loadArchive @@ -151,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -440,57 +441,78 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + +lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of +#if defined(HAVE_INTERNAL_INTERPRETER) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) +#endif + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either -- an absolute pathname to the file, or a relative filename -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. --- --- Returns: --- --- Nothing => success --- Just err_msg => failure -loadDLL :: Interp -> String -> IO (Maybe String) +loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL)) loadDLL interp str = interpCmd interp (LoadDLL str) loadArchive :: Interp -> String -> IO () @@ -549,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/Message.hs ===================================== @@ -23,6 +23,7 @@ module GHCi.Message , getMessage, putMessage, getTHMessage, putTHMessage , Pipe(..), remoteCall, remoteTHCall, readPipe, writePipe , BreakModule + , LoadedDLL ) where import Prelude -- See note [Why do we import Prelude here?] @@ -73,8 +74,9 @@ data Message a where -- These all invoke the corresponding functions in the RTS Linker API. InitLinker :: Message () LookupSymbol :: String -> Message (Maybe (RemotePtr ())) + LookupSymbolInDLL :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ())) LookupClosure :: String -> Message (Maybe HValueRef) - LoadDLL :: String -> Message (Maybe String) + LoadDLL :: String -> Message (Either String (RemotePtr LoadedDLL)) LoadArchive :: String -> Message () -- error? LoadObj :: String -> Message () -- error? UnloadObj :: String -> Message () -- error? @@ -415,6 +417,9 @@ instance Binary a => Binary (EvalResult a) -- that type isn't available here. data BreakModule +-- | A dummy type that tags pointers returned by 'LoadDLL'. +data LoadedDLL + -- SomeException can't be serialized because it contains dynamic -- types. However, we do very limited things with the exceptions that -- are thrown by interpreted computations: @@ -544,6 +549,7 @@ getMessage = do 37 -> Msg <$> return RtsRevertCAFs 38 -> Msg <$> (ResumeSeq <$> get) 39 -> Msg <$> (NewBreakModule <$> get) + 40 -> Msg <$> (LookupSymbolInDLL <$> get <*> get) _ -> error $ "Unknown Message code " ++ (show b) putMessage :: Message a -> Put @@ -588,7 +594,8 @@ putMessage m = case m of Seq a -> putWord8 36 >> put a RtsRevertCAFs -> putWord8 37 ResumeSeq a -> putWord8 38 >> put a - NewBreakModule name -> putWord8 39 >> put name + NewBreakModule name -> putWord8 39 >> put name + LookupSymbolInDLL dll str -> putWord8 40 >> put dll >> put str {- Note [Parallelize CreateBCOs serialization] ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -18,6 +18,7 @@ module GHCi.ObjLink , unloadObj , purgeObj , lookupSymbol + , lookupSymbolInDLL , lookupClosure , resolveObjs , addLibrarySearchPath @@ -27,18 +28,17 @@ module GHCi.ObjLink import Prelude -- See note [Why do we import Prelude here?] import GHCi.RemoteTypes +import GHCi.Message (LoadedDLL) import Control.Exception (throwIO, ErrorCall(..)) import Control.Monad ( when ) import Foreign.C -import Foreign.Marshal.Alloc ( free ) -import Foreign ( nullPtr ) +import Foreign.Marshal.Alloc ( alloca, free ) +import Foreign ( nullPtr, peek ) import GHC.Exts import System.Posix.Internals ( CFilePath, withFilePath, peekFilePath ) import System.FilePath ( dropExtension, normalise ) - - -- --------------------------------------------------------------------------- -- RTS Linker Interface -- --------------------------------------------------------------------------- @@ -70,6 +70,15 @@ lookupSymbol str_in = do then return Nothing else return (Just addr) +lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) +lookupSymbolInDLL dll str_in = do + let str = prefixUnderscore str_in + withCAString str $ \c_str -> do + addr <- c_lookupSymbolInNativeObj dll c_str + if addr == nullPtr + then return Nothing + else return (Just addr) + lookupClosure :: String -> IO (Maybe HValueRef) lookupClosure str = do m <- lookupSymbol str @@ -89,7 +98,7 @@ prefixUnderscore -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. -- -loadDLL :: String -> IO (Maybe String) +loadDLL :: String -> IO (Either String (Ptr LoadedDLL)) -- Nothing => success -- Just err_msg => failure loadDLL str0 = do @@ -101,12 +110,16 @@ loadDLL str0 = do str | isWindowsHost = dropExtension str0 | otherwise = str0 -- - maybe_errmsg <- withFilePath (normalise str) $ \dll -> c_addDLL dll - if maybe_errmsg == nullPtr - then return Nothing - else do str <- peekCString maybe_errmsg - free maybe_errmsg - return (Just str) + (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> + alloca $ \errmsg_ptr -> (,) + <$> c_loadNativeObj dll errmsg_ptr + <*> peek errmsg_ptr + + if maybe_handle == nullPtr + then do str <- peekCString maybe_errmsg + free maybe_errmsg + return (Left str) + else return (Right maybe_handle) loadArchive :: String -> IO () loadArchive str = do @@ -163,7 +176,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> IO CString +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== libraries/ghci/GHCi/Run.hs ===================================== @@ -66,7 +66,7 @@ run m = case m of LookupClosure str -> lookupJSClosure str #else InitLinker -> initObjLinker RetainCAFs - LoadDLL str -> loadDLL str + LoadDLL str -> fmap toRemotePtr <$> loadDLL str LoadArchive str -> loadArchive str LoadObj str -> loadObj str UnloadObj str -> unloadObj str @@ -81,6 +81,8 @@ run m = case m of #endif RtsRevertCAFs -> rts_revertCAFs LookupSymbol str -> fmap toRemotePtr <$> lookupSymbol str + LookupSymbolInDLL dll str -> + fmap toRemotePtr <$> lookupSymbolInDLL (fromRemotePtr dll) str FreeHValueRefs rs -> mapM_ freeRemoteRef rs AddSptEntry fpr r -> localRef r >>= sptAddEntry fpr EvalStmt opts r -> evalStmt opts r ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInDLL) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,90 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static const char * -internal_dlopen(const char *dll_name) -{ - OpenedSO* o_so; - void *hdl; - const char *errmsg; - char *errmsg_copy; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - errmsg = NULL; - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - errmsg = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return errmsg; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -660,11 +571,10 @@ internal_dlopen(const char *dll_name) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -672,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -725,79 +634,35 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } -# endif -const char * -addDLL( pathchar *dll_name ) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; + ACQUIRE_LOCK(&linker_mutex); - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - errmsg = internal_dlopen(dll_name); +#if defined(OBJFORMAT_MACHO) + CHECK(symbol_name[0] == '_'); + symbol_name = symbol_name+1; +#endif + void *result = dlsym(handle, symbol_name); - if (errmsg == NULL) { - return NULL; - } + RELEASE_LOCK(&linker_mutex); + return result; +} +# endif - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - return errmsg; // return original error if open fails - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - errmsg = internal_dlopen(line+match[2].rm_so); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +const char *addDLL(pathchar* dll_name) +{ +# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return errmsg; # elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name, NULL); + return addDLL_PEi386(dll_name); # else barf("addDLL: not implemented on this platform"); @@ -1228,10 +1093,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1896,12 +1761,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -1988,11 +1861,21 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); + void *r = loadNativeObj_POSIX(path, errmsg); + +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + RELEASE_LOCK(&linker_mutex); return r; } @@ -2006,7 +1889,7 @@ loadNativeObj (pathchar *path, char **errmsg) } #endif -HsInt unloadNativeObj (void *handle) +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2039,11 +1922,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -619,6 +619,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,8 +90,12 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); + /* load a dynamic library */ -const char *addDLL( pathchar* dll_name ); +const char *addDLL(pathchar* dll_name); + +void *lookupSymbolInDLL(void *handle, const char *symbol_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,211 @@ +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "LinkerInternals.h" +#include "Rts.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + + ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where ===================================== testsuite/tests/rts/linker/T2615.hs ===================================== @@ -6,5 +6,5 @@ main = do initObjLinker RetainCAFs result <- loadDLL library_name case result of - Nothing -> putStrLn (library_name ++ " loaded successfully") - Just x -> putStrLn ("error: " ++ x) + Right _ -> putStrLn (library_name ++ " loaded successfully") + Left x -> putStrLn ("error: " ++ x) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d86193a5803a7d820c30ed362e7e67a9aebd121...0ba67d90e6af52e2a564cac74c902828f8fc05a9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d86193a5803a7d820c30ed362e7e67a9aebd121...0ba67d90e6af52e2a564cac74c902828f8fc05a9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 19:12:23 2024 From: gitlab at gitlab.haskell.org (Oleg Grenrus (@phadej)) Date: Mon, 01 Apr 2024 15:12:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/unicode-splice Message-ID: <660b071721187_3a933935450d0598e0@gitlab.mail> Oleg Grenrus pushed new branch wip/unicode-splice at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/unicode-splice You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 1 22:35:29 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 01 Apr 2024 18:35:29 -0400 Subject: [Git][ghc/ghc][wip/T24463] 2 commits: Clone in CorePrep Message-ID: <660b36b1392ee_3a93394c57cc8670f4@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24463 at Glasgow Haskell Compiler / GHC Commits: 710ef4fa by Simon Peyton Jones at 2024-04-01T23:06:15+01:00 Clone in CorePrep - - - - - 4c445c97 by Simon Peyton Jones at 2024-04-01T23:33:55+01:00 Wibble - - - - - 3 changed files: - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs Changes: ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -20,7 +20,7 @@ module GHC.Core.TyCo.Subst extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, extendTCvSubst, extendTCvSubstWithClone, extendCvSubst, extendCvSubstWithClone, - extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone, + extendTvSubst, extendTvSubstWithClone, extendTvSubstList, extendTvSubstAndInScope, extendTCvSubstList, unionSubst, zipTyEnv, zipCoEnv, @@ -372,13 +372,6 @@ extendTvSubst (Subst in_scope ids tvs cvs) tv ty = assert (isTyVar tv) $ Subst in_scope ids (extendVarEnv tvs tv ty) cvs -extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst -extendTvSubstBinderAndInScope subst (Named (Bndr v _)) ty - = assert (isTyVar v ) - extendTvSubstAndInScope subst v ty -extendTvSubstBinderAndInScope subst (Anon {}) _ - = subst - extendTvSubstWithClone :: Subst -> TyVar -> TyVar -> Subst -- Adds a new tv -> tv mapping, /and/ extends the in-scope set with the clone -- Does not look in the kind of the new variable; ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -205,8 +205,7 @@ module GHC.Core.Type ( zapSubst, getSubstInScope, setInScope, getSubstRangeTyCoFVs, extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, extendTCvSubst, extendCvSubst, - extendTvSubst, extendTvSubstBinderAndInScope, - extendTvSubstList, extendTvSubstAndInScope, + extendTvSubst, extendTvSubstList, extendTvSubstAndInScope, extendTCvSubstList, extendTvSubstWithClone, extendTCvSubstWithClone, ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Core.Utils import GHC.Core.Opt.Arity import GHC.Core.Lint ( EndPassConfig(..), endPassIO ) import GHC.Core +import GHC.Core.Subst import GHC.Core.Make hiding( FloatBind(..) ) -- We use our own FloatBind here import GHC.Core.Type import GHC.Core.Coercion @@ -56,7 +57,6 @@ import GHC.Utils.Logger import GHC.Types.Demand import GHC.Types.Var -import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) @@ -763,10 +763,10 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) -- For example -- f (g x) ===> ([v = g x], f v) -cpeRhsE _ (Type ty) - = return (emptyFloats, Type ty) -cpeRhsE _ (Coercion co) - = return (emptyFloats, Coercion co) +cpeRhsE env (Type ty) + = return (emptyFloats, Type (cpSubstTy env ty)) +cpeRhsE env (Coercion co) + = return (emptyFloats, Coercion (cpSubstCo env co)) cpeRhsE env expr@(Lit lit) | LitNumber LitNumBigNat i <- lit = cpeBigNatLit env i @@ -799,7 +799,7 @@ cpeRhsE env (Tick tickish expr) cpeRhsE env (Cast expr co) = do { (floats, expr') <- cpeRhsE env expr - ; return (floats, Cast expr' co) } + ; return (floats, Cast expr' (cpSubstCo env co)) } cpeRhsE env expr@(Lam {}) = do { let (bndrs,body) = collectBinders expr @@ -807,7 +807,7 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } -cpeRhsE env (Case scrut bndr _ alts@[Alt con bs _]) +cpeRhsE env (Case scrut bndr _ alts@[Alt con [covar] _]) -- See (U3) in Note [Implementing unsafeCoerce] -- We need make the Case float, otherwise we get -- let x = case ... of UnsafeRefl co -> @@ -823,14 +823,14 @@ cpeRhsE env (Case scrut bndr _ alts@[Alt con bs _]) -- (such as `print003`). | Just rhs <- isUnsafeEqualityCase scrut bndr alts = do { (floats_scrut, scrut) <- cpeBody env scrut - ; (env, bndr) <- cpCloneBndr env bndr - ; (env, bs) <- cpCloneBndrs env bs + ; (env, bndr') <- cpCloneBndr env bndr + ; (env, covar') <- cpCloneCoVarBndr env covar -- Up until here this should do exactly the same as the regular code -- path of `cpeRhsE Case{}`. ; (floats_rhs, rhs) <- cpeBody env rhs -- ... but we want to float `floats_rhs` as in (U3) so that rhs' might -- become a value - ; let case_float = UnsafeEqualityCase scrut bndr con bs + ; let case_float = UnsafeEqualityCase scrut bndr' con [covar'] -- NB: It is OK to "evaluate" the proof eagerly. -- Usually there's the danger that we float the unsafeCoerce out of -- a branching Case alt. Not so here, because the regular code path @@ -849,7 +849,7 @@ cpeRhsE env (Case scrut bndr ty alts) where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 ty alts'') } + ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -1184,10 +1184,14 @@ cpeApp top_env expr in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) - -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth + -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth + where + arg_ty' = cpSubstTy env arg_ty CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth + -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth + where + co' = cpSubstCo env co CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make @@ -1199,7 +1203,10 @@ cpeApp top_env expr rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co - -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth + -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth + where + co' = cpSubstCo env co + -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -2220,6 +2227,7 @@ binding for data constructors; see Note [Data constructor workers]. Note [CorePrep inlines trivial CoreExpr not Id] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +TODO Why does cpe_env need to be an IdEnv CoreExpr, as opposed to an IdEnv Id? Naively, we might conjecture that trivial updatable thunks as per Note [Inlining in CorePrep] always have the form @@ -2259,8 +2267,8 @@ data CorePrepEnv -- the case where a function we think should bottom -- unexpectedly returns. - , cpe_env :: IdEnv CoreExpr -- Clone local Ids - -- ^ This environment is used for three operations: + , cpe_subst :: Subst + -- ^ The IdEnv part of the substitution is used for three operations: -- -- 1. To support cloning of local Ids so that they are -- all unique (see item (6) of CorePrep overview). @@ -2271,6 +2279,9 @@ data CorePrepEnv -- 3. To let us inline trivial RHSs of non top-level let-bindings, -- see Note [lazyId magic], Note [Inlining in CorePrep] -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) + -- + -- The TyCoVar part of the substitution is used only for + -- Note [UnsafeEqualityProof] , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } @@ -2278,33 +2289,48 @@ data CorePrepEnv mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg - , cpe_env = emptyVarEnv + , cpe_subst = emptySubst , cpe_rec_ids = emptyUnVarSet } extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv -extendCorePrepEnv cpe id id' - = cpe { cpe_env = extendVarEnv (cpe_env cpe) id (Var id') } +extendCorePrepEnv cpe@(CPE { cpe_subst = subst }) id id' + = cpe { cpe_subst = subst2 } + where + subst1 = extendSubstInScope subst id' + subst2 = extendIdSubst subst1 id (Var id') + +extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv +extendCorePrepEnvList cpe@(CPE { cpe_subst = subst }) prs + = cpe { cpe_subst = subst2 } + where + subst1 = extendSubstInScopeList subst (map snd prs) + subst2 = extendIdSubstList subst1 [(id, Var id') | (id,id') <- prs] extendCorePrepEnvExpr :: CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv extendCorePrepEnvExpr cpe id expr - = cpe { cpe_env = extendVarEnv (cpe_env cpe) id expr } - -extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv -extendCorePrepEnvList cpe prs - = cpe { cpe_env = extendVarEnvList (cpe_env cpe) - (map (\(id, id') -> (id, Var id')) prs) } + = cpe { cpe_subst = extendIdSubst (cpe_subst cpe) id expr } lookupCorePrepEnv :: CorePrepEnv -> Id -> CoreExpr lookupCorePrepEnv cpe id - = case lookupVarEnv (cpe_env cpe) id of - Nothing -> Var id - Just exp -> exp + = case lookupIdSubst_maybe (cpe_subst cpe) id of + Just e -> e + Nothing -> Var id + -- Do not use GHC.Core.Subs.lookupIdSubst because that is a no-op on GblIds; + -- and Tidy has made top-level externally-visible Ids into GblIds enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv enterRecGroupRHSs env grp = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } +cpSubstTy :: CorePrepEnv -> Type -> Type +cpSubstTy (CPE { cpe_subst = subst }) ty = substTy subst ty + -- substTy has a short-cut if the TCvSubst is empty + +cpSubstCo :: CorePrepEnv -> Coercion -> Coercion +cpSubstCo (CPE { cpe_subst = subst }) co = substCo subst co + -- substCo has a short-cut if the TCvSubst is empty + ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2312,12 +2338,29 @@ enterRecGroupRHSs env grp cpCloneBndrs :: CorePrepEnv -> [InVar] -> UniqSM (CorePrepEnv, [OutVar]) cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs +cpCloneCoVarBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) +cpCloneCoVarBndr env@(CPE { cpe_subst = subst }) covar + = assertPpr (isCoVar covar) (ppr covar) $ + do { uniq <- getUniqueM + ; let covar1 = setVarUnique covar uniq + covar2 = updateVarType (substTy subst) covar1 + subst1 = extendTCvSubstWithClone subst covar covar2 + ; return (env { cpe_subst = subst1 }, covar2) } + cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) -cpCloneBndr env bndr +-- See Note [CorePrep Overview] point (6) +cpCloneBndr env@(CPE { cpe_subst = subst }) bndr | isTyCoVar bndr - = return (env, bndr) - | otherwise - = do { bndr' <- clone_it bndr + = if isEmptyTCvSubst subst + then return (env, bndr) -- The common case + else -- No need to clone the Unique; but apply the substitution + let bndr1 = updateVarType (substTy subst) bndr + subst1 = extendTCvSubstWithClone subst bndr bndr1 + in return (env { cpe_subst = subst1 }, bndr1) + + | otherwise -- A non-CoVar Id + = do { bndr1 <- clone_it bndr + ; let bndr2 = updateIdTypeAndMult (substTy subst) bndr1 -- Drop (now-useless) rules/unfoldings -- See Note [Drop unfoldings and rules] @@ -2327,10 +2370,10 @@ cpCloneBndr env bndr ; let !unfolding' = trimUnfolding (realIdUnfolding bndr) -- Simplifier will set the Id's unfolding - bndr'' = bndr' `setIdUnfolding` unfolding' - `setIdSpecialisation` emptyRuleInfo + bndr3 = bndr2 `setIdUnfolding` unfolding' + `setIdSpecialisation` emptyRuleInfo - ; return (extendCorePrepEnv env bndr bndr'', bndr'') } + ; return (extendCorePrepEnv env bndr bndr3, bndr3) } where clone_it bndr | isLocalId bndr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/42237c9f9094c0b9527d4884c559e1282724cea0...4c445c97492dfe9a5d12fb2b13d4291a4daa30c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/42237c9f9094c0b9527d4884c559e1282724cea0...4c445c97492dfe9a5d12fb2b13d4291a4daa30c2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 02:42:28 2024 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Mon, 01 Apr 2024 22:42:28 -0400 Subject: [Git][ghc/ghc][wip/multiline-strings] 54 commits: Fix sharing of 'IfaceTyConInfo' during core to iface type translation Message-ID: <660b70946db9_1c6b478585444293@gitlab.mail> Brandon Chinn pushed to branch wip/multiline-strings at Glasgow Haskell Compiler / GHC Commits: 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - 912f2374 by Brandon Chinn at 2024-04-01T19:41:21-07:00 Add MultilineStrings extension - - - - - ef2f26fa by Brandon Chinn at 2024-04-01T19:41:21-07:00 Add test cases for MultilineStrings - - - - - ea19627a by Brandon Chinn at 2024-04-01T19:41:21-07:00 Break out common lex_magic_hash logic for strings and chars - - - - - 49a6f25e by Brandon Chinn at 2024-04-01T19:41:21-07:00 Factor out string processing functions - - - - - e5add677 by Brandon Chinn at 2024-04-01T19:41:21-07:00 Implement MultilineStrings (#24390) Updates haddock submodule for new ITmultiline constructor - - - - - 3aa8bea0 by Brandon Chinn at 2024-04-01T19:42:16-07:00 Add docs for MultilineStrings - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/TyCo/Compare.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/Word64Map/Strict.hs - compiler/GHC/Driver/CmdLine.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Foreign/Call.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/HsToCore/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/775254fb84509381e042bba0d03d3b88139e6eed...3aa8bea0e1da042d78522ca9ebd738cfa3226131 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/775254fb84509381e042bba0d03d3b88139e6eed...3aa8bea0e1da042d78522ca9ebd738cfa3226131 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 07:39:09 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 03:39:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/seek-bin-off-by-one Message-ID: <660bb61d8c02f_1d9a9f7c1f6425966@gitlab.mail> Hannes Siebenhandl pushed new branch wip/seek-bin-off-by-one at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/seek-bin-off-by-one You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 07:55:14 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 03:55:14 -0400 Subject: [Git][ghc/ghc][wip/seek-bin-off-by-one] 2 commits: Fix off by one error in seekBinNoExpand and seekBin Message-ID: <660bb9e268077_1d9a9f97d2b832086@gitlab.mail> Hannes Siebenhandl pushed to branch wip/seek-bin-off-by-one at Glasgow Haskell Compiler / GHC Commits: 2994fafc by Matthew Pickering at 2024-04-02T09:44:03+02:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - f7d2f9e1 by Fendor at 2024-04-02T09:45:39+02:00 Remove `seekBin` function Binary utility `seekBin` used to expand the buffer of the `BinMem` handle. This is dubious, because the only way to call `seekBin` requires us use `tellBin`, which always gives us a pointer to already allocated index. As we don't have a way to reduce the buffer size of the underlying `BinArray`, there is no way to create an out-of-bounds pointer for the same `BinArray`. Thus, it is effectively a bug, if anyone manages to seek to an out-of-bounds location. We make this more clear by removing `seekBin` and replacing all occurrences with `seekBinNoExpand`. - - - - - 5 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -135,7 +135,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpand bh extFields_p extFields <- get bh return mod_iface @@ -191,7 +191,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p <- tellBin bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinNoExpand bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -113,7 +113,7 @@ writeHieFile hie_file_path hiefile = do -- write the symtab pointer at the front of the file symtab_p <- tellBin bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinNoExpand bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -123,7 +123,7 @@ writeHieFile hie_file_path hiefile = do -- write the dictionary pointer at the front of the file dict_p <- tellBin bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinNoExpand bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -232,17 +232,17 @@ readHieFileContents bh0 name_cache = do get_dictionary bin_handle = do dict_p <- get bin_handle data_p <- tellBin bin_handle - seekBin bin_handle dict_p + seekBinNoExpand bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpand bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 data_p' <- tellBin bh1 - seekBin bh1 symtab_p + seekBinNoExpand bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpand bh1 data_p' return symtab putFastString :: HieDictionary -> BinHandle -> FastString -> IO () ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -42,7 +42,7 @@ instance Binary ExtensibleFields where forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBin bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinNoExpand bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpand bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -392,7 +392,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpand bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -28,9 +28,9 @@ module GHC.Utils.Binary unsafeUnpackBinBuffer, openBinMem, + seekBinNoExpand, -- closeBin, - seekBin, tellBin, castBin, withBinBuffer, @@ -222,10 +222,10 @@ class Binary a where put bh a = do p <- tellBin bh; put_ bh a; return p putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt bh p x = do seekBinNoExpand bh p; put_ bh x; return () getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt bh p = do seekBinNoExpand bh p; get bh openBinMem :: Int -> IO BinHandle openBinMem size @@ -240,18 +240,14 @@ openBinMem size tellBin :: BinHandle -> IO (Bin a) tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do - sz <- readFastMutInt sz_r - if (p >= sz) - then do expandBin h p; writeFastMutInt ix_r p - else writeFastMutInt ix_r p - --- | SeekBin but without calling expandBin +-- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- by 'Bin a'. +-- This operation may 'panic', if the pointer location is out of bounds of the +-- buffer of 'BinHandle'. seekBinNoExpand :: BinHandle -> Bin a -> IO () seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p @@ -1025,7 +1021,7 @@ lazyPut bh a = do put_ bh a -- dump the object q <- tellBin bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinNoExpand bh q -- finally carry on writing at q lazyGet :: Binary a => BinHandle -> IO a lazyGet bh = do @@ -1036,7 +1032,7 @@ lazyGet bh = do -- safety. off_r <- newFastMutInt 0 getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + seekBinNoExpand bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11409d511801e3dfb8edeaeffb9e11ce7ef36181...f7d2f9e18e9705cd8e44c903f0129c5d1567d081 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11409d511801e3dfb8edeaeffb9e11ce7ef36181...f7d2f9e18e9705cd8e44c903f0129c5d1567d081 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 07:57:15 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 03:57:15 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/remove-seek-bin Message-ID: <660bba5b70d5b_1d9a9f9cb8143223a@gitlab.mail> Hannes Siebenhandl pushed new branch wip/remove-seek-bin at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/remove-seek-bin You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 07:57:29 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 03:57:29 -0400 Subject: [Git][ghc/ghc][wip/seek-bin-off-by-one] Deleted 1 commit: Remove `seekBin` function Message-ID: <660bba6987d96_1d9a9fa03f0c324d6@gitlab.mail> Hannes Siebenhandl pushed to branch wip/seek-bin-off-by-one at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: f7d2f9e1 by Fendor at 2024-04-02T09:45:39+02:00 Remove `seekBin` function Binary utility `seekBin` used to expand the buffer of the `BinMem` handle. This is dubious, because the only way to call `seekBin` requires us use `tellBin`, which always gives us a pointer to already allocated index. As we don't have a way to reduce the buffer size of the underlying `BinArray`, there is no way to create an out-of-bounds pointer for the same `BinArray`. Thus, it is effectively a bug, if anyone manages to seek to an out-of-bounds location. We make this more clear by removing `seekBin` and replacing all occurrences with `seekBinNoExpand`. - - - - - 5 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -135,7 +135,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpand bh extFields_p extFields <- get bh return mod_iface @@ -191,7 +191,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p <- tellBin bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinNoExpand bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -113,7 +113,7 @@ writeHieFile hie_file_path hiefile = do -- write the symtab pointer at the front of the file symtab_p <- tellBin bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinNoExpand bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -123,7 +123,7 @@ writeHieFile hie_file_path hiefile = do -- write the dictionary pointer at the front of the file dict_p <- tellBin bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinNoExpand bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -232,17 +232,17 @@ readHieFileContents bh0 name_cache = do get_dictionary bin_handle = do dict_p <- get bin_handle data_p <- tellBin bin_handle - seekBin bin_handle dict_p + seekBinNoExpand bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpand bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 data_p' <- tellBin bh1 - seekBin bh1 symtab_p + seekBinNoExpand bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpand bh1 data_p' return symtab putFastString :: HieDictionary -> BinHandle -> FastString -> IO () ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -42,7 +42,7 @@ instance Binary ExtensibleFields where forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBin bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinNoExpand bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpand bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -392,7 +392,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpand bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -28,9 +28,9 @@ module GHC.Utils.Binary unsafeUnpackBinBuffer, openBinMem, + seekBinNoExpand, -- closeBin, - seekBin, tellBin, castBin, withBinBuffer, @@ -222,10 +222,10 @@ class Binary a where put bh a = do p <- tellBin bh; put_ bh a; return p putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt bh p x = do seekBinNoExpand bh p; put_ bh x; return () getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt bh p = do seekBinNoExpand bh p; get bh openBinMem :: Int -> IO BinHandle openBinMem size @@ -240,13 +240,6 @@ openBinMem size tellBin :: BinHandle -> IO (Bin a) tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do - sz <- readFastMutInt sz_r - if (p > sz) - then do expandBin h p; writeFastMutInt ix_r p - else writeFastMutInt ix_r p - -- | 'seekBinNoExpand' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the @@ -1028,7 +1021,7 @@ lazyPut bh a = do put_ bh a -- dump the object q <- tellBin bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinNoExpand bh q -- finally carry on writing at q lazyGet :: Binary a => BinHandle -> IO a lazyGet bh = do @@ -1039,7 +1032,7 @@ lazyGet bh = do -- safety. off_r <- newFastMutInt 0 getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + seekBinNoExpand bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d2f9e18e9705cd8e44c903f0129c5d1567d081 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d2f9e18e9705cd8e44c903f0129c5d1567d081 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 08:13:33 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 04:13:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/nounpack-z-encs-faststring Message-ID: <660bbe2d2cf59_1d9a9fc4f33836683@gitlab.mail> Hannes Siebenhandl pushed new branch wip/nounpack-z-encs-faststring at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/nounpack-z-encs-faststring You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 10:32:31 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 06:32:31 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ghc-iface-refact Message-ID: <660bdebf32348_26e1f632434458638@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ghc-iface-refact You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 10:40:52 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 06:40:52 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660be0b47d32a_26e1f63daedc5886b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 46254161 by Fendor at 2024-04-02T12:39:30+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 345e81f4 by Fendor at 2024-04-02T12:40:31+02:00 Fixup: Generic Symbol Table - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,19 +111,19 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next symtab_map' <- readIORef symtab_map putSymbolTable bh symtab_next' symtab_map' - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + -- write the tellBinWriter pointer at the front of the file + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -90,10 +90,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -88,6 +90,12 @@ module GHC.Utils.Binary putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +179,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +274,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +298,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +357,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +394,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +410,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +431,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +453,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +491,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +504,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +516,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +537,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +563,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +588,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +612,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +640,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1059,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1123,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1220,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1261,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1270,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,14 +1291,80 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol } +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: WriteBinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- @@ -1299,14 +1402,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1418,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1460,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08f11545cae90c5187fb05b71299e7a4f0e727ad...345e81f47d9f811c124207ce51cf8f95bdb01b1e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08f11545cae90c5187fb05b71299e7a4f0e727ad...345e81f47d9f811c124207ce51cf8f95bdb01b1e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 10:50:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 06:50:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ghc-iface-refact-with-gen-sym-table Message-ID: <660be2f662d63_26e1f654d1c0590dd@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ghc-iface-refact-with-gen-sym-table at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ghc-iface-refact-with-gen-sym-table You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 10:51:06 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 06:51:06 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Deleted 1 commit: Fixup: Generic Symbol Table Message-ID: <660be31a9a063_26e1f659e020592c0@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: 345e81f4 by Fendor at 2024-04-02T12:40:31+02:00 Fixup: Generic Symbol Table - - - - - 1 changed file: - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -89,15 +89,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, -<<<<<<< HEAD - -- * Generic Symbol that can be used for user-defined deduplication tables. - GenericSymbolTable(..), - initGenericSymbolTable, - putGenericSymbolTable, getGenericSymbolTable, - putGenericSymTab, getGenericSymtab, -||||||| parent of f3fd018a62 (Fixup: Generic Symbol Table) - -======= -- * Generic Symbol that can be used for user-defined deduplication tables. GenericSymbolTable(..), @@ -105,7 +96,6 @@ module GHC.Utils.Binary putGenericSymbolTable, getGenericSymbolTable, putGenericSymTab, getGenericSymtab, ->>>>>>> f3fd018a62 (Fixup: Generic Symbol Table) -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -1330,7 +1320,7 @@ initGenericSymbolTable = do , gen_symtab_map = symtab_map } -putGenericSymbolTable :: forall a. GenericSymbolTable a -> (BinHandle -> a -> IO ()) -> BinHandle -> IO Int +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int putGenericSymbolTable gen_sym_tab serialiser bh = do table_count <- readFastMutInt symtab_next symtab_map <- readIORef symtab_map @@ -1339,13 +1329,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do where symtab_map = gen_symtab_map gen_sym_tab symtab_next = gen_symtab_next gen_sym_tab - putGenericSymbolTable :: BinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable :: WriteBinHandle -> Int -> Map.Map a Int -> IO () putGenericSymbolTable bh name_count symtab = do put_ bh name_count let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) mapM_ (\n -> serialiser bh n) genElements -getGenericSymbolTable :: forall a. (BinHandle -> IO a) -> BinHandle -> IO (SymbolTable a) +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) @@ -1354,7 +1344,7 @@ getGenericSymbolTable deserialiser bh = do writeArray mut_arr i f unsafeFreeze mut_arr -putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> BinHandle -> a -> IO () +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () putGenericSymTab GenericSymbolTable{ gen_symtab_map = symtab_map_ref, gen_symtab_next = symtab_next } @@ -1370,7 +1360,7 @@ putGenericSymTab GenericSymbolTable{ put_ bh (fromIntegral off :: Word32) getGenericSymtab :: Binary a => SymbolTable a - -> BinHandle -> IO a + -> ReadBinHandle -> IO a getGenericSymtab symtab bh = do i :: Word32 <- get bh return $! symtab ! fromIntegral i View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/345e81f47d9f811c124207ce51cf8f95bdb01b1e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/345e81f47d9f811c124207ce51cf8f95bdb01b1e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 10:56:14 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 06:56:14 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <660be44ee24c_26e1f6733da463048@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: df5c3fc0 by Fendor at 2024-04-02T12:55:43+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. - - - - - aa3ccba8 by Fendor at 2024-04-02T12:55:43+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -54,6 +53,7 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import Data.Functor.Identity -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,32 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) - - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) - - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) - - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) - --- | Write an interface file + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + tables :: [SomeReaderTable IO] + tables = + [ SomeReaderTable initFastStringReaderTable + , SomeReaderTable (initReadNameCachedBinary name_cache) + ] + + tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables + + final_bh <- foldM (\bh (SomeReaderTable (tbl' :: Identity (ReaderTable a))) -> do + let tbl = runIdentity tbl' + res <- Binary.forwardGet bh (getTable tbl bh) + let newDecoder = mkReaderFromTable tbl res + pure $ addReaderToUserData (mkSomeBinaryReader newDecoder) bh + ) bh tables + + pure final_bh + +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +235,39 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + writerTables = + [ SomeWriterTable initFastStringWriterTable + , SomeWriterTable initWriteNameTable + ] + + tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + + let writerUserData = + mkWriterUserData $ + map + (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) + tables + + let bh = setWriterUserData bh' writerUserData + (fs_count : name_count : _, r) <- + putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +279,108 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be duplicated 'FastString's and 'Name's. +To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ │ +│ ModIface │ +│ Payload │ +│ │ +├──────────────┤ +│ Ptr FS ├───────────┐ +├──────────────┤ │ +│ Ptr Name ├────────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄───────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄──────────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) +initReadNameCachedBinary cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +434,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +459,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +478,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,25 +105,25 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next symtab_map' <- readIORef symtab_map putSymbolTable bh symtab_next' symtab_map' - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + -- write the tellBinWriter pointer at the front of the file + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +213,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -520,7 +520,7 @@ checkFlagHash :: HscEnv -> ModIface -> IO RecompileRequired checkFlagHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_flag_hash (mi_final_exts iface) - new_hash <- fingerprintDynFlags hsc_env (mi_module iface) putNameLiterally + new_hash <- fingerprintDynFlags hsc_env (mi_module iface) case old_hash == new_hash of True -> up_to_date logger (text "Module flags unchanged") False -> out_of_date_hash logger FlagsChanged @@ -533,7 +533,6 @@ checkOptimHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_opt_hash (mi_final_exts iface) new_hash <- fingerprintOptFlags (hsc_dflags hsc_env) - putNameLiterally if | old_hash == new_hash -> up_to_date logger (text "Optimisation flags unchanged") | gopt Opt_IgnoreOptimChanges (hsc_dflags hsc_env) @@ -549,7 +548,6 @@ checkHpcHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_hpc_hash (mi_final_exts iface) new_hash <- fingerprintHpcFlags (hsc_dflags hsc_env) - putNameLiterally if | old_hash == new_hash -> up_to_date logger (text "HPC flags unchanged") | gopt Opt_IgnoreHpcChanges (hsc_dflags hsc_env) @@ -960,7 +958,6 @@ addFingerprints -> IO ModIface addFingerprints hsc_env iface0 = do - eps <- hscEPS hsc_env let decls = mi_decls iface0 decl_warn_fn = mkIfaceDeclWarnCache (fromIfaceWarnings $ mi_warns iface0) @@ -1023,40 +1020,6 @@ addFingerprints hsc_env iface0 groups :: [SCC IfaceDeclABI] groups = stronglyConnCompFromEdgedVerticesOrd edges - global_hash_fn = mkHashFun hsc_env eps - - -- How to output Names when generating the data to fingerprint. - -- Here we want to output the fingerprint for each top-level - -- Name, whether it comes from the current module or another - -- module. In this way, the fingerprint for a declaration will - -- change if the fingerprint for anything it refers to (transitively) - -- changes. - mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () - mk_put_name local_env bh name - | isWiredInName name = putNameLiterally bh name - -- wired-in names don't have fingerprints - | otherwise - = assertPpr (isExternalName name) (ppr name) $ - let hash | nameModule name /= semantic_mod = global_hash_fn name - -- Get it from the REAL interface!! - -- This will trigger when we compile an hsig file - -- and we know a backing impl for it. - -- See Note [Identity versus semantic module] - | semantic_mod /= this_mod - , not (isHoleModule semantic_mod) = global_hash_fn name - | otherwise = return (snd (lookupOccEnv local_env (getOccName name) - `orElse` pprPanic "urk! lookup local fingerprint" - (ppr name $$ ppr local_env))) - -- This panic indicates that we got the dependency - -- analysis wrong, because we needed a fingerprint for - -- an entity that wasn't in the environment. To debug - -- it, turn the panic into a trace, uncomment the - -- pprTraces below, run the compile again, and inspect - -- the output and the generated .hi file with - -- --show-iface. - in hash >>= put_ bh - -- take a strongly-connected group of declarations and compute -- its fingerprint. @@ -1067,23 +1030,18 @@ addFingerprints hsc_env iface0 [(Fingerprint,IfaceDecl)]) fingerprint_group (local_env, decls_w_hashes) (AcyclicSCC abi) - = do let hash_fn = mk_put_name local_env - decl = abiDecl abi + = do let decl = abiDecl abi --pprTrace "fingerprinting" (ppr (ifName decl) ) $ do - hash <- computeFingerprint hash_fn abi + hash <- computeFingerprint abi env' <- extend_hash_env local_env (hash,decl) return (env', (hash,decl) : decls_w_hashes) fingerprint_group (local_env, decls_w_hashes) (CyclicSCC abis) = do let stable_abis = sortBy cmp_abiNames abis stable_decls = map abiDecl stable_abis - local_env1 <- foldM extend_hash_env local_env - (zip (map mkRecFingerprint [0..]) stable_decls) - -- See Note [Fingerprinting recursive groups] - let hash_fn = mk_put_name local_env1 -- pprTrace "fingerprinting" (ppr (map ifName decls) ) $ do -- put the cycle in a canonical order - hash <- computeFingerprint hash_fn stable_abis + hash <- computeFingerprint stable_abis let pairs = zip (map (bumpFingerprint hash) [0..]) stable_decls -- See Note [Fingerprinting recursive groups] local_env2 <- foldM extend_hash_env local_env pairs @@ -1156,11 +1114,10 @@ addFingerprints hsc_env iface0 -- instances yourself, no need to consult hs-boot; if you do load the -- interface into EPS, you will see a duplicate orphan instance. - orphan_hash <- computeFingerprint (mk_put_name local_env) - (map ifDFun orph_insts, orph_rules, orph_fis) + orphan_hash <- computeFingerprint (map ifDFun orph_insts, orph_rules, orph_fis) -- Hash of the transitive things in dependencies - dep_hash <- computeFingerprint putNameLiterally + dep_hash <- computeFingerprint (dep_sig_mods (mi_deps iface0), dep_boot_mods (mi_deps iface0), -- Trusted packages are like orphans @@ -1170,7 +1127,7 @@ addFingerprints hsc_env iface0 -- the export list hash doesn't depend on the fingerprints of -- the Names it mentions, only the Names themselves, hence putNameLiterally. - export_hash <- computeFingerprint putNameLiterally + export_hash <- computeFingerprint (mi_exports iface0, orphan_hash, dep_hash, @@ -1229,11 +1186,11 @@ addFingerprints hsc_env iface0 -- - (some of) dflags -- it returns two hashes, one that shouldn't change -- the abi hash and one that should - flag_hash <- fingerprintDynFlags hsc_env this_mod putNameLiterally + flag_hash <- fingerprintDynFlags hsc_env this_mod - opt_hash <- fingerprintOptFlags dflags putNameLiterally + opt_hash <- fingerprintOptFlags dflags - hpc_hash <- fingerprintHpcFlags dflags putNameLiterally + hpc_hash <- fingerprintHpcFlags dflags plugin_hash <- fingerprintPlugins (hsc_plugins hsc_env) @@ -1243,7 +1200,7 @@ addFingerprints hsc_env iface0 -- - orphans -- - deprecations -- - flag abi hash - mod_hash <- computeFingerprint putNameLiterally + mod_hash <- computeFingerprint (map fst sorted_decls, export_hash, -- includes orphan_hash mi_warns iface0) @@ -1255,7 +1212,7 @@ addFingerprints hsc_env iface0 -- - usages -- - deps (home and external packages, dependent files) -- - hpc - iface_hash <- computeFingerprint putNameLiterally + iface_hash <- computeFingerprint (mod_hash, mi_src_hash iface0, ann_fn (mkVarOccFS (fsLit "module")), -- See mkIfaceAnnCache @@ -1594,57 +1551,6 @@ mkOrphMap get_key decls = (extendOccEnv_Acc (:) Utils.singleton non_orphs occ d, orphs) | otherwise = (non_orphs, d:orphs) --- ----------------------------------------------------------------------------- --- Look up parents and versions of Names - --- This is like a global version of the mi_hash_fn field in each ModIface. --- Given a Name, it finds the ModIface, and then uses mi_hash_fn to get --- the parent and version info. - -mkHashFun - :: HscEnv -- needed to look up versions - -> ExternalPackageState -- ditto - -> (Name -> IO Fingerprint) -mkHashFun hsc_env eps name - | isHoleModule orig_mod - = lookup (mkHomeModule home_unit (moduleName orig_mod)) - | otherwise - = lookup orig_mod - where - home_unit = hsc_home_unit hsc_env - dflags = hsc_dflags hsc_env - hpt = hsc_HUG hsc_env - pit = eps_PIT eps - ctx = initSDocContext dflags defaultUserStyle - occ = nameOccName name - orig_mod = nameModule name - lookup mod = do - massertPpr (isExternalName name) (ppr name) - iface <- case lookupIfaceByModule hpt pit mod of - Just iface -> return iface - Nothing -> - -- This can occur when we're writing out ifaces for - -- requirements; we didn't do any /real/ typechecking - -- so there's no guarantee everything is loaded. - -- Kind of a heinous hack. - initIfaceLoad hsc_env . withIfaceErr ctx - $ withoutDynamicNow - -- If you try and load interfaces when dynamic-too - -- enabled then it attempts to load the dyn_hi and hi - -- interface files. Backpack doesn't really care about - -- dynamic object files as it isn't doing any code - -- generation so -dynamic-too is turned off. - -- Some tests fail without doing this (such as T16219), - -- but they fail because dyn_hi files are not found for - -- one of the dependencies (because they are deliberately turned off) - -- Why is this check turned off here? That is unclear but - -- just one of the many horrible hacks in the backpack - -- implementation. - $ loadInterface (text "lookupVers2") mod ImportBySystem - return $ snd (mi_hash_fn (mi_final_exts iface) occ `orElse` - pprPanic "lookupVers1" (ppr mod <+> ppr occ)) - - -- | Creates cached lookup for the 'mi_anns' field of ModIface -- Hackily, we use "module" as the OccName for any module-level annotations mkIfaceAnnCache :: [IfaceAnnotation] -> OccName -> [AnnPayload] ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,20 +26,18 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) - -> a + => a -> IO Fingerprint -computeFingerprint put_nonbinding_name a = do +computeFingerprint a = do bh <- fmap set_user_data $ openBinMem (3*1024) -- just less than a block put_ bh a fingerprintBinMem bh where - set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ newWriteState putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -13,9 +13,7 @@ import GHC.Prelude import GHC.Driver.Session import GHC.Driver.Env -import GHC.Utils.Binary import GHC.Unit.Module -import GHC.Types.Name import GHC.Types.SafeHaskell import GHC.Utils.Fingerprint import GHC.Iface.Recomp.Binary @@ -31,10 +29,9 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintDynFlags hsc_env this_mod nameio = +fingerprintDynFlags hsc_env this_mod = let dflags at DynFlags{..} = hsc_dflags hsc_env mainis = if mainModIs (hsc_HUE hsc_env) == this_mod then Just mainFunIs else Nothing -- see #5878 @@ -73,7 +70,7 @@ fingerprintDynFlags hsc_env this_mod nameio = flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, codegen, debugLevel, callerCcFilters)) in -- pprTrace "flags" (ppr flags) $ - computeFingerprint nameio flags + computeFingerprint flags -- Fingerprint the optimisation info. We keep this separate from the rest of -- the flags because GHCi users (especially) may wish to ignore changes in @@ -81,9 +78,8 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintOptFlags DynFlags{..} nameio = +fingerprintOptFlags DynFlags{..} = let -- See https://gitlab.haskell.org/ghc/ghc/issues/10923 -- We used to fingerprint the optimisation level, but as Joachim @@ -92,22 +88,21 @@ fingerprintOptFlags DynFlags{..} nameio = opt_flags = map fromEnum $ filter (`EnumSet.member` optimisationFlags) (EnumSet.toList generalFlags) - in computeFingerprint nameio opt_flags + in computeFingerprint opt_flags -- Fingerprint the HPC info. We keep this separate from the rest of -- the flags because GHCi users (especially) may wish to use an object -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintHpcFlags dflags at DynFlags{..} nameio = +fingerprintHpcFlags dflags at DynFlags{..} = let -- -fhpc, see https://gitlab.haskell.org/ghc/ghc/issues/11798 -- hpcDir is output-only, so we should recompile if it changes hpc = if gopt Opt_Hpc dflags then Just hpcDir else Nothing - in computeFingerprint nameio hpc + in computeFingerprint hpc {- Note [path flags and recompilation] ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter Proxy bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh name data IfaceDecl @@ -585,7 +586,7 @@ ifaceDeclFingerprints hash decl where computeFingerprint' = unsafeDupablePerformIO - . computeFingerprint (panic "ifaceDeclFingerprints") + . computeFingerprint fromIfaceWarnings :: IfaceWarnings -> Warnings GhcRn fromIfaceWarnings = \case @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,8 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,13 +69,43 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + SomeReaderTable(..), + ReaderTable(..), + SomeWriterTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, +<<<<<<< HEAD + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, +||||||| parent of f3fd018a62 (Fixup: Generic Symbol Table) + +======= + + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + +>>>>>>> f3fd018a62 (Fixup: Generic Symbol Table) -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -93,6 +126,7 @@ import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +138,14 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time +import Data.Tuple (swap) import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +156,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +189,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh + +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +284,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,42 +308,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -279,20 +367,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -313,7 +404,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -329,7 +420,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -350,8 +441,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -372,39 +463,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -412,7 +501,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -425,7 +514,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -437,7 +526,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -458,10 +547,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -484,15 +573,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -509,15 +598,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -533,15 +622,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -561,15 +650,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -980,63 +1069,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1044,14 +1133,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1062,7 +1151,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1081,73 +1172,254 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) - -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader + } + +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter put_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data SomeReaderTable f = forall a . Typeable a => + SomeReaderTable (f (ReaderTable a)) + +data SomeWriterTable f = forall a . Typeable a => + SomeWriterTable (f (WriterTable, BinaryWriter a)) + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol + } + +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (BinHandle -> a -> IO ()) -> BinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: BinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (BinHandle -> IO a) -> BinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> BinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> BinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count + + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1156,34 +1428,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1212,43 +1462,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1260,12 +1509,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/462541610e53b4fa54b6c67a361e730fedab62d9...aa3ccba8f9c84e141377908e96dd832c173d2267 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/462541610e53b4fa54b6c67a361e730fedab62d9...aa3ccba8f9c84e141377908e96dd832c173d2267 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:00:22 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 07:00:22 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660be546ee39f_26e1f6864b106609@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 38971885 by Rodrigo Mesquita at 2024-04-02T10:12:11+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - fa4973f4 by Rodrigo Mesquita at 2024-04-02T11:59:56+01:00 fixup! fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 4 changed files: - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,18 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r = addDLL_PEi386(path, NULL); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1883,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,3 +1,5 @@ +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + #include "CheckUnload.h" #include "ForeignExports.h" #include "LinkerInternals.h" @@ -208,4 +210,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ba67d90e6af52e2a564cac74c902828f8fc05a9...fa4973f496050e7ade469f09205c4629d8894a80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ba67d90e6af52e2a564cac74c902828f8fc05a9...fa4973f496050e7ade469f09205c4629d8894a80 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:14:14 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:14:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ghci-mi-extra-decls Message-ID: <660be8864aefe_26e1f6ab38e472664@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ghci-mi-extra-decls at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ghci-mi-extra-decls You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:41:38 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:41:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/os-string-modlocation Message-ID: <660beef264f5c_26e1f6d9b4d08058@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/os-string-modlocation You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:49:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:49:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660bf0b6b9f93_26e1f6f0224c84318@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: cc35cf02 by Fendor at 2024-04-02T13:48:50+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 17 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,19 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , unsafeDecodeUtf + , unsafeEncodeUtf + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import System.OsPath +import Data.Either + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -300,7 +300,7 @@ mkIface_ hsc_env trust_info = setSafeMode safe_mode annotations = map mkIfaceAnnotation anns icomplete_matches = map mkIfaceCompleteMatch complete_matches - !rdrs = maybeGlobalRdrEnv rdr_env + _ = maybeGlobalRdrEnv rdr_env ModIface { mi_module = this_mod, @@ -323,7 +323,7 @@ mkIface_ hsc_env mi_fixities = fixities, mi_warns = warns, mi_anns = annotations, - mi_globals = rdrs, + mi_globals = Nothing, mi_used_th = used_th, mi_decls = decls, mi_extra_decls = extra_decls, ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsPath -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,9 +455,9 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. @@ -488,14 +490,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +505,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +514,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +545,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +583,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> OsPath -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +602,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +675,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +728,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,7 @@ where import GHC.Prelude import GHC.Unit +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -16,6 +17,7 @@ import GHC.Platform.Ways import Data.IORef import GHC.Data.FastString import qualified Data.Set as Set +import System.OsPath (OsPath) -- | The 'FinderCache' maps modules to the result of -- searching for that module. It records the results of searching for @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsPath + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsPath + , finder_dynHiSuf :: OsPath + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsPath + , finder_dynObjectSuf :: OsPath + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,12 +7,21 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude import GHC.Unit.Types import GHC.Utils.Outputable +import qualified GHC.Data.Strict as Strict +import System.OsPath +import GHC.Data.OsPath -- | Module Location -- @@ -39,30 +48,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +80,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +91,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +104,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ + +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc35cf024fa11cdab803de7c9290069dbf831d29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc35cf024fa11cdab803de7c9290069dbf831d29 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:51:41 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:51:41 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660bf14de6ec8_26e1f6100970885149@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 1f19ba2b by Fendor at 2024-04-02T13:51:23+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,19 +111,19 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next symtab_map' <- readIORef symtab_map putSymbolTable bh symtab_next' symtab_map' - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + -- write the tellBinWriter pointer at the front of the file + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -87,7 +89,23 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - +<<<<<<< HEAD + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, +||||||| parent of f3fd018a62 (Fixup: Generic Symbol Table) + +======= + + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + +>>>>>>> f3fd018a62 (Fixup: Generic Symbol Table) -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +189,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +284,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +308,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +367,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +404,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +420,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +441,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +463,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +501,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +514,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +526,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +547,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +573,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +598,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +622,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +650,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1069,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1133,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1230,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1271,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1280,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,14 +1301,80 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol } +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (BinHandle -> a -> IO ()) -> BinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: BinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (BinHandle -> IO a) -> BinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> BinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> BinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- @@ -1299,14 +1412,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1428,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1470,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f19ba2ba0f4bcc25eceffd3531b949eedb000a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f19ba2ba0f4bcc25eceffd3531b949eedb000a0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:52:07 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:52:07 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660bf16719ccd_26e1f61086c6c859a3@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 487e6f44 by Fendor at 2024-04-02T13:51:37+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,19 +111,19 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next symtab_map' <- readIORef symtab_map putSymbolTable bh symtab_next' symtab_map' - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + -- write the tellBinWriter pointer at the front of the file + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -87,7 +89,23 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - +<<<<<<< HEAD + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, +||||||| parent of f3fd018a62 (Fixup: Generic Symbol Table) + +======= + + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + +>>>>>>> f3fd018a62 (Fixup: Generic Symbol Table) -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +189,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +284,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +308,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +367,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +404,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +420,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +441,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +463,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +501,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +514,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +526,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +547,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +573,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +598,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +622,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +650,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1069,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1133,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1230,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1271,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1280,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,14 +1301,80 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol } +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (BinHandle -> a -> IO ()) -> BinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: BinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (BinHandle -> IO a) -> BinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> BinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> BinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- @@ -1299,14 +1412,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1428,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1470,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/487e6f44be930b4536481c202b5af1d11a8ff185 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/487e6f44be930b4536481c202b5af1d11a8ff185 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:57:18 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:57:18 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660bf29df2da7_26e1f611b5278871f0@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 2c19bd36 by Fendor at 2024-04-02T13:56:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,9 +111,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +121,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -87,7 +89,23 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - +<<<<<<< HEAD + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, +||||||| parent of f3fd018a62 (Fixup: Generic Symbol Table) + +======= + + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + +>>>>>>> f3fd018a62 (Fixup: Generic Symbol Table) -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +189,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +284,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +308,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +367,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +404,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +420,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +441,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +463,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +501,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +514,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +526,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +547,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +573,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +598,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +622,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +650,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1069,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1133,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1230,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1271,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1280,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,14 +1301,80 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol } +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (BinHandle -> a -> IO ()) -> BinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: BinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (BinHandle -> IO a) -> BinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> BinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> BinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- @@ -1299,14 +1412,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1428,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1470,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c19bd36e0124194f641ef74a11aee0736125fa7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c19bd36e0124194f641ef74a11aee0736125fa7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 11:59:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 07:59:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660bf30e1b84d_26e1f6129646c8839a@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: e67e4a42 by Fendor at 2024-04-02T13:58:52+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 17 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,19 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , unsafeDecodeUtf + , unsafeEncodeUtf + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import System.OsPath +import Data.Either + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -300,7 +300,7 @@ mkIface_ hsc_env trust_info = setSafeMode safe_mode annotations = map mkIfaceAnnotation anns icomplete_matches = map mkIfaceCompleteMatch complete_matches - !rdrs = maybeGlobalRdrEnv rdr_env + _ = maybeGlobalRdrEnv rdr_env ModIface { mi_module = this_mod, @@ -323,7 +323,7 @@ mkIface_ hsc_env mi_fixities = fixities, mi_warns = warns, mi_anns = annotations, - mi_globals = rdrs, + mi_globals = Nothing, mi_used_th = used_th, mi_decls = decls, mi_extra_decls = extra_decls, ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsPath -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,9 +455,9 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. @@ -488,14 +490,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +505,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +514,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +545,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +583,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> OsPath -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +602,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +675,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +728,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,7 @@ where import GHC.Prelude import GHC.Unit +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -16,6 +17,7 @@ import GHC.Platform.Ways import Data.IORef import GHC.Data.FastString import qualified Data.Set as Set +import System.OsPath (OsPath) -- | The 'FinderCache' maps modules to the result of -- searching for that module. It records the results of searching for @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsPath + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsPath + , finder_dynHiSuf :: OsPath + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsPath + , finder_dynObjectSuf :: OsPath + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,12 +7,21 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude import GHC.Unit.Types import GHC.Utils.Outputable +import qualified GHC.Data.Strict as Strict +import System.OsPath +import GHC.Data.OsPath -- | Module Location -- @@ -39,30 +48,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +80,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +91,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +104,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ + +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e67e4a42d53d3b37d1bfbed895b070c0bf95bbc8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e67e4a42d53d3b37d1bfbed895b070c0bf95bbc8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:16:54 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 08:16:54 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660bf73643d7_26e1f61616cb8961bd@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 5f1f6372 by Rodrigo Mesquita at 2024-04-02T13:12:43+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 1 changed file: - rts/linker/LoadNativeObjPosix.c Changes: ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,9 +1,10 @@ +#include "LinkerInternals.h" +#include "Rts.h" + #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) #include "CheckUnload.h" #include "ForeignExports.h" -#include "LinkerInternals.h" -#include "Rts.h" #include "RtsUtils.h" #include "Profiling.h" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f1f637262e27584c309420e6dffb7524fba3901 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f1f637262e27584c309420e6dffb7524fba3901 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:17:56 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 08:17:56 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660bf774b1503_26e1f616adfa09645b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: df697526 by Fendor at 2024-04-02T14:17:36+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,9 +111,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +121,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -87,7 +89,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +172,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +267,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +291,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +350,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +387,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +403,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +424,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +446,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +484,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +497,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +509,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +530,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +556,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +581,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +605,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +633,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1052,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1116,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1213,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1254,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1263,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,12 +1284,12 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int } --------------------------------------------------------- @@ -1299,14 +1329,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1345,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1387,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df697526f836456e06b1c965119edb4be238875d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df697526f836456e06b1c965119edb4be238875d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:20:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 08:20:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact-with-gen-sym-table] 2 commits: Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660bf7fa9010d_26e1f617d23cc9721c@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact-with-gen-sym-table at Glasgow Haskell Compiler / GHC Commits: 47374615 by Fendor at 2024-04-02T14:18:32+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - fc469160 by Fendor at 2024-04-02T14:19:50+02:00 Fixup: Generic Symbol Table - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -194,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -211,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -235,7 +235,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -380,7 +380,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -389,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -410,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -434,7 +434,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -460,7 +460,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -111,19 +111,19 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next symtab_map' <- readIORef symtab_map putSymbolTable bh symtab_next' symtab_map' - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + -- write the tellBinWriter pointer at the front of the file + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,7 +213,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -232,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -260,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -276,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -334,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -345,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -37,7 +37,7 @@ computeFingerprint a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -90,10 +90,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Data.Proxy +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -88,6 +90,12 @@ module GHC.Utils.Binary putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic Symbol that can be used for user-defined deduplication tables. + GenericSymbolTable(..), + initGenericSymbolTable, + putGenericSymbolTable, getGenericSymbolTable, + putGenericSymTab, getGenericSymtab, + -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -171,70 +179,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -253,23 +274,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -277,42 +298,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -321,20 +357,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -355,7 +394,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -371,7 +410,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -392,8 +431,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -414,39 +453,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -454,7 +491,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -467,7 +504,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -479,7 +516,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -500,10 +537,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -526,15 +563,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -551,15 +588,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -575,15 +612,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -603,15 +640,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1022,63 +1059,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1086,14 +1123,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1183,31 +1220,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) @@ -1224,8 +1261,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1233,9 +1270,9 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_binding_name put_fs = mkWriterUserData @@ -1254,14 +1291,80 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol } +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + table_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putGenericSymbolTable bh table_count symtab_map + pure table_count + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: WriteBinHandle -> Int -> Map.Map a Int -> IO () + putGenericSymbolTable bh name_count symtab = do + put_ bh name_count + let genElements = elems (array (0,name_count-1) (fmap swap $ Map.toList symtab)) + mapM_ (\n -> serialiser bh n) genElements + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- get bh :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a + -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- @@ -1299,14 +1402,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1315,12 +1418,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1357,34 +1460,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d559cde5afeb9323861428a7317a59be055b9e13 +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/345e81f47d9f811c124207ce51cf8f95bdb01b1e...fc469160c47daf12cdee33019df1e16bfc470375 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/345e81f47d9f811c124207ce51cf8f95bdb01b1e...fc469160c47daf12cdee33019df1e16bfc470375 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:28:18 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 08:28:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/fix-thunks-name-and-ui Message-ID: <660bf9e261b70_26e1f6190f94c994cd@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/fix-thunks-name-and-ui at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/fix-thunks-name-and-ui You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:29:28 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 08:29:28 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! fixup! fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660bfa28e1d0c_26e1f6195c864996cd@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: b86dfbc9 by Rodrigo Mesquita at 2024-04-02T13:29:13+01:00 fixup! fixup! fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 1 changed file: - rts/linker/PEi386.h Changes: ===================================== rts/linker/PEi386.h ===================================== @@ -60,7 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); -SymbolAddr *lookupSymbolInDLL_PEi386 (SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +SymbolAddr *lookupSymbolInDLL_PEi386 (SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b86dfbc9bf32f2e2de08dc9242b478c5f7edf1a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b86dfbc9bf32f2e2de08dc9242b478c5f7edf1a4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:34:55 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 08:34:55 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660bfb6f6566d_26e1f61b21cbc103788@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 4704c5ef by Rodrigo Mesquita at 2024-04-02T13:34:44+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 4 changed files: - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,18 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r = addDLL_PEi386(path, NULL); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1883,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4704c5ef2f416ff36d91c9b3387f3cdf94441ecd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4704c5ef2f416ff36d91c9b3387f3cdf94441ecd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:36:24 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 08:36:24 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] fixup! clarify Note [Preproccesing invocations] Message-ID: <660bfbc8d7bfc_26e1f61c60ee810409a@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 466682d0 by Fendor at 2024-04-02T14:36:09+02:00 fixup! clarify Note [Preproccesing invocations] - - - - - 1 changed file: - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -126,7 +126,6 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.Tuple (swap) import Data.List (unfoldr) import Data.Typeable import System.IO as IO View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/466682d09a3a0ecd1862807b5194e7de3ba01640 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/466682d09a3a0ecd1862807b5194e7de3ba01640 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:37:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 08:37:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <660bfbf67a01a_26e1f61cc63b010481@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 957df705 by Fendor at 2024-04-02T14:36:35+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. - - - - - d3b37648 by Fendor at 2024-04-02T14:36:35+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -54,6 +53,7 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import Data.Functor.Identity -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,32 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) - - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) - - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) - - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) - --- | Write an interface file + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + tables :: [SomeReaderTable IO] + tables = + [ SomeReaderTable initFastStringReaderTable + , SomeReaderTable (initReadNameCachedBinary name_cache) + ] + + tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables + + final_bh <- foldM (\bh (SomeReaderTable (tbl' :: Identity (ReaderTable a))) -> do + let tbl = runIdentity tbl' + res <- Binary.forwardGet bh (getTable tbl bh) + let newDecoder = mkReaderFromTable tbl res + pure $ addReaderToUserData (mkSomeBinaryReader newDecoder) bh + ) bh tables + + pure final_bh + +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +194,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +211,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +235,39 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + writerTables = + [ SomeWriterTable initFastStringWriterTable + , SomeWriterTable initWriteNameTable + ] + + tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + + let writerUserData = + mkWriterUserData $ + map + (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) + tables + + let bh = setWriterUserData bh' writerUserData + (fs_count : name_count : _, r) <- + putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +279,108 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be duplicated 'FastString's and 'Name's. +To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ │ +│ ModIface │ +│ Payload │ +│ │ +├──────────────┤ +│ Ptr FS ├───────────┐ +├──────────────┤ │ +│ Ptr Name ├────────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄───────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄──────────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) +initReadNameCachedBinary cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +389,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +410,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +434,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +459,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +478,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,15 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +121,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +213,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +232,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +260,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +276,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +334,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +345,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -520,7 +520,7 @@ checkFlagHash :: HscEnv -> ModIface -> IO RecompileRequired checkFlagHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_flag_hash (mi_final_exts iface) - new_hash <- fingerprintDynFlags hsc_env (mi_module iface) putNameLiterally + new_hash <- fingerprintDynFlags hsc_env (mi_module iface) case old_hash == new_hash of True -> up_to_date logger (text "Module flags unchanged") False -> out_of_date_hash logger FlagsChanged @@ -533,7 +533,6 @@ checkOptimHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_opt_hash (mi_final_exts iface) new_hash <- fingerprintOptFlags (hsc_dflags hsc_env) - putNameLiterally if | old_hash == new_hash -> up_to_date logger (text "Optimisation flags unchanged") | gopt Opt_IgnoreOptimChanges (hsc_dflags hsc_env) @@ -549,7 +548,6 @@ checkHpcHash hsc_env iface = do let logger = hsc_logger hsc_env let old_hash = mi_hpc_hash (mi_final_exts iface) new_hash <- fingerprintHpcFlags (hsc_dflags hsc_env) - putNameLiterally if | old_hash == new_hash -> up_to_date logger (text "HPC flags unchanged") | gopt Opt_IgnoreHpcChanges (hsc_dflags hsc_env) @@ -960,7 +958,6 @@ addFingerprints -> IO ModIface addFingerprints hsc_env iface0 = do - eps <- hscEPS hsc_env let decls = mi_decls iface0 decl_warn_fn = mkIfaceDeclWarnCache (fromIfaceWarnings $ mi_warns iface0) @@ -1023,40 +1020,6 @@ addFingerprints hsc_env iface0 groups :: [SCC IfaceDeclABI] groups = stronglyConnCompFromEdgedVerticesOrd edges - global_hash_fn = mkHashFun hsc_env eps - - -- How to output Names when generating the data to fingerprint. - -- Here we want to output the fingerprint for each top-level - -- Name, whether it comes from the current module or another - -- module. In this way, the fingerprint for a declaration will - -- change if the fingerprint for anything it refers to (transitively) - -- changes. - mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () - mk_put_name local_env bh name - | isWiredInName name = putNameLiterally bh name - -- wired-in names don't have fingerprints - | otherwise - = assertPpr (isExternalName name) (ppr name) $ - let hash | nameModule name /= semantic_mod = global_hash_fn name - -- Get it from the REAL interface!! - -- This will trigger when we compile an hsig file - -- and we know a backing impl for it. - -- See Note [Identity versus semantic module] - | semantic_mod /= this_mod - , not (isHoleModule semantic_mod) = global_hash_fn name - | otherwise = return (snd (lookupOccEnv local_env (getOccName name) - `orElse` pprPanic "urk! lookup local fingerprint" - (ppr name $$ ppr local_env))) - -- This panic indicates that we got the dependency - -- analysis wrong, because we needed a fingerprint for - -- an entity that wasn't in the environment. To debug - -- it, turn the panic into a trace, uncomment the - -- pprTraces below, run the compile again, and inspect - -- the output and the generated .hi file with - -- --show-iface. - in hash >>= put_ bh - -- take a strongly-connected group of declarations and compute -- its fingerprint. @@ -1067,23 +1030,18 @@ addFingerprints hsc_env iface0 [(Fingerprint,IfaceDecl)]) fingerprint_group (local_env, decls_w_hashes) (AcyclicSCC abi) - = do let hash_fn = mk_put_name local_env - decl = abiDecl abi + = do let decl = abiDecl abi --pprTrace "fingerprinting" (ppr (ifName decl) ) $ do - hash <- computeFingerprint hash_fn abi + hash <- computeFingerprint abi env' <- extend_hash_env local_env (hash,decl) return (env', (hash,decl) : decls_w_hashes) fingerprint_group (local_env, decls_w_hashes) (CyclicSCC abis) = do let stable_abis = sortBy cmp_abiNames abis stable_decls = map abiDecl stable_abis - local_env1 <- foldM extend_hash_env local_env - (zip (map mkRecFingerprint [0..]) stable_decls) - -- See Note [Fingerprinting recursive groups] - let hash_fn = mk_put_name local_env1 -- pprTrace "fingerprinting" (ppr (map ifName decls) ) $ do -- put the cycle in a canonical order - hash <- computeFingerprint hash_fn stable_abis + hash <- computeFingerprint stable_abis let pairs = zip (map (bumpFingerprint hash) [0..]) stable_decls -- See Note [Fingerprinting recursive groups] local_env2 <- foldM extend_hash_env local_env pairs @@ -1156,11 +1114,10 @@ addFingerprints hsc_env iface0 -- instances yourself, no need to consult hs-boot; if you do load the -- interface into EPS, you will see a duplicate orphan instance. - orphan_hash <- computeFingerprint (mk_put_name local_env) - (map ifDFun orph_insts, orph_rules, orph_fis) + orphan_hash <- computeFingerprint (map ifDFun orph_insts, orph_rules, orph_fis) -- Hash of the transitive things in dependencies - dep_hash <- computeFingerprint putNameLiterally + dep_hash <- computeFingerprint (dep_sig_mods (mi_deps iface0), dep_boot_mods (mi_deps iface0), -- Trusted packages are like orphans @@ -1170,7 +1127,7 @@ addFingerprints hsc_env iface0 -- the export list hash doesn't depend on the fingerprints of -- the Names it mentions, only the Names themselves, hence putNameLiterally. - export_hash <- computeFingerprint putNameLiterally + export_hash <- computeFingerprint (mi_exports iface0, orphan_hash, dep_hash, @@ -1229,11 +1186,11 @@ addFingerprints hsc_env iface0 -- - (some of) dflags -- it returns two hashes, one that shouldn't change -- the abi hash and one that should - flag_hash <- fingerprintDynFlags hsc_env this_mod putNameLiterally + flag_hash <- fingerprintDynFlags hsc_env this_mod - opt_hash <- fingerprintOptFlags dflags putNameLiterally + opt_hash <- fingerprintOptFlags dflags - hpc_hash <- fingerprintHpcFlags dflags putNameLiterally + hpc_hash <- fingerprintHpcFlags dflags plugin_hash <- fingerprintPlugins (hsc_plugins hsc_env) @@ -1243,7 +1200,7 @@ addFingerprints hsc_env iface0 -- - orphans -- - deprecations -- - flag abi hash - mod_hash <- computeFingerprint putNameLiterally + mod_hash <- computeFingerprint (map fst sorted_decls, export_hash, -- includes orphan_hash mi_warns iface0) @@ -1255,7 +1212,7 @@ addFingerprints hsc_env iface0 -- - usages -- - deps (home and external packages, dependent files) -- - hpc - iface_hash <- computeFingerprint putNameLiterally + iface_hash <- computeFingerprint (mod_hash, mi_src_hash iface0, ann_fn (mkVarOccFS (fsLit "module")), -- See mkIfaceAnnCache @@ -1594,57 +1551,6 @@ mkOrphMap get_key decls = (extendOccEnv_Acc (:) Utils.singleton non_orphs occ d, orphs) | otherwise = (non_orphs, d:orphs) --- ----------------------------------------------------------------------------- --- Look up parents and versions of Names - --- This is like a global version of the mi_hash_fn field in each ModIface. --- Given a Name, it finds the ModIface, and then uses mi_hash_fn to get --- the parent and version info. - -mkHashFun - :: HscEnv -- needed to look up versions - -> ExternalPackageState -- ditto - -> (Name -> IO Fingerprint) -mkHashFun hsc_env eps name - | isHoleModule orig_mod - = lookup (mkHomeModule home_unit (moduleName orig_mod)) - | otherwise - = lookup orig_mod - where - home_unit = hsc_home_unit hsc_env - dflags = hsc_dflags hsc_env - hpt = hsc_HUG hsc_env - pit = eps_PIT eps - ctx = initSDocContext dflags defaultUserStyle - occ = nameOccName name - orig_mod = nameModule name - lookup mod = do - massertPpr (isExternalName name) (ppr name) - iface <- case lookupIfaceByModule hpt pit mod of - Just iface -> return iface - Nothing -> - -- This can occur when we're writing out ifaces for - -- requirements; we didn't do any /real/ typechecking - -- so there's no guarantee everything is loaded. - -- Kind of a heinous hack. - initIfaceLoad hsc_env . withIfaceErr ctx - $ withoutDynamicNow - -- If you try and load interfaces when dynamic-too - -- enabled then it attempts to load the dyn_hi and hi - -- interface files. Backpack doesn't really care about - -- dynamic object files as it isn't doing any code - -- generation so -dynamic-too is turned off. - -- Some tests fail without doing this (such as T16219), - -- but they fail because dyn_hi files are not found for - -- one of the dependencies (because they are deliberately turned off) - -- Why is this check turned off here? That is unclear but - -- just one of the many horrible hacks in the backpack - -- implementation. - $ loadInterface (text "lookupVers2") mod ImportBySystem - return $ snd (mi_hash_fn (mi_final_exts iface) occ `orElse` - pprPanic "lookupVers1" (ppr mod <+> ppr occ)) - - -- | Creates cached lookup for the 'mi_anns' field of ModIface -- Hackily, we use "module" as the OccName for any module-level annotations mkIfaceAnnCache :: [IfaceAnnotation] -> OccName -> [AnnPayload] ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,20 +26,18 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) - -> a + => a -> IO Fingerprint -computeFingerprint put_nonbinding_name a = do +computeFingerprint a = do bh <- fmap set_user_data $ openBinMem (3*1024) -- just less than a block put_ bh a fingerprintBinMem bh where - set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ newWriteState putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -13,9 +13,7 @@ import GHC.Prelude import GHC.Driver.Session import GHC.Driver.Env -import GHC.Utils.Binary import GHC.Unit.Module -import GHC.Types.Name import GHC.Types.SafeHaskell import GHC.Utils.Fingerprint import GHC.Iface.Recomp.Binary @@ -31,10 +29,9 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintDynFlags hsc_env this_mod nameio = +fingerprintDynFlags hsc_env this_mod = let dflags at DynFlags{..} = hsc_dflags hsc_env mainis = if mainModIs (hsc_HUE hsc_env) == this_mod then Just mainFunIs else Nothing -- see #5878 @@ -73,7 +70,7 @@ fingerprintDynFlags hsc_env this_mod nameio = flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, codegen, debugLevel, callerCcFilters)) in -- pprTrace "flags" (ppr flags) $ - computeFingerprint nameio flags + computeFingerprint flags -- Fingerprint the optimisation info. We keep this separate from the rest of -- the flags because GHCi users (especially) may wish to ignore changes in @@ -81,9 +78,8 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintOptFlags DynFlags{..} nameio = +fingerprintOptFlags DynFlags{..} = let -- See https://gitlab.haskell.org/ghc/ghc/issues/10923 -- We used to fingerprint the optimisation level, but as Joachim @@ -92,22 +88,21 @@ fingerprintOptFlags DynFlags{..} nameio = opt_flags = map fromEnum $ filter (`EnumSet.member` optimisationFlags) (EnumSet.toList generalFlags) - in computeFingerprint nameio opt_flags + in computeFingerprint opt_flags -- Fingerprint the HPC info. We keep this separate from the rest of -- the flags because GHCi users (especially) may wish to use an object -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintHpcFlags dflags at DynFlags{..} nameio = +fingerprintHpcFlags dflags at DynFlags{..} = let -- -fhpc, see https://gitlab.haskell.org/ghc/ghc/issues/11798 -- hpcDir is output-only, so we should recompile if it changes hpc = if gopt Opt_Hpc dflags then Just hpcDir else Nothing - in computeFingerprint nameio hpc + in computeFingerprint hpc {- Note [path flags and recompilation] ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter Proxy bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh name data IfaceDecl @@ -585,7 +586,7 @@ ifaceDeclFingerprints hash decl where computeFingerprint' = unsafeDupablePerformIO - . computeFingerprint (panic "ifaceDeclFingerprints") + . computeFingerprint fromIfaceWarnings :: IfaceWarnings -> Warnings GhcRn fromIfaceWarnings = \case @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,8 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,13 +69,26 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + SomeReaderTable(..), + ReaderTable(..), + SomeWriterTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..) ) where @@ -93,6 +109,7 @@ import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +121,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +138,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +171,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +266,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,42 +290,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -279,20 +349,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -313,7 +386,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -329,7 +402,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -350,8 +423,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -372,39 +445,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -412,7 +483,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -425,7 +496,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -437,7 +508,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -458,10 +529,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -484,15 +555,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -509,15 +580,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -533,15 +604,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -561,15 +632,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -980,63 +1051,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1044,14 +1115,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1062,7 +1133,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1081,73 +1154,188 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) - -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader + } + +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for key " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for key " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter put_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data SomeReaderTable f = forall a . Typeable a => + SomeReaderTable (f (ReaderTable a)) + +data SomeWriterTable f = forall a . Typeable a => + SomeWriterTable (f (WriterTable, BinaryWriter a)) + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count + + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1156,34 +1344,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1212,43 +1378,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1260,12 +1425,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 799390d1c6d59a606c3dd00dea057baa26ed0c2f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/466682d09a3a0ecd1862807b5194e7de3ba01640...d3b37648179355fde9e450a55a56e09bc3a12944 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/466682d09a3a0ecd1862807b5194e7de3ba01640...d3b37648179355fde9e450a55a56e09bc3a12944 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 12:51:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 08:51:14 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: clarify Note [Preproccesing invocations] Message-ID: <660bff42ec17_26e1f61ffea0011539@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - 136bd621 by Ben Gamari at 2024-04-02T08:50:27-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - 9aa67c85 by Cheng Shao at 2024-04-02T08:50:27-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - 50ee0828 by Cheng Shao at 2024-04-02T08:50:27-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 4fe0222f by Cheng Shao at 2024-04-02T08:50:27-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 42b70f1f by Cheng Shao at 2024-04-02T08:50:27-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - c1c37c47 by Andrei Borzenkov at 2024-04-02T08:50:28-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 20 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/Language/Haskell/Syntax/Type.hs - rts/TSANUtils.c - rts/include/Cmm.h - rts/include/rts/TSANUtils.h - rts/include/stg/SMP.h - rts/rts.cabal - testsuite/tests/partial-sigs/should_run/GHCiWildcardKind.stdout - + testsuite/tests/th/T24299.hs - + testsuite/tests/th/T24299.stderr - testsuite/tests/th/all.T Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -339,7 +339,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f flavour_string Llvm = "llvm" flavour_string Dwarf = "debug_info" flavour_string FullyStatic = "fully_static" - flavour_string ThreadSanitiser = "thread_sanitizer" + flavour_string ThreadSanitiser = "thread_sanitizer_cmm" flavour_string NoSplitSections = "no_split_sections" flavour_string BootNonmovingGc = "boot_nonmoving_gc" @@ -969,9 +969,9 @@ job_groups = , validateBuilds Amd64 (Linux Debian10) nativeInt , validateBuilds Amd64 (Linux Debian10) unreg , fastCI (validateBuilds Amd64 (Linux Debian10) debug) - , -- Nightly allowed to fail: #22520 + , -- More work is needed to address TSAN failures: #22520 modifyNightlyJobs allowFailure - (modifyValidateJobs manual tsan_jobs) + (modifyValidateJobs (allowFailure . manual) tsan_jobs) , -- Nightly allowed to fail: #22343 modifyNightlyJobs allowFailure (modifyValidateJobs manual (validateBuilds Amd64 (Linux Debian10) noTntc)) @@ -1039,7 +1039,7 @@ job_groups = -- Haddock is large enough to make TSAN choke without massive quantities of -- memory. . addVariable "HADRIAN_ARGS" "--docs=none") $ - validateBuilds Amd64 (Linux Debian10) tsan + validateBuilds Amd64 (Linux Debian12) tsan make_wasm_jobs cfg = modifyJobs @@ -1083,6 +1083,7 @@ platform_mapping = Map.map go combined_result , "nightly-x86_64-linux-deb11-validate" , "nightly-x86_64-linux-deb12-validate" , "x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static" + , "x86_64-linux-deb12-validate+thread_sanitizer_cmm" , "nightly-aarch64-linux-deb10-validate" , "nightly-x86_64-linux-alpine3_12-validate" , "nightly-x86_64-linux-deb10-validate" ===================================== .gitlab/jobs.yaml ===================================== @@ -1644,18 +1644,18 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb10-validate+thread_sanitizer": { + "nightly-x86_64-linux-deb10-zstd-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": true, + "allow_failure": false, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb10-validate+thread_sanitizer.tar.xz", + "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1698,17 +1698,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+thread_sanitizer", - "BUILD_FLAVOUR": "validate+thread_sanitizer", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "HADRIAN_ARGS": "--docs=none", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-validate+thread_sanitizer", - "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions", + "TEST_ENV": "x86_64-linux-deb10-zstd-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb10-zstd-validate": { + "nightly-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1719,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", + "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1729,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb10-$CACHE_REV", + "key": "x86_64-linux-deb11-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1762,15 +1760,17 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", + "CROSS_TARGET": "aarch64-linux-gnu", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-zstd-validate", + "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { + "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1781,7 +1781,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1823,18 +1823,19 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", - "CROSS_TARGET": "aarch64-linux-gnu", + "CONFIGURE_WRAPPER": "emconfigure", + "CROSS_EMULATOR": "js-emulator", + "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1845,7 +1846,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1887,19 +1888,16 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CONFIGURE_WRAPPER": "emconfigure", - "CROSS_EMULATOR": "js-emulator", - "CROSS_TARGET": "javascript-unknown-ghcjs", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-validate": { + "nightly-x86_64-linux-deb11-validate+boot_nonmoving_gc": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1910,7 +1908,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1953,15 +1951,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate", - "BUILD_FLAVOUR": "validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", + "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-validate", + "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", + "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-validate+boot_nonmoving_gc": { + "nightly-x86_64-linux-deb12-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1972,7 +1970,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", + "ghc-x86_64-linux-deb12-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1982,14 +1980,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb12-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -2015,15 +2013,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", - "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate", + "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", - "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc", + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-deb12-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb12-validate": { + "nightly-x86_64-linux-deb12-validate+llvm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -2034,7 +2032,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate.tar.xz", + "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2077,26 +2075,26 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate", - "BUILD_FLAVOUR": "validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate", + "TEST_ENV": "x86_64-linux-deb12-validate+llvm", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb12-validate+llvm": { + "nightly-x86_64-linux-deb12-validate+thread_sanitizer_cmm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": false, + "allow_failure": true, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", + "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2139,11 +2137,13 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", - "BUILD_FLAVOUR": "validate+llvm", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "BUILD_FLAVOUR": "validate+thread_sanitizer_cmm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate+llvm", + "TEST_ENV": "x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions", "XZ_OPT": "-9" } }, @@ -5090,7 +5090,7 @@ "TEST_ENV": "x86_64-linux-deb10-validate+debug_info" } }, - "x86_64-linux-deb10-validate+thread_sanitizer": { + "x86_64-linux-deb10-zstd-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5101,7 +5101,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb10-validate+thread_sanitizer.tar.xz", + "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5127,9 +5127,8 @@ ], "rules": [ { - "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "manual" + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" } ], "script": [ @@ -5145,16 +5144,14 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+thread_sanitizer", - "BUILD_FLAVOUR": "validate+thread_sanitizer", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "HADRIAN_ARGS": "--docs=none", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-validate+thread_sanitizer", - "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions" + "TEST_ENV": "x86_64-linux-deb10-zstd-validate" } }, - "x86_64-linux-deb10-zstd-validate": { + "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5165,7 +5162,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", + "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5175,14 +5172,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb10-$CACHE_REV", + "key": "x86_64-linux-deb11-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5191,7 +5188,7 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5208,14 +5205,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", + "CROSS_TARGET": "aarch64-linux-gnu", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-zstd-validate" + "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { + "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5226,7 +5225,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5252,7 +5251,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*javascript.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5268,17 +5267,18 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", - "CROSS_TARGET": "aarch64-linux-gnu", + "CONFIGURE_WRAPPER": "emconfigure", + "CROSS_EMULATOR": "js-emulator", + "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" + "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-validate+boot_nonmoving_gc": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5289,7 +5289,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5315,7 +5315,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*javascript.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*non-moving GC.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5331,18 +5331,15 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", - "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CONFIGURE_WRAPPER": "emconfigure", - "CROSS_EMULATOR": "js-emulator", - "CROSS_TARGET": "javascript-unknown-ghcjs", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", + "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", + "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc" } }, - "x86_64-linux-deb11-validate+boot_nonmoving_gc": { + "x86_64-linux-deb12-validate+llvm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5353,7 +5350,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", + "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5363,14 +5360,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb12-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5379,7 +5376,7 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*non-moving GC.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5396,25 +5393,25 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", - "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", - "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc" + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-deb12-validate+llvm" } }, - "x86_64-linux-deb12-validate+llvm": { + "x86_64-linux-deb12-validate+thread_sanitizer_cmm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": false, + "allow_failure": true, "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", + "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5440,8 +5437,9 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "on_success" + "allow_failure": true, + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "manual" } ], "script": [ @@ -5457,11 +5455,13 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", - "BUILD_FLAVOUR": "validate+llvm", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "BUILD_FLAVOUR": "validate+thread_sanitizer_cmm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate+llvm" + "TEST_ENV": "x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions" } }, "x86_64-linux-fedora33-release": { ===================================== compiler/GHC/Cmm/ThreadSanitizer.hs ===================================== @@ -184,7 +184,7 @@ saveRestoreCallerRegs us platform = restore = blockFromList restore_nodes -- | Mirrors __tsan_memory_order --- +-- memoryOrderToTsanMemoryOrder :: Env -> MemoryOrdering -> CmmExpr memoryOrderToTsanMemoryOrder env mord = mkIntExpr (platform env) n @@ -294,4 +294,3 @@ tsanAtomicRMW env mord op w addr val dest = AMO_Or -> "fetch_or" AMO_Xor -> "fetch_xor" fn = fsLit $ "__tsan_atomic" ++ show (widthInBits w) ++ "_" ++ op' - ===================================== compiler/GHC/Rename/Splice.hs ===================================== @@ -677,7 +677,7 @@ References: [2] 'rnSpliceExpr' [3] 'GHC.Tc.Gen.Splice.qAddModFinalizer' [4] 'GHC.Tc.Gen.Expr.tcExpr' ('HsSpliceE' ('HsSpliced' ...)) -[5] 'GHC.Tc.Gen.HsType.tc_hs_type' ('HsSpliceTy' ('HsSpliced' ...)) +[5] 'GHC.Tc.Gen.HsType.tcHsType' ('HsSpliceTy' ('HsSpliced' ...)) [6] 'GHC.Tc.Gen.Pat.tc_pat' ('SplicePat' ('HsSpliced' ...)) -} ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -63,7 +63,22 @@ underlying program (the C compiler), the set of flags passed determines the behaviour of the preprocessor, and Cpp and HsCpp behave differently. Specifically, we rely on "traditional" (pre-standard) preprocessing semantics (which most compilers expose via the `-traditional` flag) when preprocessing -Haskell source. This avoids, e.g., the preprocessor removing C-style comments. +Haskell source. This avoids the following situations: + + * Removal of C-style comments, which are not comments in Haskell but valid + operators; + + * Errors due to an ANSI C preprocessor lexing the source and failing on + names with single quotes (TH quotes, ticked promoted constructors, + names with primes in them). + + Both of those cases may be subtle: gcc and clang permit C++-style // + comments in C code, and Data.Array and Data.Vector both export a // + operator whose type is such that a removed "comment" may leave code that + typechecks but does the wrong thing. Another example is that, since ANSI + C permits long character constants, an expression involving multiple + functions with primes in their names may not expand macros properly when + they occur between the primed functions. -} -- | Run either the Haskell preprocessor or the C preprocessor, as per the ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -1678,7 +1678,7 @@ tcRhs (TcPatBind infos pat' mult mult_ann grhss pat_ty) -- is generated so that multiplicity can be inferred. tcMultAnn :: HsMultAnn GhcRn -> TcM Mult tcMultAnn (HsPct1Ann _) = return oneDataConTy -tcMultAnn (HsMultAnn _ p) = tcCheckLHsType p (TheKind multiplicityTy) +tcMultAnn (HsMultAnn _ p) = tcCheckLHsTypeInContext p (TheKind multiplicityTy) tcMultAnn (HsNoMultAnn _) = newFlexiTyVarTy multiplicityTy tcExtendTyVarEnvForRhs :: Maybe TcIdSigInst -> TcM a -> TcM a ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsType, + tcCheckLHsTypeInContext, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -397,7 +397,7 @@ kcClassSigType names sig_ty@(L _ (HsSig { sig_bndrs = hs_outer_bndrs, sig_body = hs_ty })) = addSigCtxt (funsSigCtxt names) sig_ty $ do { _ <- bindOuterSigTKBndrs_Tv hs_outer_bndrs $ - tcLHsType hs_ty liftedTypeKind + tcCheckLHsType hs_ty liftedTypeKind ; return () } tcClassSigType :: [LocatedN Name] -> LHsSigType GhcRn -> TcM Type @@ -467,7 +467,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs do { exp_kind <- newExpectedKind ctxt_kind -- See Note [Escaping kind in type signatures] ; stuff <- tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcLHsType hs_ty exp_kind + tcCheckLHsType hs_ty exp_kind ; return (exp_kind, stuff) } -- Default any unconstrained variables free in the kind @@ -609,7 +609,7 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_lhs_type (mkMode tyki) body kind } + ; tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs @@ -704,7 +704,7 @@ tcHsTypeApp wc_ty kind -- We are looking at a user-written type, very like a -- signature so we want to solve its equalities right now bindNamedWildCardBinders sig_wcs $ \ _ -> - tc_lhs_type mode hs_ty kind + tc_check_lhs_type mode hs_ty kind -- We do not kind-generalize type applications: we just -- instantiate with exactly what the user says. @@ -720,7 +720,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole +tcHsTypeApp, tcCheckLHsTypeInContext will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -790,10 +790,10 @@ We work this out in a hacky way, by looking at the expected kind: see Note [Inferring tuple kinds]. In this case, we kind-check the RHS using the kind gotten from the LHS: -see the call to tcCheckLHsType in tcTyFamInstEqnGuts in GHC.Tc.Tycl. +see the call to tcCheckLHsTypeInContext in tcTyFamInstEqnGuts in GHC.Tc.Tycl. But we want the kind from the LHS to be /zonked/, so that when -kind-checking the RHS (tcCheckLHsType) we can "see" what we learned +kind-checking the RHS (tcCheckLHsTypeInContext) we can "see" what we learned from kind-checking the LHS (tcFamTyPats). In our example above, the type of the LHS is just `kappa` (by instantiating the forall k), but then we learn (from x::Constraint) that kappa ~ Constraint. We want @@ -821,15 +821,15 @@ tcHsOpenType, tcHsLiftedType, tcHsOpenType hs_ty = addTypeCtxt hs_ty $ tcHsOpenTypeNC hs_ty tcHsLiftedType hs_ty = addTypeCtxt hs_ty $ tcHsLiftedTypeNC hs_ty -tcHsOpenTypeNC hs_ty = do { ek <- newOpenTypeKind; tcLHsType hs_ty ek } -tcHsLiftedTypeNC hs_ty = tcLHsType hs_ty liftedTypeKind +tcHsOpenTypeNC hs_ty = do { ek <- newOpenTypeKind; tcCheckLHsType hs_ty ek } +tcHsLiftedTypeNC hs_ty = tcCheckLHsType hs_ty liftedTypeKind --- Like tcHsType, but takes an expected kind -tcCheckLHsType :: LHsType GhcRn -> ContextKind -> TcM TcType -tcCheckLHsType hs_ty exp_kind +-- Like tcCheckLHsType, but takes an expected kind +tcCheckLHsTypeInContext :: LHsType GhcRn -> ContextKind -> TcM TcType +tcCheckLHsTypeInContext hs_ty exp_kind = addTypeCtxt hs_ty $ do { ek <- newExpectedKind exp_kind - ; tcLHsType hs_ty ek } + ; tcCheckLHsType hs_ty ek } tcInferLHsType :: LHsType GhcRn -> TcM TcType tcInferLHsType hs_ty @@ -854,7 +854,7 @@ tcInferLHsTypeUnsaturated :: LHsType GhcRn -> TcM (TcType, TcKind) tcInferLHsTypeUnsaturated hs_ty = addTypeCtxt hs_ty $ do { mode <- mkHoleMode TypeLevel HM_Sig -- Allow and report holes - ; case splitHsAppTys (unLoc hs_ty) of + ; case splitHsAppTys_maybe (unLoc hs_ty) of Just (hs_fun_ty, hs_args) -> do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty ; tcInferTyApps_nosat mode hs_fun_ty fun_ty hs_args } @@ -890,12 +890,18 @@ Terms are eagerly instantiated. This means that if you say x = id then `id` gets instantiated to have type alpha -> alpha. The variable -alpha is then unconstrained and regeneralized. But we cannot do this -in types, as we have no type-level lambda. So, when we are sure -that we will not want to regeneralize later -- because we are done -checking a type, for example -- we can instantiate. But we do not -instantiate at variables, nor do we in tcInferLHsTypeUnsaturated, -which is used by :kind in GHCi. +alpha is then unconstrained and regeneralized. So we may well end up with + x = /\x. id @a +But we cannot do this in types, as we have no type-level lambda. + +So, we must be careful only to instantiate at the last possible moment, when +we're sure we're never going to want the lost polymorphism again. This is done +in calls to `tcInstInvisibleTyBinders`; a particular case in point is in +`checkExpectedKind`. + +Otherwise, we are careful /not/ to instantiate. For example: +* at a variable in `tcTyVar` +* in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi. ************************************************************************ * * @@ -969,48 +975,18 @@ instance Outputable TcTyMode where {- Note [Bidirectional type checking] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In expressions, whenever we see a polymorphic identifier, say `id`, we are -free to instantiate it with metavariables, knowing that we can always -re-generalize with type-lambdas when necessary. For example: - - rank2 :: (forall a. a -> a) -> () - x = rank2 id - -When checking the body of `x`, we can instantiate `id` with a metavariable. -Then, when we're checking the application of `rank2`, we notice that we really -need a polymorphic `id`, and then re-generalize over the unconstrained -metavariable. - -In types, however, we're not so lucky, because *we cannot re-generalize*! -There is no lambda. So, we must be careful only to instantiate at the last -possible moment, when we're sure we're never going to want the lost polymorphism -again. This is done in calls to tcInstInvisibleTyBinders. - -To implement this behavior, we use bidirectional type checking, where we -explicitly think about whether we know the kind of the type we're checking -or not. Note that there is a difference between not knowing a kind and -knowing a metavariable kind: the metavariables are TauTvs, and cannot become -forall-quantified kinds. Previously (before dependent types), there were -no higher-rank kinds, and so we could instantiate early and be sure that -no types would have polymorphic kinds, and so we could always assume that -the kind of a type was a fresh metavariable. Not so anymore, thus the -need for two algorithms. - -For HsType forms that can never be kind-polymorphic, we implement only the -"down" direction, where we safely assume a metavariable kind. For HsType forms -that *can* be kind-polymorphic, we implement just the "up" (functions with -"infer" in their name) version, as we gain nothing by also implementing the -"down" version. - -Note [Future-proofing the type checker] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As discussed in Note [Bidirectional type checking], each HsType form is -handled in *either* tc_infer_hs_type *or* tc_hs_type. These functions -are mutually recursive, so that either one can work for any type former. -But, we want to make sure that our pattern-matches are complete. So, -we have a bunch of repetitive code just so that we get warnings if we're -missing any patterns. +In types, as in terms, we use bidirectional type infefence. The main workhorse +function looks like this: + type ExpKind = ExpType + data ExpType = Check TcSigmaKind | Infer ...(hole TcRhoType)... + + tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType + +* When the `ExpKind` argument is (Check ki), we /check/ that the type has + kind `ki` +* When the `ExpKind` argument is (Infer hole), we /infer/ the kind of the + type, and fill the hole with that kind -} ------------------------------------------ @@ -1022,74 +998,13 @@ tc_infer_lhs_type mode (L span ty) = setSrcSpanA span $ tc_infer_hs_type mode ty ---------------------------- --- | Call 'tc_infer_hs_type' and check its result against an expected kind. -tc_infer_hs_type_ek :: HasDebugCallStack => TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType -tc_infer_hs_type_ek mode hs_ty ek - = do { (ty, k) <- tc_infer_hs_type mode hs_ty - ; checkExpectedKind hs_ty ty k ek } - --------------------------- -- | Infer the kind of a type and desugar. This is the "up" type-checker, -- as described in Note [Bidirectional type checking] tc_infer_hs_type :: TcTyMode -> HsType GhcRn -> TcM (TcType, TcKind) -tc_infer_hs_type mode (HsParTy _ t) - = tc_infer_lhs_type mode t - -tc_infer_hs_type mode ty - | Just (hs_fun_ty, hs_args) <- splitHsAppTys ty - = do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty - ; tcInferTyApps mode hs_fun_ty fun_ty hs_args } - -tc_infer_hs_type mode (HsKindSig _ ty sig) - = do { let mode' = mode { mode_tyki = KindLevel } - ; sig' <- tc_lhs_kind_sig mode' KindSigCtxt sig - -- We must typecheck the kind signature, and solve all - -- its equalities etc; from this point on we may do - -- things like instantiate its foralls, so it needs - -- to be fully determined (#14904) - ; traceTc "tc_infer_hs_type:sig" (ppr ty $$ ppr sig') - ; ty' <- tcAddKindSigPlaceholders sig $ - tc_lhs_type mode ty sig' - ; return (ty', sig') } - --- HsSpliced is an annotation produced by 'GHC.Rename.Splice.rnSpliceType' to communicate --- the splice location to the typechecker. Here we skip over it in order to have --- the same kind inferred for a given expression whether it was produced from --- splices or not. --- --- See Note [Delaying modFinalizers in untyped splices]. -tc_infer_hs_type mode (HsSpliceTy (HsUntypedSpliceTop _ ty) _) - = tc_infer_lhs_type mode ty - -tc_infer_hs_type _ (HsSpliceTy (HsUntypedSpliceNested n) s) = pprPanic "tc_infer_hs_type: invalid nested splice" (pprUntypedSplice True (Just n) s) - -tc_infer_hs_type mode (HsDocTy _ ty _) = tc_infer_lhs_type mode ty - --- See Note [Typechecking HsCoreTys] -tc_infer_hs_type _ (XHsType ty) - = do env <- getLclEnv - -- Raw uniques since we go from NameEnv to TvSubstEnv. - let subst_prs :: [(Unique, TcTyVar)] - subst_prs = [ (getUnique nm, tv) - | ATyVar nm tv <- nonDetNameEnvElts (getLclEnvTypeEnv env) ] - subst = mkTvSubst - (mkInScopeSetList $ map snd subst_prs) - (listToUFM_Directly $ map (fmap mkTyVarTy) subst_prs) - ty' = substTy subst ty - return (ty', typeKind ty') - -tc_infer_hs_type _ (HsExplicitListTy _ _ tys) - | null tys -- this is so that we can use visible kind application with '[] - -- e.g ... '[] @Bool - = return (mkTyConTy promotedNilDataCon, - mkSpecForAllTys [alphaTyVar] $ mkListTy alphaTy) - -tc_infer_hs_type mode other_ty - = do { kv <- newMetaKindVar - ; ty' <- tc_hs_type mode other_ty kv - ; return (ty', kv) } +tc_infer_hs_type mode rn_ty + = tcInfer $ \exp_kind -> tcHsType mode rn_ty exp_kind {- Note [Typechecking HsCoreTys] @@ -1133,26 +1048,36 @@ substitution to each HsCoreTy and all is well: -} ------------------------------------------ -tcLHsType :: LHsType GhcRn -> TcKind -> TcM TcType -tcLHsType hs_ty exp_kind - = tc_lhs_type typeLevelMode hs_ty exp_kind +tcCheckLHsType :: LHsType GhcRn -> TcKind -> TcM TcType +tcCheckLHsType hs_ty exp_kind + = tc_check_lhs_type typeLevelMode hs_ty exp_kind + +tc_check_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType +tc_check_lhs_type mode (L span ty) exp_kind + = setSrcSpanA span $ + tc_check_hs_type mode ty exp_kind -tc_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType -tc_lhs_type mode (L span ty) exp_kind +tc_check_hs_type :: TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType +-- See Note [Bidirectional type checking] +tc_check_hs_type mode ty ek = tcHsType mode ty (Check ek) + +tcLHsType :: TcTyMode -> LHsType GhcRn -> ExpKind -> TcM TcType +tcLHsType mode (L span ty) exp_kind = setSrcSpanA span $ - tc_hs_type mode ty exp_kind + tcHsType mode ty exp_kind -tc_hs_type :: TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType +tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType +-- The main workhorse for type kind checking -- See Note [Bidirectional type checking] -tc_hs_type mode (HsParTy _ ty) exp_kind = tc_lhs_type mode ty exp_kind -tc_hs_type mode (HsDocTy _ ty _) exp_kind = tc_lhs_type mode ty exp_kind -tc_hs_type _ ty@(HsBangTy _ bang _) _ +tcHsType mode (HsParTy _ ty) exp_kind = tcLHsType mode ty exp_kind +tcHsType mode (HsDocTy _ ty _) exp_kind = tcLHsType mode ty exp_kind +tcHsType _ ty@(HsBangTy _ bang _) _ -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of -- bangs are invalid, so fail. (#7210, #14761) = failWith $ TcRnUnexpectedAnnotation ty bang -tc_hs_type _ ty@(HsRecTy {}) _ +tcHsType _ ty@(HsRecTy {}) _ -- Record types (which only show up temporarily in constructor -- signatures) should have been removed by now = failWithTc $ TcRnIllegalRecordSyntax (Right ty) @@ -1162,23 +1087,23 @@ tc_hs_type _ ty@(HsRecTy {}) _ -- while capturing the local environment. -- -- See Note [Delaying modFinalizers in untyped splices]. -tc_hs_type mode (HsSpliceTy (HsUntypedSpliceTop mod_finalizers ty) _) +tcHsType mode (HsSpliceTy (HsUntypedSpliceTop mod_finalizers ty) _) exp_kind = do addModFinalizersWithLclEnv mod_finalizers - tc_lhs_type mode ty exp_kind + tcLHsType mode ty exp_kind -tc_hs_type _ (HsSpliceTy (HsUntypedSpliceNested n) s) _ = pprPanic "tc_hs_type: invalid nested splice" (pprUntypedSplice True (Just n) s) +tcHsType _ (HsSpliceTy (HsUntypedSpliceNested n) s) _ = pprPanic "tcHsType: invalid nested splice" (pprUntypedSplice True (Just n) s) ---------- Functions and applications -tc_hs_type mode (HsFunTy _ mult ty1 ty2) exp_kind +tcHsType mode (HsFunTy _ mult ty1 ty2) exp_kind = tc_fun_type mode mult ty1 ty2 exp_kind -tc_hs_type mode (HsOpTy _ _ ty1 (L _ op) ty2) exp_kind +tcHsType mode (HsOpTy _ _ ty1 (L _ op) ty2) exp_kind | op `hasKey` unrestrictedFunTyConKey = tc_fun_type mode (HsUnrestrictedArrow noExtField) ty1 ty2 exp_kind --------- Foralls -tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind +tcHsType mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind | HsForAllInvis{} <- tele = tc_hs_forall_ty tele ty exp_kind -- For an invisible forall, we allow the body to have @@ -1187,15 +1112,15 @@ tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind | HsForAllVis{} <- tele = do { ek <- newOpenTypeKind - ; r <- tc_hs_forall_ty tele ty ek - ; checkExpectedKind t r ek exp_kind } + ; r <- tc_hs_forall_ty tele ty (Check ek) + ; checkExpKind t r ek exp_kind } -- For a visible forall, we require that the body is of kind TYPE r. -- See Note [Body kind of a HsForAllTy] where tc_hs_forall_ty tele ty ek = do { (tv_bndrs, ty') <- tcTKTelescope mode tele $ - tc_lhs_type mode ty ek + tcLHsType mode ty ek -- Pass on the mode from the type, to any wildcards -- in kind signatures on the forall'd variables -- e.g. f :: _ -> Int -> forall (a :: _). blah @@ -1203,145 +1128,196 @@ tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind -- Do not kind-generalise here! See Note [Kind generalisation] ; return (mkForAllTys tv_bndrs ty') } -tc_hs_type mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind +tcHsType mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind | null (unLoc ctxt) - = tc_lhs_type mode rn_ty exp_kind - - -- See Note [Body kind of a HsQualTy] - | isConstraintLikeKind exp_kind + = tcLHsType mode rn_ty exp_kind + -- See Note [Body kind of a HsQualTy] + | Check kind <- exp_kind, isConstraintLikeKind kind = do { ctxt' <- tc_hs_context mode ctxt - ; ty' <- tc_lhs_type mode rn_ty constraintKind - ; return (tcMkDFunPhiTy ctxt' ty') } + ; ty' <- tc_check_lhs_type mode rn_ty constraintKind + ; return (tcMkDFunPhiTy ctxt' ty') } | otherwise = do { ctxt' <- tc_hs_context mode ctxt - ; ek <- newOpenTypeKind -- The body kind (result of the function) can + ; ek <- newOpenTypeKind -- The body kind (result of the function) can -- be TYPE r, for any r, hence newOpenTypeKind - ; ty' <- tc_lhs_type mode rn_ty ek - ; checkExpectedKind (unLoc rn_ty) (tcMkPhiTy ctxt' ty') - liftedTypeKind exp_kind } + ; ty' <- tc_check_lhs_type mode rn_ty ek + ; let res_ty = tcMkPhiTy ctxt' ty' + ; checkExpKind (unLoc rn_ty) res_ty + liftedTypeKind exp_kind } --------- Lists, arrays, and tuples -tc_hs_type mode rn_ty@(HsListTy _ elt_ty) exp_kind - = do { tau_ty <- tc_lhs_type mode elt_ty liftedTypeKind +tcHsType mode rn_ty@(HsListTy _ elt_ty) exp_kind + = do { tau_ty <- tc_check_lhs_type mode elt_ty liftedTypeKind ; checkWiredInTyCon listTyCon - ; checkExpectedKind rn_ty (mkListTy tau_ty) liftedTypeKind exp_kind } + ; checkExpKind rn_ty (mkListTy tau_ty) liftedTypeKind exp_kind } --- See Note [Distinguishing tuple kinds] in Language.Haskell.Syntax.Type --- See Note [Inferring tuple kinds] -tc_hs_type mode rn_ty@(HsTupleTy _ HsBoxedOrConstraintTuple hs_tys) exp_kind - -- (NB: not zonking before looking at exp_k, to avoid left-right bias) - | Just tup_sort <- tupKindSort_maybe exp_kind - = traceTc "tc_hs_type tuple" (ppr hs_tys) >> - tc_tuple rn_ty mode tup_sort hs_tys exp_kind - | otherwise - = do { traceTc "tc_hs_type tuple 2" (ppr hs_tys) - ; (tys, kinds) <- mapAndUnzipM (tc_infer_lhs_type mode) hs_tys - ; kinds <- liftZonkM $ mapM zonkTcType kinds - -- Infer each arg type separately, because errors can be - -- confusing if we give them a shared kind. Eg #7410 - -- (Either Int, Int), we do not want to get an error saying - -- "the second argument of a tuple should have kind *->*" +tcHsType mode rn_ty@(HsTupleTy _ tup_sort tys) exp_kind + = do k <- expTypeToType exp_kind + tc_hs_tuple_ty rn_ty mode tup_sort tys k - ; let (arg_kind, tup_sort) - = case [ (k,s) | k <- kinds - , Just s <- [tupKindSort_maybe k] ] of - ((k,s) : _) -> (k,s) - [] -> (liftedTypeKind, BoxedTuple) - -- In the [] case, it's not clear what the kind is, so guess * - - ; tys' <- sequence [ setSrcSpanA loc $ - checkExpectedKind hs_ty ty kind arg_kind - | ((L loc hs_ty),ty,kind) <- zip3 hs_tys tys kinds ] - - ; finish_tuple rn_ty tup_sort tys' (map (const arg_kind) tys') exp_kind } - - -tc_hs_type mode rn_ty@(HsTupleTy _ HsUnboxedTuple tys) exp_kind - = tc_tuple rn_ty mode UnboxedTuple tys exp_kind - -tc_hs_type mode rn_ty@(HsSumTy _ hs_tys) exp_kind +tcHsType mode rn_ty@(HsSumTy _ hs_tys) exp_kind = do { let arity = length hs_tys ; arg_kinds <- mapM (\_ -> newOpenTypeKind) hs_tys - ; tau_tys <- zipWithM (tc_lhs_type mode) hs_tys arg_kinds + ; tau_tys <- zipWithM (tc_check_lhs_type mode) hs_tys arg_kinds ; let arg_reps = map kindRep arg_kinds arg_tys = arg_reps ++ tau_tys sum_ty = mkTyConApp (sumTyCon arity) arg_tys sum_kind = unboxedSumKind arg_reps - ; checkExpectedKind rn_ty sum_ty sum_kind exp_kind + ; checkExpKind rn_ty sum_ty sum_kind exp_kind } --------- Promoted lists and tuples -tc_hs_type mode rn_ty@(HsExplicitListTy _ _ tys) exp_kind - -- The '[] case is handled in tc_infer_hs_type. - -- See Note [Future-proofing the type checker]. +tcHsType mode rn_ty@(HsExplicitListTy _ _ tys) exp_kind + -- See Note [Kind-checking explicit lists] + | null tys - = tc_infer_hs_type_ek mode rn_ty exp_kind + = do let ty = mkTyConTy promotedNilDataCon + let kind = mkSpecForAllTys [alphaTyVar] $ mkListTy alphaTy + checkExpKind rn_ty ty kind exp_kind | otherwise = do { tks <- mapM (tc_infer_lhs_type mode) tys ; (taus', kind) <- unifyKinds tys tks ; let ty = (foldr (mk_cons kind) (mk_nil kind) taus') - ; checkExpectedKind rn_ty ty (mkListTy kind) exp_kind } + ; checkExpKind rn_ty ty (mkListTy kind) exp_kind } where mk_cons k a b = mkTyConApp (promoteDataCon consDataCon) [k, a, b] mk_nil k = mkTyConApp (promoteDataCon nilDataCon) [k] -tc_hs_type mode rn_ty@(HsExplicitTupleTy _ tys) exp_kind +tcHsType mode rn_ty@(HsExplicitTupleTy _ tys) exp_kind -- using newMetaKindVar means that we force instantiations of any polykinded -- types. At first, I just used tc_infer_lhs_type, but that led to #11255. = do { ks <- replicateM arity newMetaKindVar - ; taus <- zipWithM (tc_lhs_type mode) tys ks + ; taus <- zipWithM (tc_check_lhs_type mode) tys ks ; let kind_con = tupleTyCon Boxed arity ty_con = promotedTupleDataCon Boxed arity tup_k = mkTyConApp kind_con ks ; checkTupSize arity - ; checkExpectedKind rn_ty (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind } + ; checkExpKind rn_ty (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind } where arity = length tys --------- Constraint types -tc_hs_type mode rn_ty@(HsIParamTy _ (L _ n) ty) exp_kind +tcHsType mode rn_ty@(HsIParamTy _ (L _ n) ty) exp_kind = do { massert (isTypeLevel (mode_tyki mode)) - ; ty' <- tc_lhs_type mode ty liftedTypeKind + ; ty' <- tc_check_lhs_type mode ty liftedTypeKind ; let n' = mkStrLitTy $ hsIPNameFS n ; ipClass <- tcLookupClass ipClassName - ; checkExpectedKind rn_ty (mkClassPred ipClass [n',ty']) + ; checkExpKind rn_ty (mkClassPred ipClass [n',ty']) constraintKind exp_kind } -tc_hs_type _ rn_ty@(HsStarTy _ _) exp_kind +tcHsType _ rn_ty@(HsStarTy _ _) exp_kind -- Desugaring 'HsStarTy' to 'Data.Kind.Type' here means that we don't -- have to handle it in 'coreView' - = checkExpectedKind rn_ty liftedTypeKind liftedTypeKind exp_kind + = checkExpKind rn_ty liftedTypeKind liftedTypeKind exp_kind --------- Literals -tc_hs_type _ rn_ty@(HsTyLit _ (HsNumTy _ n)) exp_kind +tcHsType _ rn_ty@(HsTyLit _ (HsNumTy _ n)) exp_kind = do { checkWiredInTyCon naturalTyCon - ; checkExpectedKind rn_ty (mkNumLitTy n) naturalTy exp_kind } + ; checkExpKind rn_ty (mkNumLitTy n) naturalTy exp_kind } -tc_hs_type _ rn_ty@(HsTyLit _ (HsStrTy _ s)) exp_kind +tcHsType _ rn_ty@(HsTyLit _ (HsStrTy _ s)) exp_kind = do { checkWiredInTyCon typeSymbolKindCon - ; checkExpectedKind rn_ty (mkStrLitTy s) typeSymbolKind exp_kind } -tc_hs_type _ rn_ty@(HsTyLit _ (HsCharTy _ c)) exp_kind + ; checkExpKind rn_ty (mkStrLitTy s) typeSymbolKind exp_kind } +tcHsType _ rn_ty@(HsTyLit _ (HsCharTy _ c)) exp_kind = do { checkWiredInTyCon charTyCon - ; checkExpectedKind rn_ty (mkCharLitTy c) charTy exp_kind } + ; checkExpKind rn_ty (mkCharLitTy c) charTy exp_kind } --------- Wildcards -tc_hs_type mode ty@(HsWildCardTy _) ek - = tcAnonWildCardOcc NoExtraConstraint mode ty ek +tcHsType mode ty@(HsWildCardTy _) ek + = do k <- expTypeToType ek + tcAnonWildCardOcc NoExtraConstraint mode ty k + +--------- Type applications +tcHsType mode rn_ty@(HsTyVar{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsAppTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsAppKindTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsOpTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind + +tcHsType mode rn_ty@(HsKindSig _ ty sig) exp_kind + = do { let mode' = mode { mode_tyki = KindLevel } + ; sig' <- tc_lhs_kind_sig mode' KindSigCtxt sig + -- We must typecheck the kind signature, and solve all + -- its equalities etc; from this point on we may do + -- things like instantiate its foralls, so it needs + -- to be fully determined (#14904) + ; traceTc "tcHsType:sig" (ppr ty $$ ppr sig') + ; ty' <- tcAddKindSigPlaceholders sig $ + tc_check_lhs_type mode ty sig' + ; checkExpKind rn_ty ty' sig' exp_kind } + +-- See Note [Typechecking HsCoreTys] +tcHsType _ rn_ty@(XHsType ty) exp_kind + = do env <- getLclEnv + -- Raw uniques since we go from NameEnv to TvSubstEnv. + let subst_prs :: [(Unique, TcTyVar)] + subst_prs = [ (getUnique nm, tv) + | ATyVar nm tv <- nonDetNameEnvElts (getLclEnvTypeEnv env) ] + subst = mkTvSubst + (mkInScopeSetList $ map snd subst_prs) + (listToUFM_Directly $ map (fmap mkTyVarTy) subst_prs) + ty' = substTy subst ty + checkExpKind rn_ty ty' (typeKind ty') exp_kind + +tc_hs_tuple_ty :: HsType GhcRn + -> TcTyMode + -> HsTupleSort + -> [LHsType GhcRn] + -> TcKind + -> TcM TcType +-- See Note [Distinguishing tuple kinds] in GHC.Hs.Type +-- See Note [Inferring tuple kinds] +tc_hs_tuple_ty rn_ty mode HsBoxedOrConstraintTuple hs_tys exp_kind + -- (NB: not zonking before looking at exp_k, to avoid left-right bias) + | Just tup_sort <- tupKindSort_maybe exp_kind + = traceTc "tcHsType tuple" (ppr hs_tys) >> + tc_tuple rn_ty mode tup_sort hs_tys exp_kind + | otherwise + = do { traceTc "tcHsType tuple 2" (ppr hs_tys) + ; (tys, kinds) <- mapAndUnzipM (tc_infer_lhs_type mode) hs_tys + ; kinds <- liftZonkM $ mapM zonkTcType kinds + -- Infer each arg type separately, because errors can be + -- confusing if we give them a shared kind. Eg #7410 + -- (Either Int, Int), we do not want to get an error saying + -- "the second argument of a tuple should have kind *->*" + + ; let (arg_kind, tup_sort) + = case [ (k,s) | k <- kinds + , Just s <- [tupKindSort_maybe k] ] of + ((k,s) : _) -> (k,s) + [] -> (liftedTypeKind, BoxedTuple) + -- In the [] case, it's not clear what the kind is, so guess * ---------- Potentially kind-polymorphic types: call the "up" checker --- See Note [Future-proofing the type checker] -tc_hs_type mode ty@(HsTyVar {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsAppTy {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsAppKindTy{}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsOpTy {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsKindSig {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(XHsType {}) ek = tc_infer_hs_type_ek mode ty ek + ; tys' <- sequence [ setSrcSpanA loc $ + checkExpectedKind hs_ty ty kind arg_kind + | ((L loc hs_ty),ty,kind) <- zip3 hs_tys tys kinds ] + + ; finish_tuple rn_ty tup_sort tys' (map (const arg_kind) tys') exp_kind } +tc_hs_tuple_ty rn_ty mode HsUnboxedTuple tys exp_kind = + tc_tuple rn_ty mode UnboxedTuple tys exp_kind {- +Note [Kind-checking explicit lists] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In a type, suppose we have an application (F [t1,t2]), +where [t1,t2] is an explicit list, and + F :: [ki] -> blah + +Then we want to return the type + F ((:) @ki t2 ((:) @ki t2 ([] @ki))) +where the argument list is instantiated to F's argument kind `ki`. + +But what about (G []), where + G :: (forall k. [k]) -> blah + +Here we want to return (G []), with no instantiation at all. But since we have +no lambda in types, we must be careful not to instantiate that `[]`, because we +can't re-generalise it. Hence, when kind-checking an explicit list, we need a +special case for `[]`. + Note [Variable Specificity and Forall Visibility] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsForAllTy contains an HsForAllTelescope to denote the visibility of the forall @@ -1366,28 +1342,28 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo ------------------------------------------ tc_mult :: TcTyMode -> HsArrow GhcRn -> TcM Mult -tc_mult mode ty = tc_lhs_type mode (arrowToHsType ty) multiplicityTy +tc_mult mode ty = tc_check_lhs_type mode (arrowToHsType ty) multiplicityTy ------------------------------------------ -tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> TcKind +tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind -> TcM TcType tc_fun_type mode mult ty1 ty2 exp_kind = case mode_tyki mode of TypeLevel -> do { traceTc "tc_fun_type" (ppr ty1 $$ ppr ty2) ; arg_k <- newOpenTypeKind ; res_k <- newOpenTypeKind - ; ty1' <- tc_lhs_type mode ty1 arg_k - ; ty2' <- tc_lhs_type mode ty2 res_k + ; ty1' <- tc_check_lhs_type mode ty1 arg_k + ; ty2' <- tc_check_lhs_type mode ty2 res_k ; mult' <- tc_mult mode mult - ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) - (tcMkVisFunTy mult' ty1' ty2') - liftedTypeKind exp_kind } + ; checkExpKind (HsFunTy noExtField mult ty1 ty2) + (tcMkVisFunTy mult' ty1' ty2') + liftedTypeKind exp_kind } KindLevel -> -- no representation polymorphism in kinds. yet. - do { ty1' <- tc_lhs_type mode ty1 liftedTypeKind - ; ty2' <- tc_lhs_type mode ty2 liftedTypeKind + do { ty1' <- tc_check_lhs_type mode ty1 liftedTypeKind + ; ty2' <- tc_check_lhs_type mode ty2 liftedTypeKind ; mult' <- tc_mult mode mult - ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) - (tcMkVisFunTy mult' ty1' ty2') - liftedTypeKind exp_kind } + ; checkExpKind (HsFunTy noExtField mult ty1 ty2) + (tcMkVisFunTy mult' ty1' ty2') + liftedTypeKind exp_kind } {- Note [Skolem escape and forall-types] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1442,7 +1418,7 @@ tc_tuple rn_ty mode tup_sort tys exp_kind BoxedTuple -> return (replicate arity liftedTypeKind) UnboxedTuple -> replicateM arity newOpenTypeKind ConstraintTuple -> return (replicate arity constraintKind) - ; tau_tys <- zipWithM (tc_lhs_type mode) tys arg_kinds + ; tau_tys <- zipWithM (tc_check_lhs_type mode) tys arg_kinds ; finish_tuple rn_ty tup_sort tau_tys arg_kinds exp_kind } where arity = length tys @@ -1530,9 +1506,9 @@ since the two constraints should be semantically equivalent. * * ********************************************************************* -} -splitHsAppTys :: HsType GhcRn -> Maybe (LHsType GhcRn, [LHsTypeArg GhcRn]) -splitHsAppTys hs_ty - | is_app hs_ty = Just (go (noLocA hs_ty) []) +splitHsAppTys_maybe :: HsType GhcRn -> Maybe (LHsType GhcRn, [LHsTypeArg GhcRn]) +splitHsAppTys_maybe hs_ty + | is_app hs_ty = Just (splitHsAppTys hs_ty) | otherwise = Nothing where is_app :: HsType GhcRn -> Bool @@ -1547,6 +1523,10 @@ splitHsAppTys hs_ty is_app (HsParTy _ (L _ ty)) = is_app ty is_app _ = False +splitHsAppTys :: HsType GhcRn -> (LHsType GhcRn, [LHsTypeArg GhcRn]) + +splitHsAppTys hs_ty = go (noLocA hs_ty) [] + where go :: LHsType GhcRn -> [HsArg GhcRn (LHsType GhcRn) (LHsKind GhcRn)] -> (LHsType GhcRn, @@ -1570,6 +1550,14 @@ tcInferTyAppHead _ (L _ (HsTyVar _ _ (L _ tv))) tcInferTyAppHead mode ty = tc_infer_lhs_type mode ty +tc_app_ty :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType +tc_app_ty mode rn_ty exp_kind + = do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty + ; (ty, infered_kind) <- tcInferTyApps mode hs_fun_ty fun_ty hs_args + ; checkExpKind rn_ty ty infered_kind exp_kind } + where + (hs_fun_ty, hs_args) = splitHsAppTys rn_ty + --------------------------- -- | Apply a type of a given kind to a list of arguments. This instantiates -- invisible parameters as necessary. Always consumes all the arguments, @@ -1656,7 +1644,7 @@ tcInferTyApps_nosat mode orig_hs_ty fun orig_hs_args ; arg_mode <- mkHoleMode KindLevel HM_VTA -- HM_VKA: see Note [Wildcards in visible kind application] ; ki_arg <- addErrCtxt (funAppCtxt orig_hs_ty hs_ki_arg n) $ - tc_lhs_type arg_mode hs_ki_arg exp_kind + tc_check_lhs_type arg_mode hs_ki_arg exp_kind ; traceTc "tcInferTyApps (vis kind app)" (ppr exp_kind) ; (subst', fun') <- mkAppTyM subst fun ki_binder ki_arg @@ -1687,7 +1675,7 @@ tcInferTyApps_nosat mode orig_hs_ty fun orig_hs_args , ppr subst ]) ; let exp_kind = substTy subst $ piTyBinderType ki_binder ; arg' <- addErrCtxt (funAppCtxt orig_hs_ty arg n) $ - tc_lhs_type mode arg exp_kind + tc_check_lhs_type mode arg exp_kind ; traceTc "tcInferTyApps (vis normal app) 2" (ppr exp_kind) ; (subst', fun') <- mkAppTyM subst fun ki_binder arg' ; go (n+1) fun' subst' inner_ki args } @@ -1975,6 +1963,19 @@ checkExpectedKind hs_ty ty act_kind exp_kind n_act_invis_bndrs = invisibleTyBndrCount act_kind n_to_inst = n_act_invis_bndrs - n_exp_invis_bndrs + +-- tyr <- checkExpKind hs_ty ty (act_ki :: Kind) (exp_ki :: ExpKind) +-- requires that `ty` has kind `act_ki` +-- It checks that the actual kind `act_ki` matches the expected kind `exp_ki` +-- and returns `tyr`, a possibly-casted form of `ty`, that has precisely kind `exp_ki` +-- `hs_ty` is purely for error messages +checkExpKind :: HsType GhcRn -> TcType -> TcKind -> ExpKind -> TcM TcType +checkExpKind rn_ty ty ki (Check ki') = + checkExpectedKind rn_ty ty ki ki' +checkExpKind _rn_ty ty ki (Infer cell) = do + co <- fillInferResult ki cell + pure (ty `mkCastTy` co) + --------------------------- tcHsContext :: Maybe (LHsContext GhcRn) -> TcM [PredType] @@ -1988,7 +1989,7 @@ tc_hs_context :: TcTyMode -> LHsContext GhcRn -> TcM [PredType] tc_hs_context mode ctxt = mapM (tc_lhs_pred mode) (unLoc ctxt) tc_lhs_pred :: TcTyMode -> LHsType GhcRn -> TcM PredType -tc_lhs_pred mode pred = tc_lhs_type mode pred constraintKind +tc_lhs_pred mode pred = tc_check_lhs_type mode pred constraintKind --------------------------- tcTyVar :: Name -> TcM (TcType, TcKind) @@ -4109,7 +4110,7 @@ tcHsPartialSigType ctxt sig_ty ; tau <- -- Don't do (addTypeCtxt hs_tau) here else we get -- In the type -- In the type signature: foo :: - tc_lhs_type mode hs_tau ek + tc_check_lhs_type mode hs_tau ek ; return (wcs, wcx, theta, tau) } @@ -4419,8 +4420,8 @@ tc_type_in_pat ctxt hole_mode hs_ty wcs ns ctxt_kind -- and c.f #16033 bindNamedWildCardBinders wcs $ \ wcs -> tcExtendNameTyVarEnv tkv_prs $ - do { ek <- newExpectedKind ctxt_kind - ; ty <- tc_lhs_type mode hs_ty ek + do { ek <- newExpectedKind ctxt_kind + ; ty <- tc_check_lhs_type mode hs_ty ek ; return (wcs, ty) } ; mapM_ emitNamedTypeHole wcs @@ -4596,7 +4597,7 @@ tc_lhs_kind_sig mode ctxt hs_kind -- Result is zonked = do { kind <- addErrCtxt (text "In the kind" <+> quotes (ppr hs_kind)) $ solveEqualities "tcLHsKindSig" $ - tc_lhs_type mode hs_kind liftedTypeKind + tc_check_lhs_type mode hs_kind liftedTypeKind ; traceTc "tcLHsKindSig" (ppr hs_kind $$ ppr kind) -- No generalization: ; kindGeneralizeNone kind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1772,7 +1772,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ let res_kind = tyConResKind tycon - in discardResult $ tcCheckLHsType rhs (TheKind res_kind) + in discardResult $ tcCheckLHsTypeInContext rhs (TheKind res_kind) -- NB: check against the result kind that we allocated -- in inferInitialKinds. @@ -1801,7 +1801,7 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsType (getBangType ty) exp_kind + ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1868,7 +1868,7 @@ kcConDecl new_or_data do { _ <- tcHsContext cxt ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind - ; _ <- tcCheckLHsType res_ty (TheKind con_res_kind) + ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) ; kcConGADTArgs new_or_data con_res_kind args ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) ; return () } @@ -1895,7 +1895,7 @@ Otherwise we'd infer the bogus kind The type signature for MkT influences the kind of T simply by kind-checking the result type (T g b), which will force 'f' and 'g' to have the same kinds. This is the call to - tcCheckLHsType res_ty (TheKind con_res_kind) + tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) Because this is the result type of an arrow, we know the kind must be of form (TYPE rr), and we get better error messages if we enforce that here (e.g. test gadt10). @@ -3054,7 +3054,7 @@ tcTySynRhs roles_info tc_name hs_ty do { env <- getLclEnv ; traceTc "tc-syn" (ppr tc_name $$ ppr (getLclEnvRdrEnv env)) ; rhs_ty <- pushLevelAndSolveEqualities skol_info tc_bndrs $ - tcCheckLHsType hs_ty (TheKind res_kind) + tcCheckLHsTypeInContext hs_ty (TheKind res_kind) -- See Note [Error on unconstrained meta-variables] in GHC.Tc.Utils.TcMType -- Example: (typecheck/should_fail/T17567) @@ -3197,7 +3197,7 @@ kcTyFamInstEqn tc_fam_tc ; discardResult $ bindOuterFamEqnTKBndrs_Q_Tv outer_bndrs $ do { (_fam_app, res_kind) <- tcFamTyPats tc_fam_tc hs_pats - ; tcCheckLHsType hs_rhs_ty (TheKind res_kind) } + ; tcCheckLHsTypeInContext hs_rhs_ty (TheKind res_kind) } -- Why "_Tv" here? Consider (#14066) -- type family Bar x y where -- Bar (x :: a) (y :: b) = Int @@ -3349,7 +3349,7 @@ tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty -- Ensure that the instance is consistent with its -- parent class (#16008) ; addConsistencyConstraints mb_clsinfo lhs_ty - ; rhs_ty <- tcCheckLHsType hs_rhs_ty (TheKind rhs_kind) + ; rhs_ty <- tcCheckLHsTypeInContext hs_rhs_ty (TheKind rhs_kind) ; return (lhs_ty, rhs_ty) } ; outer_bndrs <- scopedSortOuter outer_bndrs @@ -3926,7 +3926,7 @@ tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatype -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) = do { traceTc "tcConArg 1" (ppr bty) - ; arg_ty <- tcCheckLHsType (getBangType bty) exp_kind + ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -27,7 +27,7 @@ module GHC.Tc.Utils.TcType ( TcKind, TcCoVar, TcTyCoVar, TcTyVarBinder, TcInvisTVBinder, TcReqTVBinder, TcTyCon, MonoTcTyCon, PolyTcTyCon, TcTyConBinder, KnotTied, - ExpType(..), InferResult(..), + ExpType(..), ExpKind, InferResult(..), ExpTypeFRR, ExpSigmaType, ExpSigmaTypeFRR, ExpRhoType, mkCheckExpType, @@ -433,6 +433,9 @@ type ExpSigmaTypeFRR = ExpTypeFRR type ExpRhoType = ExpType +-- | Like 'ExpType', but on kind level +type ExpKind = ExpType + instance Outputable ExpType where ppr (Check ty) = text "Check" <> braces (ppr ty) ppr (Infer ir) = ppr ir ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -43,6 +43,8 @@ module GHC.Tc.Utils.Unify ( PuResult(..), failCheckWith, okCheckRefl, mapCheck, TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, famAppArgFlags, simpleUnifyCheck, checkPromoteFreeVars, + + fillInferResult, ) where import GHC.Prelude ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -1006,7 +1006,7 @@ would mean that when we pretty-print it back, we don't know whether the user wrote '*' or 'Type', and lose the parse/ppr roundtrip property. As a workaround, we parse '*' as HsStarTy (if it stands for 'Data.Kind.Type') -and then desugar it to 'Data.Kind.Type' in the typechecker (see tc_hs_type). +and then desugar it to 'Data.Kind.Type' in the typechecker (see tcHsType). When '*' is a regular type operator (StarIsType is disabled), HsStarTy is not involved. ===================================== rts/TSANUtils.c ===================================== @@ -2,7 +2,7 @@ #if defined(TSAN_ENABLED) -uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder) { __tsan_atomic64_compare_exchange_strong( ptr, &expected, new_value, @@ -10,7 +10,7 @@ uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, ui return expected; } -uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder) { __tsan_atomic32_compare_exchange_strong( ptr, &expected, new_value, @@ -18,7 +18,7 @@ uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, ui return expected; } -uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder) { __tsan_atomic16_compare_exchange_strong( ptr, &expected, new_value, @@ -26,7 +26,7 @@ uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, ui return expected; } -uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder) { __tsan_atomic8_compare_exchange_strong( ptr, &expected, new_value, ===================================== rts/include/Cmm.h ===================================== @@ -698,11 +698,11 @@ #define ACQUIRE_FENCE prim %fence_acquire(); #define SEQ_CST_FENCE prim %fence_seq_cst(); -#if TSAN_ENABLED +#if defined(TSAN_ENABLED) // This is may be efficient than a fence but TSAN can reason about it. -#if WORD_SIZE_IN_BITS == 64 +#if SIZEOF_W == 8 #define ACQUIRE_FENCE_ON(x) if (1) { W_ tmp; (tmp) = prim %load_acquire64(x); } -#elif WORD_SIZE_IN_BITS == 32 +#elif SIZEOF_W == 4 #define ACQUIRE_FENCE_ON(x) if (1) { W_ tmp; (tmp) = prim %load_acquire32(x); } #endif #else ===================================== rts/include/rts/TSANUtils.h ===================================== @@ -98,10 +98,18 @@ void AnnotateBenignRaceSized(const char *file, #define TSAN_ANNOTATE_BENIGN_RACE(addr,desc) \ TSAN_ANNOTATE_BENIGN_RACE_SIZED((void*)(addr), sizeof(*addr), desc) +#if defined(TSAN_ENABLED) && defined(__clang__) +#include +#else +typedef char __tsan_atomic8; +typedef short __tsan_atomic16; +typedef int __tsan_atomic32; +typedef long __tsan_atomic64; +#endif -uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder); -uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder); -uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder); -uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder); +__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder); +__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder); +__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder); +__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder); #endif ===================================== rts/include/stg/SMP.h ===================================== @@ -549,9 +549,14 @@ busy_wait_nop(void) #define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST) #if defined(TSAN_ENABLED) +#if !defined(__clang__) +#undef ACQUIRE_FENCE +#undef RELEASE_FENCE +#undef SEQ_CST_FENCE #define ACQUIRE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_ACQUIRE);) #define RELEASE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_RELEASE);) #define SEQ_CST_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_SEQ_CST);) +#endif #define ACQUIRE_FENCE_ON(x) (void)ACQUIRE_LOAD(x) #else #define ACQUIRE_FENCE_ON(x) __atomic_thread_fence(__ATOMIC_ACQUIRE) ===================================== rts/rts.cabal ===================================== @@ -184,7 +184,6 @@ library if flag(thread-sanitizer) cc-options: -fsanitize=thread ld-options: -fsanitize=thread - extra-libraries: tsan if os(linux) -- the RTS depends upon libc. while this dependency is generally ===================================== testsuite/tests/partial-sigs/should_run/GHCiWildcardKind.stdout ===================================== @@ -1,2 +1,2 @@ -_ :: k +_ :: p Maybe _ :: * ===================================== testsuite/tests/th/T24299.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE TemplateHaskell #-} + +module T24299 where +import Language.Haskell.TH.Syntax (addModFinalizer, runIO) +import GHC.Types (Type) +import System.IO + +type Proxy :: forall a. a -> Type +data Proxy a = MkProxy + +check :: ($(addModFinalizer (runIO (do putStrLn "check"; hFlush stdout)) >> + [t| Proxy |]) :: Type -> Type) Int -- There is kind signature, we are in check mode +check = MkProxy + +infer :: ($(addModFinalizer (runIO (do putStrLn "infer"; hFlush stdout)) >> + [t| Proxy |]) ) Int -- no kind signature, inference mode is enabled +infer = MkProxy ===================================== testsuite/tests/th/T24299.stderr ===================================== @@ -0,0 +1,2 @@ +check +infer ===================================== testsuite/tests/th/all.T ===================================== @@ -606,3 +606,4 @@ test('T14032e', normal, compile_fail, ['-dsuppress-uniques']) test('ListTuplePunsTH', [only_ways(['ghci']), extra_files(['ListTuplePunsTH.hs', 'T15843a.hs'])], ghci_script, ['ListTuplePunsTH.script']) test('T24559', normal, compile, ['']) test('T24571', normal, compile, ['']) +test('T24299', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9884f016e07e78aff67a38786c45a536621a20e...c1c37c47130f1f78137f49a1bfb5e0e3dd322b37 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9884f016e07e78aff67a38786c45a536621a20e...c1c37c47130f1f78137f49a1bfb5e0e3dd322b37 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 13:13:59 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 09:13:59 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660c04979fa87_26e1f6242bccc137895@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 07b5e766 by Rodrigo Mesquita at 2024-04-02T14:13:45+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 4 changed files: - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = addDLL_PEi386(path, &(HINSTANCE)r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07b5e766fd3d08a8056982488918e272025fb69a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07b5e766fd3d08a8056982488918e272025fb69a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 13:19:55 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 09:19:55 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660c05fb99da8_26e1f625441e013835a@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 0116da1c by Rodrigo Mesquita at 2024-04-02T14:19:45+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 4 changed files: - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%PATH_FMT'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0116da1c6e5d11441c44ee1d4e75760fd6b0ac85 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0116da1c6e5d11441c44ee1d4e75760fd6b0ac85 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 13:22:45 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 09:22:45 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] fixup! rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660c06a536605_39cba685520196eb@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: d445f1b3 by Rodrigo Mesquita at 2024-04-02T14:21:53+01:00 fixup! rts: Make addDLL a wrapper around loadNativeObj - - - - - 4 changed files: - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d445f1b32208c16908707bc8a930c4b856d53b26 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d445f1b32208c16908707bc8a930c4b856d53b26 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 13:24:26 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 09:24:26 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660c070a946fd_39cba61e573020111@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: b072d397 by Rodrigo Mesquita at 2024-04-02T14:24:07+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 896de9ca by Rodrigo Mesquita at 2024-04-02T14:24:10+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d445f1b32208c16908707bc8a930c4b856d53b26...896de9ca275c52bff530aafd343ceb246866d2f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d445f1b32208c16908707bc8a930c4b856d53b26...896de9ca275c52bff530aafd343ceb246866d2f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 13:45:29 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Tue, 02 Apr 2024 09:45:29 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/invis-pats-change-ast] Change how invisible patterns represented in haskell syntax and TH AST (#24557) Message-ID: <660c0bf991b9b_39cba65a5fc8267c6@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/invis-pats-change-ast at Glasgow Haskell Compiler / GHC Commits: 64339f17 by Andrei Borzenkov at 2024-04-02T17:45:09+04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64339f17846405e046f8c6d241ef1a2887ffe37d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64339f17846405e046f8c6d241ef1a2887ffe37d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 14:52:58 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 10:52:58 -0400 Subject: [Git][ghc/ghc][wip/simplifier-tweaks] 3 commits: Simplifier improvements Message-ID: <660c1bcaeb80a_2bcef227862023858@gitlab.mail> Simon Peyton Jones pushed to branch wip/simplifier-tweaks at Glasgow Haskell Compiler / GHC Commits: 8b2a088d by Simon Peyton Jones at 2024-04-02T15:52:49+01:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: T13253-spj T18304 T18698a T9961 T3294 - - - - - e9149c8c by Simon Peyton Jones at 2024-04-02T15:52:49+01:00 Testsuite message changes from simplifier improvements - - - - - 848f360f by Simon Peyton Jones at 2024-04-02T15:52:49+01:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 24 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Stats.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unfold/Make.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Tickish.hs - testsuite/tests/arityanal/should_compile/Arity01.stderr - testsuite/tests/arityanal/should_compile/Arity02.stderr - testsuite/tests/arityanal/should_compile/Arity09.stderr - testsuite/tests/arityanal/should_compile/Arity13.stderr - testsuite/tests/cpranal/should_compile/T18401.stderr - testsuite/tests/driver/inline-check.stderr - testsuite/tests/lib/integer/Makefile - testsuite/tests/numeric/should_compile/T19641.stderr - testsuite/tests/perf/compiler/T15630.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c556cf6d71e096eb62851503fc04266d1e32895b...848f360fe1bcbdac28e9cc0014665bf8ccbfd259 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c556cf6d71e096eb62851503fc04266d1e32895b...848f360fe1bcbdac28e9cc0014665bf8ccbfd259 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 14:55:24 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 10:55:24 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660c1c5c33da_2bcef239a8dc2789@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 9d80352f by Rodrigo Mesquita at 2024-04-02T15:54:58+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 96fb179d by Rodrigo Mesquita at 2024-04-02T15:54:58+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,58 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent) +{ +#if !defined(DEBUG) + UNUSED(dll_name); +#endif + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ + + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } - sym = GetProcAddress(o_dll->instance, lbl); + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/896de9ca275c52bff530aafd343ceb246866d2f5...96fb179d5fd008bdf4a1ef87a2e49a6e35452ccf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/896de9ca275c52bff530aafd343ceb246866d2f5...96fb179d5fd008bdf4a1ef87a2e49a6e35452ccf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 14:56:36 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 10:56:36 -0400 Subject: [Git][ghc/ghc][wip/mco-in-exprIsConApp] Try using MCoercion in exprIsConApp_maybe Message-ID: <660c1ca4acb52_2bcef24282182834e@gitlab.mail> Simon Peyton Jones pushed to branch wip/mco-in-exprIsConApp at Glasgow Haskell Compiler / GHC Commits: 6d6e9d57 by Simon Peyton Jones at 2024-04-02T15:56:27+01:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 2 changed files: - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/SimpleOpt.hs Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -3023,7 +3023,7 @@ pushCoercionIntoLambda in_scope x e co | otherwise = Nothing -pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion +pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion -> Maybe (DataCon , [Type] -- Universal type args , [CoreExpr]) -- All other args incl existentials @@ -3033,10 +3033,20 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion -- where co :: (T t1 .. tn) ~ to_ty -- The left-hand one must be a T, because exprIsConApp returned True -- but the right-hand one might not be. (Though it usually will.) -pushCoDataCon dc dc_args co - | isReflCo co || from_ty `eqType` to_ty -- try cheap test first - , let (univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args - = Just (dc, map exprToType univ_ty_args, rest_args) +pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args) +pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co) + +push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr]) +push_dc_refl dc dc_args + = (dc, map exprToType univ_ty_args, rest_args) + where + !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args + +push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type + -> Maybe (DataCon, [Type], [CoreExpr]) +push_dc_gen dc dc_args co (Pair from_ty to_ty) + | from_ty `eqType` to_ty -- try cheap test first + = Just $! (push_dc_refl dc dc_args) | Just (to_tc, to_tc_arg_tys) <- splitTyConApp_maybe to_ty , to_tc == dataConTyCon dc @@ -3082,8 +3092,6 @@ pushCoDataCon dc dc_args co | otherwise = Nothing - where - Pair from_ty to_ty = coercionKind co collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr) -- Collect lambda binders, pushing coercions inside if possible ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1211,7 +1211,7 @@ data-con wrappers, and that cure would be worse than the disease. This Note exists solely to document the problem. -} -data ConCont = CC [CoreExpr] Coercion +data ConCont = CC [CoreExpr] MCoercion -- Substitution already applied -- | Returns @Just ([b1..bp], dc, [t1..tk], [x1..xn])@ if the argument @@ -1233,7 +1233,7 @@ exprIsConApp_maybe :: HasDebugCallStack => InScopeEnv -> CoreExpr -> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr]) exprIsConApp_maybe ise@(ISE in_scope id_unf) expr - = go (Left in_scope) [] expr (CC [] (mkRepReflCo (exprType expr))) + = go (Left in_scope) [] expr (CC [] MRefl) where go :: Either InScopeSet Subst -- Left in-scope means "empty substitution" @@ -1246,14 +1246,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr go subst floats (Tick t expr) cont | not (tickishIsCode t) = go subst floats expr cont - go subst floats (Cast expr co1) (CC args co2) + go subst floats (Cast expr co1) (CC args m_co2) | Just (args', m_co1') <- pushCoArgs (subst_co subst co1) args -- See Note [Push coercions in exprIsConApp_maybe] - = case m_co1' of - MCo co1' -> go subst floats expr (CC args' (co1' `mkTransCo` co2)) - MRefl -> go subst floats expr (CC args' co2) + = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2)) - go subst floats (App fun arg) (CC args co) + go subst floats (App fun arg) (CC args mco) | let arg_type = exprType arg , not (isTypeArg arg) && needsCaseBinding arg_type arg -- An unlifted argument that’s not ok for speculation must not simply be @@ -1276,17 +1274,17 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) float = FloatCase arg' bndr DEFAULT [] subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) co) + in go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise - = go subst floats fun (CC (subst_expr subst arg : args) co) + = go subst floats fun (CC (subst_expr subst arg : args) mco) - go subst floats (Lam bndr body) (CC (arg:args) co) + go subst floats (Lam bndr body) (CC (arg:args) mco) | do_beta_by_substitution bndr arg - = go (extend subst bndr arg) floats body (CC args co) + = go (extend subst bndr arg) floats body (CC args mco) | otherwise = let (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' arg) - in go subst' (float:floats) body (CC args co) + in go subst' (float:floats) body (CC args mco) go subst floats (Let (NonRec bndr rhs) expr) cont | not (isJoinId bndr) @@ -1311,12 +1309,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr (lookupIdSubst sub v) cont - go (Left in_scope) floats (Var fun) cont@(CC args co) + go (Left in_scope) floats (Var fun) cont@(CC args mco) | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun = succeedWith in_scope floats $ - pushCoDataCon con args co + pushCoDataCon con args mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1336,7 +1334,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplOptExpr initialises the in-scope set with exprFreeVars, -- but that doesn't account for DFun unfoldings = succeedWith in_scope floats $ - pushCoDataCon con (map (substExpr subst) dfun_args) co + pushCoDataCon con (map (substExpr subst) dfun_args) mco -- Look through unfoldings, but only arity-zero one; -- if arity > 0 we are effectively inlining a function call, @@ -1354,7 +1352,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr , [arg] <- args , Just (LitString str) <- exprIsLiteral_maybe ise arg = succeedWith in_scope floats $ - dealWithStringLiteral fun str co + dealWithStringLiteral fun str mco where unfolding = id_unf fun extend_in_scope unf_fvs @@ -1404,15 +1402,15 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- See Note [exprIsConApp_maybe on literal strings] -dealWithStringLiteral :: Var -> BS.ByteString -> Coercion +dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion -> Maybe (DataCon, [Type], [CoreExpr]) -- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS -- turns those into [] automatically, but just in case something else in GHC -- generates a string literal directly. -dealWithStringLiteral fun str co = +dealWithStringLiteral fun str mco = case utf8UnconsByteString str of - Nothing -> pushCoDataCon nilDataCon [Type charTy] co + Nothing -> pushCoDataCon nilDataCon [Type charTy] mco Just (char, charTail) -> let char_expr = mkConApp charDataCon [mkCharLit char] -- In singleton strings, just add [] instead of unpackCstring# ""#. @@ -1421,7 +1419,7 @@ dealWithStringLiteral fun str co = else App (Var fun) (Lit (LitString charTail)) - in pushCoDataCon consDataCon [Type charTy, char_expr, rest] co + in pushCoDataCon consDataCon [Type charTy, char_expr, rest] mco {- Note [Unfolding DFuns] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d6e9d570898331805b63620b8241ff8970fcf0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d6e9d570898331805b63620b8241ff8970fcf0a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:19:49 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 11:19:49 -0400 Subject: [Git][ghc/ghc][wip/T24604] Deal with duplicate tyvars in type declarations Message-ID: <660c2215e01fd_2bcef28ca1f4403c2@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24604 at Glasgow Haskell Compiler / GHC Commits: f004fd56 by Simon Peyton Jones at 2024-04-02T16:19:31+01:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - 9 changed files: - compiler/GHC/Tc/Gen/HsType.hs - testsuite/tests/saks/should_compile/all.T - + testsuite/tests/saks/should_compile/saks018.stderr - + testsuite/tests/saks/should_compile/saks021.stderr - testsuite/tests/typecheck/should_compile/T24470b.hs - testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2573,7 +2573,7 @@ kcCheckDeclHeader_sig sig_kind name flav , text "implict_nms:" <+> ppr implicit_nms , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2622,11 +2622,10 @@ kcCheckDeclHeader_sig sig_kind name flav -- type UF :: forall zk -> zk -> Constraint -- class UF kk (xb :: k) -- Here `k` and `kk` both denote the same variable; but only `k` is implicit - -- Hence we need to add the visible binders into dup_chk_prs + -- Hence we need to add skol_scoped_tvs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - dup_chk_prs = implicit_prs ++ - [ (tyVarName tv, tv) | Bndr tv vis <- skol_tcbs, isVisibleTcbVis vis ] + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs ; unless (null implicit_nms) $ -- No need if no implicit tyvars checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs @@ -2697,6 +2696,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Skolem tyvars brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2707,7 +2707,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2724,18 +2724,21 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } + -- We do a tcExtendTyVarEnv [tv'], so we return tv' in + -- the list of lexically-scoped skolem type variables | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2755,9 +2758,13 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. @@ -3021,15 +3028,7 @@ checkForDisconnectedScopedTyVars name flav all_tcbs scoped_prs checkForDuplicateScopedTyVars :: [(Name,TcTyVar)] -> TcM () -- Check for duplicates --- E.g. data SameKind (a::k) (b::k) --- data T (a::k1) (b::k2) c = MkT (SameKind a b) c --- Here k1 and k2 start as TyVarTvs, and get unified with each other --- If this happens, things get very confused later, so fail fast --- --- In the CUSK case k1 and k2 are skolems so they won't unify; --- but in the inference case (see generaliseTcTyCon), --- and the type-sig case (see kcCheckDeclHeader_sig), they are --- TcTyVars, so we must check. +-- See Note [Aliasing in type and class declarations] checkForDuplicateScopedTyVars scoped_prs = unless (null err_prs) $ do { mapM_ report_dup err_prs; failM } @@ -3049,8 +3048,41 @@ checkForDuplicateScopedTyVars scoped_prs addErrTc $ TcRnDifferentNamesForTyVar n1 n2 -{- Note [Disconnected type variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Aliasing in type and class declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + data SameKind (a::k) (b::k) + data T1 (a::k1) (b::k2) c = MkT (SameKind a b) c +We do not allow this, because `k1` and `k2` would both stand for the same type +variable -- they are both aliases for `k`. + +Other examples + data T2 (a::k1) = MkT2 (SameKind a Int) -- k1 stands for Type + data T3 @k1 @k2 (a::k1) (b::k2) = MkT (SameKind a b) -- k1 and k2 are aliases + + type UF :: forall zk. zk -> Constraint + class UF @kk (xb :: k) where -- kk and k are aliases + op :: (xs::kk) -> Bool + +See #24604 for an example that crashed GHC. + +There is a design choice here. It would be possible to allow implicit type variables +like `k1` and `k2` in T1's declartion to stand for /abitrary kinds/. This is in fact +the rule we use in /terms/ pattern signatures: + f :: [Int] -> Int + f ((x::a) : xs) = ... +Here `a` stands for `Int`. But in type /signatures/ we make a different choice: + f1 :: forall (a::k1) (b::k2). SameKind a b -> blah + f2 :: forall (a::k). SameKind a Int -> blah + +Here f1's signature is rejected becaues `k1` and `k2` are aliased; and f2's is +rejected because `k` stands for `Int`. + +Our current choice is that type and class declarations behave more like signatures; +we do not allow aliasing. That is what `checkForDuplicateScopedTyVars` checks. + +Note [Disconnected type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This note applies when kind-checking the header of a type/class decl that has a separate, standalone kind signature. See #24083. ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -13,10 +13,10 @@ test('saks014', normal, compile, ['']) test('saks015', normal, compile, ['']) test('saks016', normal, compile, ['']) test('saks017', normal, compile, ['']) -test('saks018', normal, compile, ['']) +test('saks018', normal, compile_fail, ['']) test('saks019', normal, compile, ['']) test('saks020', normal, compile, ['']) -test('saks021', normal, compile, ['']) +test('saks021', normal, compile_fail, ['']) test('saks023', normal, ghci_script, ['saks023.script']) test('saks024', normal, compile, ['']) test('saks025', extra_files(['saks025.hs']), ghci_script, ['saks025.script']) ===================================== testsuite/tests/saks/should_compile/saks018.stderr ===================================== @@ -0,0 +1,4 @@ + +saks018.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/saks/should_compile/saks021.stderr ===================================== @@ -0,0 +1,4 @@ + +saks021.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_compile/T24470b.hs ===================================== @@ -7,4 +7,4 @@ import Data.Kind import Data.Data type SynOK :: forall k. k -> Type -type SynOK @t = Proxy :: j -> Type +type SynOK @j = Proxy :: j -> Type ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -1,6 +1,6 @@ module T24604 where -import Data.Kind (Constraint, Type) +import Data.Kind type UF :: forall zk -> zk -> Constraint class UF kk (xb :: k) where ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -19,3 +19,4 @@ test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) test('T23739_fail_case', normal, compile_fail, ['']) test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f004fd56dd5483f85527b5801a3fbdc5a5aac0a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f004fd56dd5483f85527b5801a3fbdc5a5aac0a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:20:25 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 11:20:25 -0400 Subject: [Git][ghc/ghc][wip/T24604] Deal with duplicate tyvars in type declarations Message-ID: <660c223950c09_2bcef297d7b8423df@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24604 at Glasgow Haskell Compiler / GHC Commits: 60ad6eb6 by Simon Peyton Jones at 2024-04-02T16:20:01+01:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - 9 changed files: - compiler/GHC/Tc/Gen/HsType.hs - testsuite/tests/saks/should_compile/all.T - + testsuite/tests/saks/should_compile/saks018.stderr - + testsuite/tests/saks/should_compile/saks021.stderr - testsuite/tests/typecheck/should_compile/T24470b.hs - testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2573,7 +2573,7 @@ kcCheckDeclHeader_sig sig_kind name flav , text "implict_nms:" <+> ppr implicit_nms , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2622,11 +2622,10 @@ kcCheckDeclHeader_sig sig_kind name flav -- type UF :: forall zk -> zk -> Constraint -- class UF kk (xb :: k) -- Here `k` and `kk` both denote the same variable; but only `k` is implicit - -- Hence we need to add the visible binders into dup_chk_prs + -- Hence we need to add skol_scoped_tvs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - dup_chk_prs = implicit_prs ++ - [ (tyVarName tv, tv) | Bndr tv vis <- skol_tcbs, isVisibleTcbVis vis ] + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs ; unless (null implicit_nms) $ -- No need if no implicit tyvars checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs @@ -2697,6 +2696,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Skolem tyvars brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2707,7 +2707,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2724,18 +2724,21 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } + -- We do a tcExtendTyVarEnv [tv'], so we return tv' in + -- the list of lexically-scoped skolem type variables | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2755,9 +2758,13 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. @@ -3021,15 +3028,7 @@ checkForDisconnectedScopedTyVars name flav all_tcbs scoped_prs checkForDuplicateScopedTyVars :: [(Name,TcTyVar)] -> TcM () -- Check for duplicates --- E.g. data SameKind (a::k) (b::k) --- data T (a::k1) (b::k2) c = MkT (SameKind a b) c --- Here k1 and k2 start as TyVarTvs, and get unified with each other --- If this happens, things get very confused later, so fail fast --- --- In the CUSK case k1 and k2 are skolems so they won't unify; --- but in the inference case (see generaliseTcTyCon), --- and the type-sig case (see kcCheckDeclHeader_sig), they are --- TcTyVars, so we must check. +-- See Note [Aliasing in type and class declarations] checkForDuplicateScopedTyVars scoped_prs = unless (null err_prs) $ do { mapM_ report_dup err_prs; failM } @@ -3049,8 +3048,41 @@ checkForDuplicateScopedTyVars scoped_prs addErrTc $ TcRnDifferentNamesForTyVar n1 n2 -{- Note [Disconnected type variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Aliasing in type and class declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + data SameKind (a::k) (b::k) + data T1 (a::k1) (b::k2) c = MkT (SameKind a b) c +We do not allow this, because `k1` and `k2` would both stand for the same type +variable -- they are both aliases for `k`. + +Other examples + data T2 (a::k1) = MkT2 (SameKind a Int) -- k1 stands for Type + data T3 @k1 @k2 (a::k1) (b::k2) = MkT (SameKind a b) -- k1 and k2 are aliases + + type UF :: forall zk. zk -> Constraint + class UF @kk (xb :: k) where -- kk and k are aliases + op :: (xs::kk) -> Bool + +See #24604 for an example that crashed GHC. + +There is a design choice here. It would be possible to allow implicit type variables +like `k1` and `k2` in T1's declartion to stand for /abitrary kinds/. This is in fact +the rule we use in /terms/ pattern signatures: + f :: [Int] -> Int + f ((x::a) : xs) = ... +Here `a` stands for `Int`. But in type /signatures/ we make a different choice: + f1 :: forall (a::k1) (b::k2). SameKind a b -> blah + f2 :: forall (a::k). SameKind a Int -> blah + +Here f1's signature is rejected because `k1` and `k2` are aliased; and f2's is +rejected because `k` stands for `Int`. + +Our current choice is that type and class declarations behave more like signatures; +we do not allow aliasing. That is what `checkForDuplicateScopedTyVars` checks. + +Note [Disconnected type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This note applies when kind-checking the header of a type/class decl that has a separate, standalone kind signature. See #24083. ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -13,10 +13,10 @@ test('saks014', normal, compile, ['']) test('saks015', normal, compile, ['']) test('saks016', normal, compile, ['']) test('saks017', normal, compile, ['']) -test('saks018', normal, compile, ['']) +test('saks018', normal, compile_fail, ['']) test('saks019', normal, compile, ['']) test('saks020', normal, compile, ['']) -test('saks021', normal, compile, ['']) +test('saks021', normal, compile_fail, ['']) test('saks023', normal, ghci_script, ['saks023.script']) test('saks024', normal, compile, ['']) test('saks025', extra_files(['saks025.hs']), ghci_script, ['saks025.script']) ===================================== testsuite/tests/saks/should_compile/saks018.stderr ===================================== @@ -0,0 +1,4 @@ + +saks018.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/saks/should_compile/saks021.stderr ===================================== @@ -0,0 +1,4 @@ + +saks021.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_compile/T24470b.hs ===================================== @@ -7,4 +7,4 @@ import Data.Kind import Data.Data type SynOK :: forall k. k -> Type -type SynOK @t = Proxy :: j -> Type +type SynOK @j = Proxy :: j -> Type ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -1,6 +1,6 @@ module T24604 where -import Data.Kind (Constraint, Type) +import Data.Kind type UF :: forall zk -> zk -> Constraint class UF kk (xb :: k) where ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -19,3 +19,4 @@ test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) test('T23739_fail_case', normal, compile_fail, ['']) test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/60ad6eb6b45a126f4c8f47173db40bed50ccba92 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/60ad6eb6b45a126f4c8f47173db40bed50ccba92 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:27:44 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 11:27:44 -0400 Subject: [Git][ghc/ghc][wip/fendor/fix-thunks-name-and-ui] 2 commits: Force in_multi to avoid retaining entire hsc_env Message-ID: <660c23f06617e_2bcef2a9804444720@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/fix-thunks-name-and-ui at Glasgow Haskell Compiler / GHC Commits: 5bdc5139 by Matthew Pickering at 2024-04-02T17:27:36+02:00 Force in_multi to avoid retaining entire hsc_env - - - - - b50ffd30 by Fendor at 2024-04-02T17:27:36+02:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. - - - - - 2 changed files: - compiler/GHC/IfaceToCore.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,7 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the ===================================== ghc/GHCi/UI.hs ===================================== @@ -557,7 +557,8 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34efd458aa5f7c42dc8608333d01d03900241fae...b50ffd3028952591290dd104c73dfda50756df4a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34efd458aa5f7c42dc8608333d01d03900241fae...b50ffd3028952591290dd104c73dfda50756df4a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:28:44 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 02 Apr 2024 11:28:44 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <660c242cd009_2bcef2ba02fc46866@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 53e282ec by David Knothe at 2024-04-02T17:28:35+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53e282ec25ee368c0e50fa2fc4a5bf97e1d365df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53e282ec25ee368c0e50fa2fc4a5bf97e1d365df You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:31:29 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 02 Apr 2024 11:31:29 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <660c24d16c124_2bcef2caf32849480@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: d7c4ba3f by David Knothe at 2024-04-02T17:31:24+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7c4ba3f80dd739213e5ceb814e7a59965738414 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7c4ba3f80dd739213e5ceb814e7a59965738414 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:33:13 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 02 Apr 2024 11:33:13 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660c25394a76d_2bcef2dcd35454081@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: ecc6d2a7 by Fendor at 2024-04-02T17:32:55+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 16 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,19 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , unsafeDecodeUtf + , unsafeEncodeUtf + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import System.OsPath +import Data.Either + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsPath -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,9 +455,9 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. @@ -488,14 +490,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +505,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +514,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +545,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +583,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> OsPath -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +602,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +675,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +728,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,7 @@ where import GHC.Prelude import GHC.Unit +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -16,6 +17,7 @@ import GHC.Platform.Ways import Data.IORef import GHC.Data.FastString import qualified Data.Set as Set +import System.OsPath (OsPath) -- | The 'FinderCache' maps modules to the result of -- searching for that module. It records the results of searching for @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsPath + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsPath + , finder_dynHiSuf :: OsPath + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsPath + , finder_dynObjectSuf :: OsPath + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,13 +7,24 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude + +import GHC.Data.OsPath +import qualified GHC.Data.Strict as Strict import GHC.Unit.Types import GHC.Utils.Outputable +import System.OsPath + -- | Module Location -- -- Where a module lives on the file system: the actual locations @@ -39,30 +50,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +82,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +93,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +106,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- + +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecc6d2a7c69f99e28e39145fd75b4b099008c68c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecc6d2a7c69f99e28e39145fd75b4b099008c68c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:42:27 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 11:42:27 -0400 Subject: [Git][ghc/ghc][wip/T24604] 3 commits: EPA: Extend StringLiteral range to include trailing commas Message-ID: <660c2763de1be_f9dac32443275@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24604 at Glasgow Haskell Compiler / GHC Commits: 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - 91bb3ee0 by Simon Peyton Jones at 2024-04-02T16:42:00+01:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - 17 changed files: - compiler/GHC/Parser.y - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/HsType.hs - testsuite/tests/saks/should_compile/saks018.hs - testsuite/tests/saks/should_compile/saks021.hs - testsuite/tests/saks/should_fail/all.T - + testsuite/tests/saks/should_fail/saks018-fail.hs - + testsuite/tests/saks/should_fail/saks018-fail.stderr - + testsuite/tests/saks/should_fail/saks021-fail.hs - + testsuite/tests/saks/should_fail/saks021-fail.stderr - testsuite/tests/typecheck/should_compile/T24470b.hs - + testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604.stderr - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -4559,7 +4559,8 @@ addTrailingCommaN (L anns a) span = do return (L anns' a) addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral -addTrailingCommaS (L l sl) span = L l (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) +addTrailingCommaS (L l sl) span + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) -- ------------------------------------- ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -63,7 +63,22 @@ underlying program (the C compiler), the set of flags passed determines the behaviour of the preprocessor, and Cpp and HsCpp behave differently. Specifically, we rely on "traditional" (pre-standard) preprocessing semantics (which most compilers expose via the `-traditional` flag) when preprocessing -Haskell source. This avoids, e.g., the preprocessor removing C-style comments. +Haskell source. This avoids the following situations: + + * Removal of C-style comments, which are not comments in Haskell but valid + operators; + + * Errors due to an ANSI C preprocessor lexing the source and failing on + names with single quotes (TH quotes, ticked promoted constructors, + names with primes in them). + + Both of those cases may be subtle: gcc and clang permit C++-style // + comments in C code, and Data.Array and Data.Vector both export a // + operator whose type is such that a removed "comment" may leave code that + typechecks but does the wrong thing. Another example is that, since ANSI + C permits long character constants, an expression involving multiple + functions with primes in their names may not expand macros properly when + they occur between the primed functions. -} -- | Run either the Haskell preprocessor or the C preprocessor, as per the ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2569,9 +2569,11 @@ kcCheckDeclHeader_sig sig_kind name flav ; traceTc "kcCheckDeclHeader_sig {" $ vcat [ text "sig_kind:" <+> ppr sig_kind , text "sig_tcbs:" <+> ppr sig_tcbs - , text "sig_res_kind:" <+> ppr sig_res_kind ] + , text "sig_res_kind:" <+> ppr sig_res_kind + , text "implict_nms:" <+> ppr implicit_nms + , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2614,9 +2616,18 @@ kcCheckDeclHeader_sig sig_kind name flav -- Here p and q both map to the same kind variable k. We don't allow this -- so we must check that they are distinct. A similar thing happens -- in GHC.Tc.TyCl.swizzleTcTyConBinders during inference. + -- + -- With visible dependent quantification, one of the binders involved + -- may be explicit. Consider #24604 + -- type UF :: forall zk -> zk -> Constraint + -- class UF kk (xb :: k) + -- Here `k` and `kk` both denote the same variable; but only `k` is implicit + -- Hence we need to add skol_scoped_tvs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - ; checkForDuplicateScopedTyVars implicit_prs + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs + ; unless (null implicit_nms) $ -- No need if no implicit tyvars + checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs -- Swizzle the Names so that the TyCon uses the user-declared implicit names @@ -2685,6 +2696,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Skolem tyvars brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2695,7 +2707,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2711,17 +2723,22 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- that come from the type declaration, not the kind signature subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } + -- We do a tcExtendTyVarEnv [tv'], so we return tv' in + -- the list of lexically-scoped skolem type variables | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2735,14 +2752,19 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside = return () tc_hs_bndr (KindedTyVar _ _ (L _ hs_nm) lhs_kind) expected_kind = do { sig_kind <- tcLHsKindSig (TyVarBndrKindCtxt hs_nm) lhs_kind + ; traceTc "musd3:unifying" (ppr sig_kind $$ ppr expected_kind) ; discardResult $ -- See Note [discardResult in kcCheckDeclHeader_sig] unifyKind (Just (NameThing hs_nm)) sig_kind expected_kind } -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. @@ -3006,15 +3028,7 @@ checkForDisconnectedScopedTyVars name flav all_tcbs scoped_prs checkForDuplicateScopedTyVars :: [(Name,TcTyVar)] -> TcM () -- Check for duplicates --- E.g. data SameKind (a::k) (b::k) --- data T (a::k1) (b::k2) c = MkT (SameKind a b) c --- Here k1 and k2 start as TyVarTvs, and get unified with each other --- If this happens, things get very confused later, so fail fast --- --- In the CUSK case k1 and k2 are skolems so they won't unify; --- but in the inference case (see generaliseTcTyCon), --- and the type-sig case (see kcCheckDeclHeader_sig), they are --- TcTyVars, so we must check. +-- See Note [Aliasing in type and class declarations] checkForDuplicateScopedTyVars scoped_prs = unless (null err_prs) $ do { mapM_ report_dup err_prs; failM } @@ -3034,8 +3048,43 @@ checkForDuplicateScopedTyVars scoped_prs addErrTc $ TcRnDifferentNamesForTyVar n1 n2 -{- Note [Disconnected type variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Aliasing in type and class declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + data SameKind (a::k) (b::k) + data T1 (a::k1) (b::k2) c = MkT (SameKind a b) c +We do not allow this, because `k1` and `k2` would both stand for the same type +variable -- they are both aliases for `k`. + +Other examples + data T2 (a::k1) = MkT2 (SameKind a Int) -- k1 stands for Type + data T3 @k1 @k2 (a::k1) (b::k2) = MkT (SameKind a b) -- k1 and k2 are aliases + + type UF :: forall zk. zk -> Constraint + class UF @kk (xb :: k) where -- kk and k are aliases + op :: (xs::kk) -> Bool + +See #24604 for an example that crashed GHC. + +There is a design choice here. It would be possible to allow implicit type variables +like `k1` and `k2` in T1's declartion to stand for /abitrary kinds/. This is in fact +the rule we use in /terms/ pattern signatures: + f :: [Int] -> Int + f ((x::a) : xs) = ... +Here `a` stands for `Int`. But in type /signatures/ we make a different choice: + f1 :: forall (a::k1) (b::k2). SameKind a b -> blah + f2 :: forall (a::k). SameKind a Int -> blah + +Here f1's signature is rejected because `k1` and `k2` are aliased; and f2's is +rejected because `k` stands for `Int`. + +Our current choice is that type and class declarations behave more like signatures; +we do not allow aliasing. That is what `checkForDuplicateScopedTyVars` checks. +See !12328 for some design discussion. + + +Note [Disconnected type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This note applies when kind-checking the header of a type/class decl that has a separate, standalone kind signature. See #24083. ===================================== testsuite/tests/saks/should_compile/saks018.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_018 where import Data.Kind (Type) type T :: forall k -> k -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_compile/saks021.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_021 where import Data.Kind (Type) type T :: forall k -> forall (xx :: k) -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -36,3 +36,5 @@ test('T18863b', normal, compile_fail, ['']) test('T18863c', normal, compile_fail, ['']) test('T18863d', normal, compile_fail, ['']) test('T20916', normal, compile_fail, ['']) +test('saks018-fail', normal, compile_fail, ['']) +test('saks021-fail', normal, compile_fail, ['']) ===================================== testsuite/tests/saks/should_fail/saks018-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_018 where + +import Data.Kind (Type) + +type T :: forall k -> k -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks018-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks018-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/saks/should_fail/saks021-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_021 where + +import Data.Kind (Type) + +type T :: forall k -> forall (xx :: k) -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks021-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks021-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_compile/T24470b.hs ===================================== @@ -7,4 +7,4 @@ import Data.Kind import Data.Data type SynOK :: forall k. k -> Type -type SynOK @t = Proxy :: j -> Type +type SynOK @j = Proxy :: j -> Type ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -0,0 +1,7 @@ +module T24604 where + +import Data.Kind + +type UF :: forall zk -> zk -> Constraint +class UF kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604.hs:6:10: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -17,4 +17,6 @@ test('T23738_fail_implicit_tv', normal, compile_fail, ['']) test('T23738_fail_var', normal, compile_fail, ['']) test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) -test('T23739_fail_case', normal, compile_fail, ['']) \ No newline at end of file +test('T23739_fail_case', normal, compile_fail, ['']) +test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -652,6 +652,10 @@ printSourceText :: (Monad m, Monoid w) => SourceText -> String -> EP w m () printSourceText (NoSourceText) txt = printStringAdvance txt >> return () printSourceText (SourceText txt) _ = printStringAdvance (unpackFS txt) >> return () +printSourceTextAA :: (Monad m, Monoid w) => SourceText -> String -> EP w m () +printSourceTextAA (NoSourceText) txt = printStringAtAA (EpaDelta (SameLine 0) []) txt >> return () +printSourceTextAA (SourceText txt) _ = printStringAtAA (EpaDelta (SameLine 0) []) (unpackFS txt) >> return () + -- --------------------------------------------------------------------- printStringAtSs :: (Monad m, Monoid w) => SrcSpan -> String -> EP w m () @@ -2099,7 +2103,7 @@ instance ExactPrint StringLiteral where setAnnotationAnchor a _ _ _ = a exact l@(StringLiteral src fs mcomma) = do - printSourceText src (show (unpackFS fs)) + printSourceTextAA src (show (unpackFS fs)) mapM_ (\r -> printStringAtRs r ",") mcomma return l View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/60ad6eb6b45a126f4c8f47173db40bed50ccba92...91bb3ee04fd6fa37a0e6b8c8a0771a3640fd7f6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/60ad6eb6b45a126f4c8f47173db40bed50ccba92...91bb3ee04fd6fa37a0e6b8c8a0771a3640fd7f6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:49:00 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 11:49:00 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660c28ecdbea0_f9da28a4c41331a@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 8a604085 by Rodrigo Mesquita at 2024-04-02T16:48:48+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 051ad35c by Rodrigo Mesquita at 2024-04-02T16:48:48+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -643,7 +643,13 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; @@ -652,7 +658,6 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96fb179d5fd008bdf4a1ef87a2e49a6e35452ccf...051ad35c2a4a9e855892038e4d22f36f83842440 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96fb179d5fd008bdf4a1ef87a2e49a6e35452ccf...051ad35c2a4a9e855892038e4d22f36f83842440 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 15:59:41 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 02 Apr 2024 11:59:41 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660c2b6dae46f_f9da459df4174bc@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: c5858977 by Rodrigo Mesquita at 2024-04-02T16:59:11+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 206adda7 by Rodrigo Mesquita at 2024-04-02T16:59:11+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 2befe7f0 by Rodrigo Mesquita at 2024-04-02T16:59:11+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 18 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/ObjLink.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -74,7 +74,7 @@ lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) lookupSymbolInDLL dll str_in = do let str = prefixUnderscore str_in withCAString str $ \c_str -> do - addr <- c_lookupSymbolInDLL dll c_str + addr <- c_lookupSymbolInNativeObj dll c_str if addr == nullPtr then return Nothing else return (Just addr) @@ -112,7 +112,7 @@ loadDLL str0 = do -- (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> alloca $ \errmsg_ptr -> (,) - <$> c_addDLL dll errmsg_ptr + <$> c_loadNativeObj dll errmsg_ptr <*> peek errmsg_ptr if maybe_handle == nullPtr @@ -176,8 +176,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) -foreign import ccall unsafe "lookupSymbolInDLL" c_lookupSymbolInDLL :: Ptr LoadedDLL -> CString -> IO (Ptr a) +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInNativeObj) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,87 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static void * -internal_dlopen(const char *dll_name, const char **errmsg_ptr) -{ - OpenedSO* o_so; - void *hdl; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - char *errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - char *errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - *errmsg_ptr = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return hdl; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -657,11 +571,10 @@ internal_dlopen(const char *dll_name, const char **errmsg_ptr) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -669,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -722,98 +634,37 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif -void *lookupSymbolInDLL(void *handle, const char *symbol_name) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ACQUIRE_LOCK(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif + + RELEASE_LOCK(&linker_mutex); return result; } -# endif -void *addDLL(pathchar* dll_name, const char **errmsg_ptr) +const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - void *handle; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - handle = internal_dlopen(dll_name, &errmsg); - - if (handle != NULL) { - return handle; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - *errmsg_ptr = errmsg; // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - handle = internal_dlopen(line+match[2].rm_so, errmsg_ptr); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return handle; - -# elif defined(OBJFORMAT_PEi386) - // FIXME - return addDLL_PEi386(dll_name, NULL); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1240,10 +1091,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1908,12 +1759,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -2000,25 +1859,33 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); - RELEASE_LOCK(&linker_mutex); - return r; -} + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); #else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); barf("loadNativeObj: not implemented on this platform"); -} #endif -HsInt unloadNativeObj (void *handle) +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + + RELEASE_LOCK(&linker_mutex); + return r; +} + +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2051,11 +1918,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -619,7 +619,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ - SymI_HasProto(lookupSymbolInDLL) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,10 +90,10 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); -/* load a dynamic library */ -void *addDLL(pathchar* dll_name, const char **errmsg); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); -void *lookupSymbolInDLL(void *handle, const char *symbol_name); +/* load a dynamic library */ +const char *addDLL(pathchar* dll_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,214 @@ +#include "LinkerInternals.h" +#include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + +#endif /* elf + macho */ ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -1141,47 +1141,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/051ad35c2a4a9e855892038e4d22f36f83842440...2befe7f0d625968b12c2e2637b3731cdeb2d1234 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/051ad35c2a4a9e855892038e4d22f36f83842440...2befe7f0d625968b12c2e2637b3731cdeb2d1234 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 16:51:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 12:51:06 -0400 Subject: [Git][ghc/ghc][master] 5 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660c377a18c98_f9dab30970313e3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - 8 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - rts/TSANUtils.c - rts/include/Cmm.h - rts/include/rts/TSANUtils.h - rts/include/stg/SMP.h - rts/rts.cabal Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -339,7 +339,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f flavour_string Llvm = "llvm" flavour_string Dwarf = "debug_info" flavour_string FullyStatic = "fully_static" - flavour_string ThreadSanitiser = "thread_sanitizer" + flavour_string ThreadSanitiser = "thread_sanitizer_cmm" flavour_string NoSplitSections = "no_split_sections" flavour_string BootNonmovingGc = "boot_nonmoving_gc" @@ -969,9 +969,9 @@ job_groups = , validateBuilds Amd64 (Linux Debian10) nativeInt , validateBuilds Amd64 (Linux Debian10) unreg , fastCI (validateBuilds Amd64 (Linux Debian10) debug) - , -- Nightly allowed to fail: #22520 + , -- More work is needed to address TSAN failures: #22520 modifyNightlyJobs allowFailure - (modifyValidateJobs manual tsan_jobs) + (modifyValidateJobs (allowFailure . manual) tsan_jobs) , -- Nightly allowed to fail: #22343 modifyNightlyJobs allowFailure (modifyValidateJobs manual (validateBuilds Amd64 (Linux Debian10) noTntc)) @@ -1039,7 +1039,7 @@ job_groups = -- Haddock is large enough to make TSAN choke without massive quantities of -- memory. . addVariable "HADRIAN_ARGS" "--docs=none") $ - validateBuilds Amd64 (Linux Debian10) tsan + validateBuilds Amd64 (Linux Debian12) tsan make_wasm_jobs cfg = modifyJobs @@ -1083,6 +1083,7 @@ platform_mapping = Map.map go combined_result , "nightly-x86_64-linux-deb11-validate" , "nightly-x86_64-linux-deb12-validate" , "x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static" + , "x86_64-linux-deb12-validate+thread_sanitizer_cmm" , "nightly-aarch64-linux-deb10-validate" , "nightly-x86_64-linux-alpine3_12-validate" , "nightly-x86_64-linux-deb10-validate" ===================================== .gitlab/jobs.yaml ===================================== @@ -1644,18 +1644,18 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb10-validate+thread_sanitizer": { + "nightly-x86_64-linux-deb10-zstd-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": true, + "allow_failure": false, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb10-validate+thread_sanitizer.tar.xz", + "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1698,17 +1698,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+thread_sanitizer", - "BUILD_FLAVOUR": "validate+thread_sanitizer", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "HADRIAN_ARGS": "--docs=none", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-validate+thread_sanitizer", - "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions", + "TEST_ENV": "x86_64-linux-deb10-zstd-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb10-zstd-validate": { + "nightly-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1719,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", + "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1729,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb10-$CACHE_REV", + "key": "x86_64-linux-deb11-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1762,15 +1760,17 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", + "CROSS_TARGET": "aarch64-linux-gnu", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-zstd-validate", + "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { + "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1781,7 +1781,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1823,18 +1823,19 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", - "CROSS_TARGET": "aarch64-linux-gnu", + "CONFIGURE_WRAPPER": "emconfigure", + "CROSS_EMULATOR": "js-emulator", + "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1845,7 +1846,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1887,19 +1888,16 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CONFIGURE_WRAPPER": "emconfigure", - "CROSS_EMULATOR": "js-emulator", - "CROSS_TARGET": "javascript-unknown-ghcjs", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-validate": { + "nightly-x86_64-linux-deb11-validate+boot_nonmoving_gc": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1910,7 +1908,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1953,15 +1951,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate", - "BUILD_FLAVOUR": "validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", + "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-validate", + "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", + "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-validate+boot_nonmoving_gc": { + "nightly-x86_64-linux-deb12-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1972,7 +1970,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", + "ghc-x86_64-linux-deb12-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1982,14 +1980,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb12-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -2015,15 +2013,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", - "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate", + "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", - "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc", + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-deb12-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb12-validate": { + "nightly-x86_64-linux-deb12-validate+llvm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -2034,7 +2032,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate.tar.xz", + "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2077,26 +2075,26 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate", - "BUILD_FLAVOUR": "validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate", + "TEST_ENV": "x86_64-linux-deb12-validate+llvm", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb12-validate+llvm": { + "nightly-x86_64-linux-deb12-validate+thread_sanitizer_cmm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": false, + "allow_failure": true, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", + "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2139,11 +2137,13 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", - "BUILD_FLAVOUR": "validate+llvm", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "BUILD_FLAVOUR": "validate+thread_sanitizer_cmm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate+llvm", + "TEST_ENV": "x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions", "XZ_OPT": "-9" } }, @@ -5090,7 +5090,7 @@ "TEST_ENV": "x86_64-linux-deb10-validate+debug_info" } }, - "x86_64-linux-deb10-validate+thread_sanitizer": { + "x86_64-linux-deb10-zstd-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5101,7 +5101,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb10-validate+thread_sanitizer.tar.xz", + "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5127,9 +5127,8 @@ ], "rules": [ { - "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "manual" + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" } ], "script": [ @@ -5145,16 +5144,14 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+thread_sanitizer", - "BUILD_FLAVOUR": "validate+thread_sanitizer", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "HADRIAN_ARGS": "--docs=none", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-validate+thread_sanitizer", - "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions" + "TEST_ENV": "x86_64-linux-deb10-zstd-validate" } }, - "x86_64-linux-deb10-zstd-validate": { + "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5165,7 +5162,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb10-zstd-validate.tar.xz", + "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5175,14 +5172,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb10-$CACHE_REV", + "key": "x86_64-linux-deb11-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5191,7 +5188,7 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5208,14 +5205,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-zstd-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--enable-ipe-data-compression --enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", + "CROSS_TARGET": "aarch64-linux-gnu", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb10-zstd-validate" + "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { + "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5226,7 +5225,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5252,7 +5251,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*javascript.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5268,17 +5267,18 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu", - "CROSS_TARGET": "aarch64-linux-gnu", + "CONFIGURE_WRAPPER": "emconfigure", + "CROSS_EMULATOR": "js-emulator", + "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" + "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-validate+boot_nonmoving_gc": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5289,7 +5289,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5315,7 +5315,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*javascript.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*non-moving GC.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5331,18 +5331,15 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", - "BUILD_FLAVOUR": "validate", - "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", - "CONFIGURE_WRAPPER": "emconfigure", - "CROSS_EMULATOR": "js-emulator", - "CROSS_TARGET": "javascript-unknown-ghcjs", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", + "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", + "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc" } }, - "x86_64-linux-deb11-validate+boot_nonmoving_gc": { + "x86_64-linux-deb12-validate+llvm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5353,7 +5350,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc.tar.xz", + "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5363,14 +5360,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb12-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5379,7 +5376,7 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*non-moving GC.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -5396,25 +5393,25 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-validate+boot_nonmoving_gc", - "BUILD_FLAVOUR": "validate+boot_nonmoving_gc", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", + "BUILD_FLAVOUR": "validate+llvm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", - "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", - "TEST_ENV": "x86_64-linux-deb11-validate+boot_nonmoving_gc" + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-deb12-validate+llvm" } }, - "x86_64-linux-deb12-validate+llvm": { + "x86_64-linux-deb12-validate+thread_sanitizer_cmm": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": false, + "allow_failure": true, "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb12-validate+llvm.tar.xz", + "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5440,8 +5437,9 @@ ], "rules": [ { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "on_success" + "allow_failure": true, + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "manual" } ], "script": [ @@ -5457,11 +5455,13 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+llvm", - "BUILD_FLAVOUR": "validate+llvm", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "BUILD_FLAVOUR": "validate+thread_sanitizer_cmm", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb12-validate+llvm" + "TEST_ENV": "x86_64-linux-deb12-validate+thread_sanitizer_cmm", + "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions" } }, "x86_64-linux-fedora33-release": { ===================================== compiler/GHC/Cmm/ThreadSanitizer.hs ===================================== @@ -184,7 +184,7 @@ saveRestoreCallerRegs us platform = restore = blockFromList restore_nodes -- | Mirrors __tsan_memory_order --- +-- memoryOrderToTsanMemoryOrder :: Env -> MemoryOrdering -> CmmExpr memoryOrderToTsanMemoryOrder env mord = mkIntExpr (platform env) n @@ -294,4 +294,3 @@ tsanAtomicRMW env mord op w addr val dest = AMO_Or -> "fetch_or" AMO_Xor -> "fetch_xor" fn = fsLit $ "__tsan_atomic" ++ show (widthInBits w) ++ "_" ++ op' - ===================================== rts/TSANUtils.c ===================================== @@ -2,7 +2,7 @@ #if defined(TSAN_ENABLED) -uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder) { __tsan_atomic64_compare_exchange_strong( ptr, &expected, new_value, @@ -10,7 +10,7 @@ uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, ui return expected; } -uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder) { __tsan_atomic32_compare_exchange_strong( ptr, &expected, new_value, @@ -18,7 +18,7 @@ uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, ui return expected; } -uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder) { __tsan_atomic16_compare_exchange_strong( ptr, &expected, new_value, @@ -26,7 +26,7 @@ uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, ui return expected; } -uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder) +__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder) { __tsan_atomic8_compare_exchange_strong( ptr, &expected, new_value, ===================================== rts/include/Cmm.h ===================================== @@ -698,11 +698,11 @@ #define ACQUIRE_FENCE prim %fence_acquire(); #define SEQ_CST_FENCE prim %fence_seq_cst(); -#if TSAN_ENABLED +#if defined(TSAN_ENABLED) // This is may be efficient than a fence but TSAN can reason about it. -#if WORD_SIZE_IN_BITS == 64 +#if SIZEOF_W == 8 #define ACQUIRE_FENCE_ON(x) if (1) { W_ tmp; (tmp) = prim %load_acquire64(x); } -#elif WORD_SIZE_IN_BITS == 32 +#elif SIZEOF_W == 4 #define ACQUIRE_FENCE_ON(x) if (1) { W_ tmp; (tmp) = prim %load_acquire32(x); } #endif #else ===================================== rts/include/rts/TSANUtils.h ===================================== @@ -98,10 +98,18 @@ void AnnotateBenignRaceSized(const char *file, #define TSAN_ANNOTATE_BENIGN_RACE(addr,desc) \ TSAN_ANNOTATE_BENIGN_RACE_SIZED((void*)(addr), sizeof(*addr), desc) +#if defined(TSAN_ENABLED) && defined(__clang__) +#include +#else +typedef char __tsan_atomic8; +typedef short __tsan_atomic16; +typedef int __tsan_atomic32; +typedef long __tsan_atomic64; +#endif -uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder); -uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder); -uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder); -uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder); +__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder); +__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder); +__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder); +__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder); #endif ===================================== rts/include/stg/SMP.h ===================================== @@ -549,9 +549,14 @@ busy_wait_nop(void) #define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST) #if defined(TSAN_ENABLED) +#if !defined(__clang__) +#undef ACQUIRE_FENCE +#undef RELEASE_FENCE +#undef SEQ_CST_FENCE #define ACQUIRE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_ACQUIRE);) #define RELEASE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_RELEASE);) #define SEQ_CST_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_SEQ_CST);) +#endif #define ACQUIRE_FENCE_ON(x) (void)ACQUIRE_LOAD(x) #else #define ACQUIRE_FENCE_ON(x) __atomic_thread_fence(__ATOMIC_ACQUIRE) ===================================== rts/rts.cabal ===================================== @@ -184,7 +184,6 @@ library if flag(thread-sanitizer) cc-options: -fsanitize=thread ld-options: -fsanitize=thread - extra-libraries: tsan if os(linux) -- the RTS depends upon libc. while this dependency is generally View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/efab3649b685d92b1856a62532b343ef70777612...07cb627c8232f573bd6a8ea1b7c110ff3c1b5d22 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/efab3649b685d92b1856a62532b343ef70777612...07cb627c8232f573bd6a8ea1b7c110ff3c1b5d22 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 16:52:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 12:52:06 -0400 Subject: [Git][ghc/ghc][master] Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) Message-ID: <660c37b61ccc7_f9dad00d04361f9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 11 changed files: - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/partial-sigs/should_run/GHCiWildcardKind.stdout - + testsuite/tests/th/T24299.hs - + testsuite/tests/th/T24299.stderr - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Rename/Splice.hs ===================================== @@ -677,7 +677,7 @@ References: [2] 'rnSpliceExpr' [3] 'GHC.Tc.Gen.Splice.qAddModFinalizer' [4] 'GHC.Tc.Gen.Expr.tcExpr' ('HsSpliceE' ('HsSpliced' ...)) -[5] 'GHC.Tc.Gen.HsType.tc_hs_type' ('HsSpliceTy' ('HsSpliced' ...)) +[5] 'GHC.Tc.Gen.HsType.tcHsType' ('HsSpliceTy' ('HsSpliced' ...)) [6] 'GHC.Tc.Gen.Pat.tc_pat' ('SplicePat' ('HsSpliced' ...)) -} ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -1678,7 +1678,7 @@ tcRhs (TcPatBind infos pat' mult mult_ann grhss pat_ty) -- is generated so that multiplicity can be inferred. tcMultAnn :: HsMultAnn GhcRn -> TcM Mult tcMultAnn (HsPct1Ann _) = return oneDataConTy -tcMultAnn (HsMultAnn _ p) = tcCheckLHsType p (TheKind multiplicityTy) +tcMultAnn (HsMultAnn _ p) = tcCheckLHsTypeInContext p (TheKind multiplicityTy) tcMultAnn (HsNoMultAnn _) = newFlexiTyVarTy multiplicityTy tcExtendTyVarEnvForRhs :: Maybe TcIdSigInst -> TcM a -> TcM a ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsType, + tcCheckLHsTypeInContext, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -397,7 +397,7 @@ kcClassSigType names sig_ty@(L _ (HsSig { sig_bndrs = hs_outer_bndrs, sig_body = hs_ty })) = addSigCtxt (funsSigCtxt names) sig_ty $ do { _ <- bindOuterSigTKBndrs_Tv hs_outer_bndrs $ - tcLHsType hs_ty liftedTypeKind + tcCheckLHsType hs_ty liftedTypeKind ; return () } tcClassSigType :: [LocatedN Name] -> LHsSigType GhcRn -> TcM Type @@ -467,7 +467,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs do { exp_kind <- newExpectedKind ctxt_kind -- See Note [Escaping kind in type signatures] ; stuff <- tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcLHsType hs_ty exp_kind + tcCheckLHsType hs_ty exp_kind ; return (exp_kind, stuff) } -- Default any unconstrained variables free in the kind @@ -609,7 +609,7 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_lhs_type (mkMode tyki) body kind } + ; tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs @@ -704,7 +704,7 @@ tcHsTypeApp wc_ty kind -- We are looking at a user-written type, very like a -- signature so we want to solve its equalities right now bindNamedWildCardBinders sig_wcs $ \ _ -> - tc_lhs_type mode hs_ty kind + tc_check_lhs_type mode hs_ty kind -- We do not kind-generalize type applications: we just -- instantiate with exactly what the user says. @@ -720,7 +720,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole +tcHsTypeApp, tcCheckLHsTypeInContext will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -790,10 +790,10 @@ We work this out in a hacky way, by looking at the expected kind: see Note [Inferring tuple kinds]. In this case, we kind-check the RHS using the kind gotten from the LHS: -see the call to tcCheckLHsType in tcTyFamInstEqnGuts in GHC.Tc.Tycl. +see the call to tcCheckLHsTypeInContext in tcTyFamInstEqnGuts in GHC.Tc.Tycl. But we want the kind from the LHS to be /zonked/, so that when -kind-checking the RHS (tcCheckLHsType) we can "see" what we learned +kind-checking the RHS (tcCheckLHsTypeInContext) we can "see" what we learned from kind-checking the LHS (tcFamTyPats). In our example above, the type of the LHS is just `kappa` (by instantiating the forall k), but then we learn (from x::Constraint) that kappa ~ Constraint. We want @@ -821,15 +821,15 @@ tcHsOpenType, tcHsLiftedType, tcHsOpenType hs_ty = addTypeCtxt hs_ty $ tcHsOpenTypeNC hs_ty tcHsLiftedType hs_ty = addTypeCtxt hs_ty $ tcHsLiftedTypeNC hs_ty -tcHsOpenTypeNC hs_ty = do { ek <- newOpenTypeKind; tcLHsType hs_ty ek } -tcHsLiftedTypeNC hs_ty = tcLHsType hs_ty liftedTypeKind +tcHsOpenTypeNC hs_ty = do { ek <- newOpenTypeKind; tcCheckLHsType hs_ty ek } +tcHsLiftedTypeNC hs_ty = tcCheckLHsType hs_ty liftedTypeKind --- Like tcHsType, but takes an expected kind -tcCheckLHsType :: LHsType GhcRn -> ContextKind -> TcM TcType -tcCheckLHsType hs_ty exp_kind +-- Like tcCheckLHsType, but takes an expected kind +tcCheckLHsTypeInContext :: LHsType GhcRn -> ContextKind -> TcM TcType +tcCheckLHsTypeInContext hs_ty exp_kind = addTypeCtxt hs_ty $ do { ek <- newExpectedKind exp_kind - ; tcLHsType hs_ty ek } + ; tcCheckLHsType hs_ty ek } tcInferLHsType :: LHsType GhcRn -> TcM TcType tcInferLHsType hs_ty @@ -854,7 +854,7 @@ tcInferLHsTypeUnsaturated :: LHsType GhcRn -> TcM (TcType, TcKind) tcInferLHsTypeUnsaturated hs_ty = addTypeCtxt hs_ty $ do { mode <- mkHoleMode TypeLevel HM_Sig -- Allow and report holes - ; case splitHsAppTys (unLoc hs_ty) of + ; case splitHsAppTys_maybe (unLoc hs_ty) of Just (hs_fun_ty, hs_args) -> do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty ; tcInferTyApps_nosat mode hs_fun_ty fun_ty hs_args } @@ -890,12 +890,18 @@ Terms are eagerly instantiated. This means that if you say x = id then `id` gets instantiated to have type alpha -> alpha. The variable -alpha is then unconstrained and regeneralized. But we cannot do this -in types, as we have no type-level lambda. So, when we are sure -that we will not want to regeneralize later -- because we are done -checking a type, for example -- we can instantiate. But we do not -instantiate at variables, nor do we in tcInferLHsTypeUnsaturated, -which is used by :kind in GHCi. +alpha is then unconstrained and regeneralized. So we may well end up with + x = /\x. id @a +But we cannot do this in types, as we have no type-level lambda. + +So, we must be careful only to instantiate at the last possible moment, when +we're sure we're never going to want the lost polymorphism again. This is done +in calls to `tcInstInvisibleTyBinders`; a particular case in point is in +`checkExpectedKind`. + +Otherwise, we are careful /not/ to instantiate. For example: +* at a variable in `tcTyVar` +* in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi. ************************************************************************ * * @@ -969,48 +975,18 @@ instance Outputable TcTyMode where {- Note [Bidirectional type checking] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In expressions, whenever we see a polymorphic identifier, say `id`, we are -free to instantiate it with metavariables, knowing that we can always -re-generalize with type-lambdas when necessary. For example: - - rank2 :: (forall a. a -> a) -> () - x = rank2 id - -When checking the body of `x`, we can instantiate `id` with a metavariable. -Then, when we're checking the application of `rank2`, we notice that we really -need a polymorphic `id`, and then re-generalize over the unconstrained -metavariable. - -In types, however, we're not so lucky, because *we cannot re-generalize*! -There is no lambda. So, we must be careful only to instantiate at the last -possible moment, when we're sure we're never going to want the lost polymorphism -again. This is done in calls to tcInstInvisibleTyBinders. - -To implement this behavior, we use bidirectional type checking, where we -explicitly think about whether we know the kind of the type we're checking -or not. Note that there is a difference between not knowing a kind and -knowing a metavariable kind: the metavariables are TauTvs, and cannot become -forall-quantified kinds. Previously (before dependent types), there were -no higher-rank kinds, and so we could instantiate early and be sure that -no types would have polymorphic kinds, and so we could always assume that -the kind of a type was a fresh metavariable. Not so anymore, thus the -need for two algorithms. - -For HsType forms that can never be kind-polymorphic, we implement only the -"down" direction, where we safely assume a metavariable kind. For HsType forms -that *can* be kind-polymorphic, we implement just the "up" (functions with -"infer" in their name) version, as we gain nothing by also implementing the -"down" version. - -Note [Future-proofing the type checker] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As discussed in Note [Bidirectional type checking], each HsType form is -handled in *either* tc_infer_hs_type *or* tc_hs_type. These functions -are mutually recursive, so that either one can work for any type former. -But, we want to make sure that our pattern-matches are complete. So, -we have a bunch of repetitive code just so that we get warnings if we're -missing any patterns. +In types, as in terms, we use bidirectional type infefence. The main workhorse +function looks like this: + type ExpKind = ExpType + data ExpType = Check TcSigmaKind | Infer ...(hole TcRhoType)... + + tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType + +* When the `ExpKind` argument is (Check ki), we /check/ that the type has + kind `ki` +* When the `ExpKind` argument is (Infer hole), we /infer/ the kind of the + type, and fill the hole with that kind -} ------------------------------------------ @@ -1022,74 +998,13 @@ tc_infer_lhs_type mode (L span ty) = setSrcSpanA span $ tc_infer_hs_type mode ty ---------------------------- --- | Call 'tc_infer_hs_type' and check its result against an expected kind. -tc_infer_hs_type_ek :: HasDebugCallStack => TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType -tc_infer_hs_type_ek mode hs_ty ek - = do { (ty, k) <- tc_infer_hs_type mode hs_ty - ; checkExpectedKind hs_ty ty k ek } - --------------------------- -- | Infer the kind of a type and desugar. This is the "up" type-checker, -- as described in Note [Bidirectional type checking] tc_infer_hs_type :: TcTyMode -> HsType GhcRn -> TcM (TcType, TcKind) -tc_infer_hs_type mode (HsParTy _ t) - = tc_infer_lhs_type mode t - -tc_infer_hs_type mode ty - | Just (hs_fun_ty, hs_args) <- splitHsAppTys ty - = do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty - ; tcInferTyApps mode hs_fun_ty fun_ty hs_args } - -tc_infer_hs_type mode (HsKindSig _ ty sig) - = do { let mode' = mode { mode_tyki = KindLevel } - ; sig' <- tc_lhs_kind_sig mode' KindSigCtxt sig - -- We must typecheck the kind signature, and solve all - -- its equalities etc; from this point on we may do - -- things like instantiate its foralls, so it needs - -- to be fully determined (#14904) - ; traceTc "tc_infer_hs_type:sig" (ppr ty $$ ppr sig') - ; ty' <- tcAddKindSigPlaceholders sig $ - tc_lhs_type mode ty sig' - ; return (ty', sig') } - --- HsSpliced is an annotation produced by 'GHC.Rename.Splice.rnSpliceType' to communicate --- the splice location to the typechecker. Here we skip over it in order to have --- the same kind inferred for a given expression whether it was produced from --- splices or not. --- --- See Note [Delaying modFinalizers in untyped splices]. -tc_infer_hs_type mode (HsSpliceTy (HsUntypedSpliceTop _ ty) _) - = tc_infer_lhs_type mode ty - -tc_infer_hs_type _ (HsSpliceTy (HsUntypedSpliceNested n) s) = pprPanic "tc_infer_hs_type: invalid nested splice" (pprUntypedSplice True (Just n) s) - -tc_infer_hs_type mode (HsDocTy _ ty _) = tc_infer_lhs_type mode ty - --- See Note [Typechecking HsCoreTys] -tc_infer_hs_type _ (XHsType ty) - = do env <- getLclEnv - -- Raw uniques since we go from NameEnv to TvSubstEnv. - let subst_prs :: [(Unique, TcTyVar)] - subst_prs = [ (getUnique nm, tv) - | ATyVar nm tv <- nonDetNameEnvElts (getLclEnvTypeEnv env) ] - subst = mkTvSubst - (mkInScopeSetList $ map snd subst_prs) - (listToUFM_Directly $ map (fmap mkTyVarTy) subst_prs) - ty' = substTy subst ty - return (ty', typeKind ty') - -tc_infer_hs_type _ (HsExplicitListTy _ _ tys) - | null tys -- this is so that we can use visible kind application with '[] - -- e.g ... '[] @Bool - = return (mkTyConTy promotedNilDataCon, - mkSpecForAllTys [alphaTyVar] $ mkListTy alphaTy) - -tc_infer_hs_type mode other_ty - = do { kv <- newMetaKindVar - ; ty' <- tc_hs_type mode other_ty kv - ; return (ty', kv) } +tc_infer_hs_type mode rn_ty + = tcInfer $ \exp_kind -> tcHsType mode rn_ty exp_kind {- Note [Typechecking HsCoreTys] @@ -1133,26 +1048,36 @@ substitution to each HsCoreTy and all is well: -} ------------------------------------------ -tcLHsType :: LHsType GhcRn -> TcKind -> TcM TcType -tcLHsType hs_ty exp_kind - = tc_lhs_type typeLevelMode hs_ty exp_kind +tcCheckLHsType :: LHsType GhcRn -> TcKind -> TcM TcType +tcCheckLHsType hs_ty exp_kind + = tc_check_lhs_type typeLevelMode hs_ty exp_kind + +tc_check_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType +tc_check_lhs_type mode (L span ty) exp_kind + = setSrcSpanA span $ + tc_check_hs_type mode ty exp_kind -tc_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType -tc_lhs_type mode (L span ty) exp_kind +tc_check_hs_type :: TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType +-- See Note [Bidirectional type checking] +tc_check_hs_type mode ty ek = tcHsType mode ty (Check ek) + +tcLHsType :: TcTyMode -> LHsType GhcRn -> ExpKind -> TcM TcType +tcLHsType mode (L span ty) exp_kind = setSrcSpanA span $ - tc_hs_type mode ty exp_kind + tcHsType mode ty exp_kind -tc_hs_type :: TcTyMode -> HsType GhcRn -> TcKind -> TcM TcType +tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType +-- The main workhorse for type kind checking -- See Note [Bidirectional type checking] -tc_hs_type mode (HsParTy _ ty) exp_kind = tc_lhs_type mode ty exp_kind -tc_hs_type mode (HsDocTy _ ty _) exp_kind = tc_lhs_type mode ty exp_kind -tc_hs_type _ ty@(HsBangTy _ bang _) _ +tcHsType mode (HsParTy _ ty) exp_kind = tcLHsType mode ty exp_kind +tcHsType mode (HsDocTy _ ty _) exp_kind = tcLHsType mode ty exp_kind +tcHsType _ ty@(HsBangTy _ bang _) _ -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of -- bangs are invalid, so fail. (#7210, #14761) = failWith $ TcRnUnexpectedAnnotation ty bang -tc_hs_type _ ty@(HsRecTy {}) _ +tcHsType _ ty@(HsRecTy {}) _ -- Record types (which only show up temporarily in constructor -- signatures) should have been removed by now = failWithTc $ TcRnIllegalRecordSyntax (Right ty) @@ -1162,23 +1087,23 @@ tc_hs_type _ ty@(HsRecTy {}) _ -- while capturing the local environment. -- -- See Note [Delaying modFinalizers in untyped splices]. -tc_hs_type mode (HsSpliceTy (HsUntypedSpliceTop mod_finalizers ty) _) +tcHsType mode (HsSpliceTy (HsUntypedSpliceTop mod_finalizers ty) _) exp_kind = do addModFinalizersWithLclEnv mod_finalizers - tc_lhs_type mode ty exp_kind + tcLHsType mode ty exp_kind -tc_hs_type _ (HsSpliceTy (HsUntypedSpliceNested n) s) _ = pprPanic "tc_hs_type: invalid nested splice" (pprUntypedSplice True (Just n) s) +tcHsType _ (HsSpliceTy (HsUntypedSpliceNested n) s) _ = pprPanic "tcHsType: invalid nested splice" (pprUntypedSplice True (Just n) s) ---------- Functions and applications -tc_hs_type mode (HsFunTy _ mult ty1 ty2) exp_kind +tcHsType mode (HsFunTy _ mult ty1 ty2) exp_kind = tc_fun_type mode mult ty1 ty2 exp_kind -tc_hs_type mode (HsOpTy _ _ ty1 (L _ op) ty2) exp_kind +tcHsType mode (HsOpTy _ _ ty1 (L _ op) ty2) exp_kind | op `hasKey` unrestrictedFunTyConKey = tc_fun_type mode (HsUnrestrictedArrow noExtField) ty1 ty2 exp_kind --------- Foralls -tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind +tcHsType mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind | HsForAllInvis{} <- tele = tc_hs_forall_ty tele ty exp_kind -- For an invisible forall, we allow the body to have @@ -1187,15 +1112,15 @@ tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind | HsForAllVis{} <- tele = do { ek <- newOpenTypeKind - ; r <- tc_hs_forall_ty tele ty ek - ; checkExpectedKind t r ek exp_kind } + ; r <- tc_hs_forall_ty tele ty (Check ek) + ; checkExpKind t r ek exp_kind } -- For a visible forall, we require that the body is of kind TYPE r. -- See Note [Body kind of a HsForAllTy] where tc_hs_forall_ty tele ty ek = do { (tv_bndrs, ty') <- tcTKTelescope mode tele $ - tc_lhs_type mode ty ek + tcLHsType mode ty ek -- Pass on the mode from the type, to any wildcards -- in kind signatures on the forall'd variables -- e.g. f :: _ -> Int -> forall (a :: _). blah @@ -1203,145 +1128,196 @@ tc_hs_type mode t@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind -- Do not kind-generalise here! See Note [Kind generalisation] ; return (mkForAllTys tv_bndrs ty') } -tc_hs_type mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind +tcHsType mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind | null (unLoc ctxt) - = tc_lhs_type mode rn_ty exp_kind - - -- See Note [Body kind of a HsQualTy] - | isConstraintLikeKind exp_kind + = tcLHsType mode rn_ty exp_kind + -- See Note [Body kind of a HsQualTy] + | Check kind <- exp_kind, isConstraintLikeKind kind = do { ctxt' <- tc_hs_context mode ctxt - ; ty' <- tc_lhs_type mode rn_ty constraintKind - ; return (tcMkDFunPhiTy ctxt' ty') } + ; ty' <- tc_check_lhs_type mode rn_ty constraintKind + ; return (tcMkDFunPhiTy ctxt' ty') } | otherwise = do { ctxt' <- tc_hs_context mode ctxt - ; ek <- newOpenTypeKind -- The body kind (result of the function) can + ; ek <- newOpenTypeKind -- The body kind (result of the function) can -- be TYPE r, for any r, hence newOpenTypeKind - ; ty' <- tc_lhs_type mode rn_ty ek - ; checkExpectedKind (unLoc rn_ty) (tcMkPhiTy ctxt' ty') - liftedTypeKind exp_kind } + ; ty' <- tc_check_lhs_type mode rn_ty ek + ; let res_ty = tcMkPhiTy ctxt' ty' + ; checkExpKind (unLoc rn_ty) res_ty + liftedTypeKind exp_kind } --------- Lists, arrays, and tuples -tc_hs_type mode rn_ty@(HsListTy _ elt_ty) exp_kind - = do { tau_ty <- tc_lhs_type mode elt_ty liftedTypeKind +tcHsType mode rn_ty@(HsListTy _ elt_ty) exp_kind + = do { tau_ty <- tc_check_lhs_type mode elt_ty liftedTypeKind ; checkWiredInTyCon listTyCon - ; checkExpectedKind rn_ty (mkListTy tau_ty) liftedTypeKind exp_kind } + ; checkExpKind rn_ty (mkListTy tau_ty) liftedTypeKind exp_kind } --- See Note [Distinguishing tuple kinds] in Language.Haskell.Syntax.Type --- See Note [Inferring tuple kinds] -tc_hs_type mode rn_ty@(HsTupleTy _ HsBoxedOrConstraintTuple hs_tys) exp_kind - -- (NB: not zonking before looking at exp_k, to avoid left-right bias) - | Just tup_sort <- tupKindSort_maybe exp_kind - = traceTc "tc_hs_type tuple" (ppr hs_tys) >> - tc_tuple rn_ty mode tup_sort hs_tys exp_kind - | otherwise - = do { traceTc "tc_hs_type tuple 2" (ppr hs_tys) - ; (tys, kinds) <- mapAndUnzipM (tc_infer_lhs_type mode) hs_tys - ; kinds <- liftZonkM $ mapM zonkTcType kinds - -- Infer each arg type separately, because errors can be - -- confusing if we give them a shared kind. Eg #7410 - -- (Either Int, Int), we do not want to get an error saying - -- "the second argument of a tuple should have kind *->*" +tcHsType mode rn_ty@(HsTupleTy _ tup_sort tys) exp_kind + = do k <- expTypeToType exp_kind + tc_hs_tuple_ty rn_ty mode tup_sort tys k - ; let (arg_kind, tup_sort) - = case [ (k,s) | k <- kinds - , Just s <- [tupKindSort_maybe k] ] of - ((k,s) : _) -> (k,s) - [] -> (liftedTypeKind, BoxedTuple) - -- In the [] case, it's not clear what the kind is, so guess * - - ; tys' <- sequence [ setSrcSpanA loc $ - checkExpectedKind hs_ty ty kind arg_kind - | ((L loc hs_ty),ty,kind) <- zip3 hs_tys tys kinds ] - - ; finish_tuple rn_ty tup_sort tys' (map (const arg_kind) tys') exp_kind } - - -tc_hs_type mode rn_ty@(HsTupleTy _ HsUnboxedTuple tys) exp_kind - = tc_tuple rn_ty mode UnboxedTuple tys exp_kind - -tc_hs_type mode rn_ty@(HsSumTy _ hs_tys) exp_kind +tcHsType mode rn_ty@(HsSumTy _ hs_tys) exp_kind = do { let arity = length hs_tys ; arg_kinds <- mapM (\_ -> newOpenTypeKind) hs_tys - ; tau_tys <- zipWithM (tc_lhs_type mode) hs_tys arg_kinds + ; tau_tys <- zipWithM (tc_check_lhs_type mode) hs_tys arg_kinds ; let arg_reps = map kindRep arg_kinds arg_tys = arg_reps ++ tau_tys sum_ty = mkTyConApp (sumTyCon arity) arg_tys sum_kind = unboxedSumKind arg_reps - ; checkExpectedKind rn_ty sum_ty sum_kind exp_kind + ; checkExpKind rn_ty sum_ty sum_kind exp_kind } --------- Promoted lists and tuples -tc_hs_type mode rn_ty@(HsExplicitListTy _ _ tys) exp_kind - -- The '[] case is handled in tc_infer_hs_type. - -- See Note [Future-proofing the type checker]. +tcHsType mode rn_ty@(HsExplicitListTy _ _ tys) exp_kind + -- See Note [Kind-checking explicit lists] + | null tys - = tc_infer_hs_type_ek mode rn_ty exp_kind + = do let ty = mkTyConTy promotedNilDataCon + let kind = mkSpecForAllTys [alphaTyVar] $ mkListTy alphaTy + checkExpKind rn_ty ty kind exp_kind | otherwise = do { tks <- mapM (tc_infer_lhs_type mode) tys ; (taus', kind) <- unifyKinds tys tks ; let ty = (foldr (mk_cons kind) (mk_nil kind) taus') - ; checkExpectedKind rn_ty ty (mkListTy kind) exp_kind } + ; checkExpKind rn_ty ty (mkListTy kind) exp_kind } where mk_cons k a b = mkTyConApp (promoteDataCon consDataCon) [k, a, b] mk_nil k = mkTyConApp (promoteDataCon nilDataCon) [k] -tc_hs_type mode rn_ty@(HsExplicitTupleTy _ tys) exp_kind +tcHsType mode rn_ty@(HsExplicitTupleTy _ tys) exp_kind -- using newMetaKindVar means that we force instantiations of any polykinded -- types. At first, I just used tc_infer_lhs_type, but that led to #11255. = do { ks <- replicateM arity newMetaKindVar - ; taus <- zipWithM (tc_lhs_type mode) tys ks + ; taus <- zipWithM (tc_check_lhs_type mode) tys ks ; let kind_con = tupleTyCon Boxed arity ty_con = promotedTupleDataCon Boxed arity tup_k = mkTyConApp kind_con ks ; checkTupSize arity - ; checkExpectedKind rn_ty (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind } + ; checkExpKind rn_ty (mkTyConApp ty_con (ks ++ taus)) tup_k exp_kind } where arity = length tys --------- Constraint types -tc_hs_type mode rn_ty@(HsIParamTy _ (L _ n) ty) exp_kind +tcHsType mode rn_ty@(HsIParamTy _ (L _ n) ty) exp_kind = do { massert (isTypeLevel (mode_tyki mode)) - ; ty' <- tc_lhs_type mode ty liftedTypeKind + ; ty' <- tc_check_lhs_type mode ty liftedTypeKind ; let n' = mkStrLitTy $ hsIPNameFS n ; ipClass <- tcLookupClass ipClassName - ; checkExpectedKind rn_ty (mkClassPred ipClass [n',ty']) + ; checkExpKind rn_ty (mkClassPred ipClass [n',ty']) constraintKind exp_kind } -tc_hs_type _ rn_ty@(HsStarTy _ _) exp_kind +tcHsType _ rn_ty@(HsStarTy _ _) exp_kind -- Desugaring 'HsStarTy' to 'Data.Kind.Type' here means that we don't -- have to handle it in 'coreView' - = checkExpectedKind rn_ty liftedTypeKind liftedTypeKind exp_kind + = checkExpKind rn_ty liftedTypeKind liftedTypeKind exp_kind --------- Literals -tc_hs_type _ rn_ty@(HsTyLit _ (HsNumTy _ n)) exp_kind +tcHsType _ rn_ty@(HsTyLit _ (HsNumTy _ n)) exp_kind = do { checkWiredInTyCon naturalTyCon - ; checkExpectedKind rn_ty (mkNumLitTy n) naturalTy exp_kind } + ; checkExpKind rn_ty (mkNumLitTy n) naturalTy exp_kind } -tc_hs_type _ rn_ty@(HsTyLit _ (HsStrTy _ s)) exp_kind +tcHsType _ rn_ty@(HsTyLit _ (HsStrTy _ s)) exp_kind = do { checkWiredInTyCon typeSymbolKindCon - ; checkExpectedKind rn_ty (mkStrLitTy s) typeSymbolKind exp_kind } -tc_hs_type _ rn_ty@(HsTyLit _ (HsCharTy _ c)) exp_kind + ; checkExpKind rn_ty (mkStrLitTy s) typeSymbolKind exp_kind } +tcHsType _ rn_ty@(HsTyLit _ (HsCharTy _ c)) exp_kind = do { checkWiredInTyCon charTyCon - ; checkExpectedKind rn_ty (mkCharLitTy c) charTy exp_kind } + ; checkExpKind rn_ty (mkCharLitTy c) charTy exp_kind } --------- Wildcards -tc_hs_type mode ty@(HsWildCardTy _) ek - = tcAnonWildCardOcc NoExtraConstraint mode ty ek +tcHsType mode ty@(HsWildCardTy _) ek + = do k <- expTypeToType ek + tcAnonWildCardOcc NoExtraConstraint mode ty k + +--------- Type applications +tcHsType mode rn_ty@(HsTyVar{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsAppTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsAppKindTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind +tcHsType mode rn_ty@(HsOpTy{}) exp_kind = tc_app_ty mode rn_ty exp_kind + +tcHsType mode rn_ty@(HsKindSig _ ty sig) exp_kind + = do { let mode' = mode { mode_tyki = KindLevel } + ; sig' <- tc_lhs_kind_sig mode' KindSigCtxt sig + -- We must typecheck the kind signature, and solve all + -- its equalities etc; from this point on we may do + -- things like instantiate its foralls, so it needs + -- to be fully determined (#14904) + ; traceTc "tcHsType:sig" (ppr ty $$ ppr sig') + ; ty' <- tcAddKindSigPlaceholders sig $ + tc_check_lhs_type mode ty sig' + ; checkExpKind rn_ty ty' sig' exp_kind } + +-- See Note [Typechecking HsCoreTys] +tcHsType _ rn_ty@(XHsType ty) exp_kind + = do env <- getLclEnv + -- Raw uniques since we go from NameEnv to TvSubstEnv. + let subst_prs :: [(Unique, TcTyVar)] + subst_prs = [ (getUnique nm, tv) + | ATyVar nm tv <- nonDetNameEnvElts (getLclEnvTypeEnv env) ] + subst = mkTvSubst + (mkInScopeSetList $ map snd subst_prs) + (listToUFM_Directly $ map (fmap mkTyVarTy) subst_prs) + ty' = substTy subst ty + checkExpKind rn_ty ty' (typeKind ty') exp_kind + +tc_hs_tuple_ty :: HsType GhcRn + -> TcTyMode + -> HsTupleSort + -> [LHsType GhcRn] + -> TcKind + -> TcM TcType +-- See Note [Distinguishing tuple kinds] in GHC.Hs.Type +-- See Note [Inferring tuple kinds] +tc_hs_tuple_ty rn_ty mode HsBoxedOrConstraintTuple hs_tys exp_kind + -- (NB: not zonking before looking at exp_k, to avoid left-right bias) + | Just tup_sort <- tupKindSort_maybe exp_kind + = traceTc "tcHsType tuple" (ppr hs_tys) >> + tc_tuple rn_ty mode tup_sort hs_tys exp_kind + | otherwise + = do { traceTc "tcHsType tuple 2" (ppr hs_tys) + ; (tys, kinds) <- mapAndUnzipM (tc_infer_lhs_type mode) hs_tys + ; kinds <- liftZonkM $ mapM zonkTcType kinds + -- Infer each arg type separately, because errors can be + -- confusing if we give them a shared kind. Eg #7410 + -- (Either Int, Int), we do not want to get an error saying + -- "the second argument of a tuple should have kind *->*" + + ; let (arg_kind, tup_sort) + = case [ (k,s) | k <- kinds + , Just s <- [tupKindSort_maybe k] ] of + ((k,s) : _) -> (k,s) + [] -> (liftedTypeKind, BoxedTuple) + -- In the [] case, it's not clear what the kind is, so guess * ---------- Potentially kind-polymorphic types: call the "up" checker --- See Note [Future-proofing the type checker] -tc_hs_type mode ty@(HsTyVar {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsAppTy {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsAppKindTy{}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsOpTy {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(HsKindSig {}) ek = tc_infer_hs_type_ek mode ty ek -tc_hs_type mode ty@(XHsType {}) ek = tc_infer_hs_type_ek mode ty ek + ; tys' <- sequence [ setSrcSpanA loc $ + checkExpectedKind hs_ty ty kind arg_kind + | ((L loc hs_ty),ty,kind) <- zip3 hs_tys tys kinds ] + + ; finish_tuple rn_ty tup_sort tys' (map (const arg_kind) tys') exp_kind } +tc_hs_tuple_ty rn_ty mode HsUnboxedTuple tys exp_kind = + tc_tuple rn_ty mode UnboxedTuple tys exp_kind {- +Note [Kind-checking explicit lists] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In a type, suppose we have an application (F [t1,t2]), +where [t1,t2] is an explicit list, and + F :: [ki] -> blah + +Then we want to return the type + F ((:) @ki t2 ((:) @ki t2 ([] @ki))) +where the argument list is instantiated to F's argument kind `ki`. + +But what about (G []), where + G :: (forall k. [k]) -> blah + +Here we want to return (G []), with no instantiation at all. But since we have +no lambda in types, we must be careful not to instantiate that `[]`, because we +can't re-generalise it. Hence, when kind-checking an explicit list, we need a +special case for `[]`. + Note [Variable Specificity and Forall Visibility] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsForAllTy contains an HsForAllTelescope to denote the visibility of the forall @@ -1366,28 +1342,28 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo ------------------------------------------ tc_mult :: TcTyMode -> HsArrow GhcRn -> TcM Mult -tc_mult mode ty = tc_lhs_type mode (arrowToHsType ty) multiplicityTy +tc_mult mode ty = tc_check_lhs_type mode (arrowToHsType ty) multiplicityTy ------------------------------------------ -tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> TcKind +tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind -> TcM TcType tc_fun_type mode mult ty1 ty2 exp_kind = case mode_tyki mode of TypeLevel -> do { traceTc "tc_fun_type" (ppr ty1 $$ ppr ty2) ; arg_k <- newOpenTypeKind ; res_k <- newOpenTypeKind - ; ty1' <- tc_lhs_type mode ty1 arg_k - ; ty2' <- tc_lhs_type mode ty2 res_k + ; ty1' <- tc_check_lhs_type mode ty1 arg_k + ; ty2' <- tc_check_lhs_type mode ty2 res_k ; mult' <- tc_mult mode mult - ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) - (tcMkVisFunTy mult' ty1' ty2') - liftedTypeKind exp_kind } + ; checkExpKind (HsFunTy noExtField mult ty1 ty2) + (tcMkVisFunTy mult' ty1' ty2') + liftedTypeKind exp_kind } KindLevel -> -- no representation polymorphism in kinds. yet. - do { ty1' <- tc_lhs_type mode ty1 liftedTypeKind - ; ty2' <- tc_lhs_type mode ty2 liftedTypeKind + do { ty1' <- tc_check_lhs_type mode ty1 liftedTypeKind + ; ty2' <- tc_check_lhs_type mode ty2 liftedTypeKind ; mult' <- tc_mult mode mult - ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) - (tcMkVisFunTy mult' ty1' ty2') - liftedTypeKind exp_kind } + ; checkExpKind (HsFunTy noExtField mult ty1 ty2) + (tcMkVisFunTy mult' ty1' ty2') + liftedTypeKind exp_kind } {- Note [Skolem escape and forall-types] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1442,7 +1418,7 @@ tc_tuple rn_ty mode tup_sort tys exp_kind BoxedTuple -> return (replicate arity liftedTypeKind) UnboxedTuple -> replicateM arity newOpenTypeKind ConstraintTuple -> return (replicate arity constraintKind) - ; tau_tys <- zipWithM (tc_lhs_type mode) tys arg_kinds + ; tau_tys <- zipWithM (tc_check_lhs_type mode) tys arg_kinds ; finish_tuple rn_ty tup_sort tau_tys arg_kinds exp_kind } where arity = length tys @@ -1530,9 +1506,9 @@ since the two constraints should be semantically equivalent. * * ********************************************************************* -} -splitHsAppTys :: HsType GhcRn -> Maybe (LHsType GhcRn, [LHsTypeArg GhcRn]) -splitHsAppTys hs_ty - | is_app hs_ty = Just (go (noLocA hs_ty) []) +splitHsAppTys_maybe :: HsType GhcRn -> Maybe (LHsType GhcRn, [LHsTypeArg GhcRn]) +splitHsAppTys_maybe hs_ty + | is_app hs_ty = Just (splitHsAppTys hs_ty) | otherwise = Nothing where is_app :: HsType GhcRn -> Bool @@ -1547,6 +1523,10 @@ splitHsAppTys hs_ty is_app (HsParTy _ (L _ ty)) = is_app ty is_app _ = False +splitHsAppTys :: HsType GhcRn -> (LHsType GhcRn, [LHsTypeArg GhcRn]) + +splitHsAppTys hs_ty = go (noLocA hs_ty) [] + where go :: LHsType GhcRn -> [HsArg GhcRn (LHsType GhcRn) (LHsKind GhcRn)] -> (LHsType GhcRn, @@ -1570,6 +1550,14 @@ tcInferTyAppHead _ (L _ (HsTyVar _ _ (L _ tv))) tcInferTyAppHead mode ty = tc_infer_lhs_type mode ty +tc_app_ty :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType +tc_app_ty mode rn_ty exp_kind + = do { (fun_ty, _ki) <- tcInferTyAppHead mode hs_fun_ty + ; (ty, infered_kind) <- tcInferTyApps mode hs_fun_ty fun_ty hs_args + ; checkExpKind rn_ty ty infered_kind exp_kind } + where + (hs_fun_ty, hs_args) = splitHsAppTys rn_ty + --------------------------- -- | Apply a type of a given kind to a list of arguments. This instantiates -- invisible parameters as necessary. Always consumes all the arguments, @@ -1656,7 +1644,7 @@ tcInferTyApps_nosat mode orig_hs_ty fun orig_hs_args ; arg_mode <- mkHoleMode KindLevel HM_VTA -- HM_VKA: see Note [Wildcards in visible kind application] ; ki_arg <- addErrCtxt (funAppCtxt orig_hs_ty hs_ki_arg n) $ - tc_lhs_type arg_mode hs_ki_arg exp_kind + tc_check_lhs_type arg_mode hs_ki_arg exp_kind ; traceTc "tcInferTyApps (vis kind app)" (ppr exp_kind) ; (subst', fun') <- mkAppTyM subst fun ki_binder ki_arg @@ -1687,7 +1675,7 @@ tcInferTyApps_nosat mode orig_hs_ty fun orig_hs_args , ppr subst ]) ; let exp_kind = substTy subst $ piTyBinderType ki_binder ; arg' <- addErrCtxt (funAppCtxt orig_hs_ty arg n) $ - tc_lhs_type mode arg exp_kind + tc_check_lhs_type mode arg exp_kind ; traceTc "tcInferTyApps (vis normal app) 2" (ppr exp_kind) ; (subst', fun') <- mkAppTyM subst fun ki_binder arg' ; go (n+1) fun' subst' inner_ki args } @@ -1975,6 +1963,19 @@ checkExpectedKind hs_ty ty act_kind exp_kind n_act_invis_bndrs = invisibleTyBndrCount act_kind n_to_inst = n_act_invis_bndrs - n_exp_invis_bndrs + +-- tyr <- checkExpKind hs_ty ty (act_ki :: Kind) (exp_ki :: ExpKind) +-- requires that `ty` has kind `act_ki` +-- It checks that the actual kind `act_ki` matches the expected kind `exp_ki` +-- and returns `tyr`, a possibly-casted form of `ty`, that has precisely kind `exp_ki` +-- `hs_ty` is purely for error messages +checkExpKind :: HsType GhcRn -> TcType -> TcKind -> ExpKind -> TcM TcType +checkExpKind rn_ty ty ki (Check ki') = + checkExpectedKind rn_ty ty ki ki' +checkExpKind _rn_ty ty ki (Infer cell) = do + co <- fillInferResult ki cell + pure (ty `mkCastTy` co) + --------------------------- tcHsContext :: Maybe (LHsContext GhcRn) -> TcM [PredType] @@ -1988,7 +1989,7 @@ tc_hs_context :: TcTyMode -> LHsContext GhcRn -> TcM [PredType] tc_hs_context mode ctxt = mapM (tc_lhs_pred mode) (unLoc ctxt) tc_lhs_pred :: TcTyMode -> LHsType GhcRn -> TcM PredType -tc_lhs_pred mode pred = tc_lhs_type mode pred constraintKind +tc_lhs_pred mode pred = tc_check_lhs_type mode pred constraintKind --------------------------- tcTyVar :: Name -> TcM (TcType, TcKind) @@ -4109,7 +4110,7 @@ tcHsPartialSigType ctxt sig_ty ; tau <- -- Don't do (addTypeCtxt hs_tau) here else we get -- In the type -- In the type signature: foo :: - tc_lhs_type mode hs_tau ek + tc_check_lhs_type mode hs_tau ek ; return (wcs, wcx, theta, tau) } @@ -4419,8 +4420,8 @@ tc_type_in_pat ctxt hole_mode hs_ty wcs ns ctxt_kind -- and c.f #16033 bindNamedWildCardBinders wcs $ \ wcs -> tcExtendNameTyVarEnv tkv_prs $ - do { ek <- newExpectedKind ctxt_kind - ; ty <- tc_lhs_type mode hs_ty ek + do { ek <- newExpectedKind ctxt_kind + ; ty <- tc_check_lhs_type mode hs_ty ek ; return (wcs, ty) } ; mapM_ emitNamedTypeHole wcs @@ -4596,7 +4597,7 @@ tc_lhs_kind_sig mode ctxt hs_kind -- Result is zonked = do { kind <- addErrCtxt (text "In the kind" <+> quotes (ppr hs_kind)) $ solveEqualities "tcLHsKindSig" $ - tc_lhs_type mode hs_kind liftedTypeKind + tc_check_lhs_type mode hs_kind liftedTypeKind ; traceTc "tcLHsKindSig" (ppr hs_kind $$ ppr kind) -- No generalization: ; kindGeneralizeNone kind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1772,7 +1772,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ let res_kind = tyConResKind tycon - in discardResult $ tcCheckLHsType rhs (TheKind res_kind) + in discardResult $ tcCheckLHsTypeInContext rhs (TheKind res_kind) -- NB: check against the result kind that we allocated -- in inferInitialKinds. @@ -1801,7 +1801,7 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsType (getBangType ty) exp_kind + ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1868,7 +1868,7 @@ kcConDecl new_or_data do { _ <- tcHsContext cxt ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind - ; _ <- tcCheckLHsType res_ty (TheKind con_res_kind) + ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) ; kcConGADTArgs new_or_data con_res_kind args ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) ; return () } @@ -1895,7 +1895,7 @@ Otherwise we'd infer the bogus kind The type signature for MkT influences the kind of T simply by kind-checking the result type (T g b), which will force 'f' and 'g' to have the same kinds. This is the call to - tcCheckLHsType res_ty (TheKind con_res_kind) + tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) Because this is the result type of an arrow, we know the kind must be of form (TYPE rr), and we get better error messages if we enforce that here (e.g. test gadt10). @@ -3054,7 +3054,7 @@ tcTySynRhs roles_info tc_name hs_ty do { env <- getLclEnv ; traceTc "tc-syn" (ppr tc_name $$ ppr (getLclEnvRdrEnv env)) ; rhs_ty <- pushLevelAndSolveEqualities skol_info tc_bndrs $ - tcCheckLHsType hs_ty (TheKind res_kind) + tcCheckLHsTypeInContext hs_ty (TheKind res_kind) -- See Note [Error on unconstrained meta-variables] in GHC.Tc.Utils.TcMType -- Example: (typecheck/should_fail/T17567) @@ -3197,7 +3197,7 @@ kcTyFamInstEqn tc_fam_tc ; discardResult $ bindOuterFamEqnTKBndrs_Q_Tv outer_bndrs $ do { (_fam_app, res_kind) <- tcFamTyPats tc_fam_tc hs_pats - ; tcCheckLHsType hs_rhs_ty (TheKind res_kind) } + ; tcCheckLHsTypeInContext hs_rhs_ty (TheKind res_kind) } -- Why "_Tv" here? Consider (#14066) -- type family Bar x y where -- Bar (x :: a) (y :: b) = Int @@ -3349,7 +3349,7 @@ tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty -- Ensure that the instance is consistent with its -- parent class (#16008) ; addConsistencyConstraints mb_clsinfo lhs_ty - ; rhs_ty <- tcCheckLHsType hs_rhs_ty (TheKind rhs_kind) + ; rhs_ty <- tcCheckLHsTypeInContext hs_rhs_ty (TheKind rhs_kind) ; return (lhs_ty, rhs_ty) } ; outer_bndrs <- scopedSortOuter outer_bndrs @@ -3926,7 +3926,7 @@ tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatype -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) = do { traceTc "tcConArg 1" (ppr bty) - ; arg_ty <- tcCheckLHsType (getBangType bty) exp_kind + ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -27,7 +27,7 @@ module GHC.Tc.Utils.TcType ( TcKind, TcCoVar, TcTyCoVar, TcTyVarBinder, TcInvisTVBinder, TcReqTVBinder, TcTyCon, MonoTcTyCon, PolyTcTyCon, TcTyConBinder, KnotTied, - ExpType(..), InferResult(..), + ExpType(..), ExpKind, InferResult(..), ExpTypeFRR, ExpSigmaType, ExpSigmaTypeFRR, ExpRhoType, mkCheckExpType, @@ -433,6 +433,9 @@ type ExpSigmaTypeFRR = ExpTypeFRR type ExpRhoType = ExpType +-- | Like 'ExpType', but on kind level +type ExpKind = ExpType + instance Outputable ExpType where ppr (Check ty) = text "Check" <> braces (ppr ty) ppr (Infer ir) = ppr ir ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -43,6 +43,8 @@ module GHC.Tc.Utils.Unify ( PuResult(..), failCheckWith, okCheckRefl, mapCheck, TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, famAppArgFlags, simpleUnifyCheck, checkPromoteFreeVars, + + fillInferResult, ) where import GHC.Prelude ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -1006,7 +1006,7 @@ would mean that when we pretty-print it back, we don't know whether the user wrote '*' or 'Type', and lose the parse/ppr roundtrip property. As a workaround, we parse '*' as HsStarTy (if it stands for 'Data.Kind.Type') -and then desugar it to 'Data.Kind.Type' in the typechecker (see tc_hs_type). +and then desugar it to 'Data.Kind.Type' in the typechecker (see tcHsType). When '*' is a regular type operator (StarIsType is disabled), HsStarTy is not involved. ===================================== testsuite/tests/partial-sigs/should_run/GHCiWildcardKind.stdout ===================================== @@ -1,2 +1,2 @@ -_ :: k +_ :: p Maybe _ :: * ===================================== testsuite/tests/th/T24299.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE TemplateHaskell #-} + +module T24299 where +import Language.Haskell.TH.Syntax (addModFinalizer, runIO) +import GHC.Types (Type) +import System.IO + +type Proxy :: forall a. a -> Type +data Proxy a = MkProxy + +check :: ($(addModFinalizer (runIO (do putStrLn "check"; hFlush stdout)) >> + [t| Proxy |]) :: Type -> Type) Int -- There is kind signature, we are in check mode +check = MkProxy + +infer :: ($(addModFinalizer (runIO (do putStrLn "infer"; hFlush stdout)) >> + [t| Proxy |]) ) Int -- no kind signature, inference mode is enabled +infer = MkProxy ===================================== testsuite/tests/th/T24299.stderr ===================================== @@ -0,0 +1,2 @@ +check +infer ===================================== testsuite/tests/th/all.T ===================================== @@ -606,3 +606,4 @@ test('T14032e', normal, compile_fail, ['-dsuppress-uniques']) test('ListTuplePunsTH', [only_ways(['ghci']), extra_files(['ListTuplePunsTH.hs', 'T15843a.hs'])], ghci_script, ['ListTuplePunsTH.script']) test('T24559', normal, compile, ['']) test('T24571', normal, compile, ['']) +test('T24299', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c18c7b70f25a733fe36a24950a981134751767 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c18c7b70f25a733fe36a24950a981134751767 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 17:22:41 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 13:22:41 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 45 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660c3ee17067d_f9da121db84392c8@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - dda18f97 by Duncan Coutts at 2024-04-02T13:22:18-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - f6405b9f by Duncan Coutts at 2024-04-02T13:22:18-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. This change is also reflected in the RTS flags types in the base library. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. - - - - - ec863cb3 by Duncan Coutts at 2024-04-02T13:22:18-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - 75ba245f by Duncan Coutts at 2024-04-02T13:22:18-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - b0d3b19f by Duncan Coutts at 2024-04-02T13:22:18-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - b7649169 by Duncan Coutts at 2024-04-02T13:22:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - a18cb695 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. - - - - - 155602b5 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Use atomic operations to update tso->why_blocked in the C code In the primops ported from Cmm to C. Since patch 515eb33d4fc the why_blocked gets accessed using load acquire and store release atomics. There was one exception to this new rule in 515eb33d4fc: for the delay# primop on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. I'm playing it safe here and using store release consistently. - - - - - 88a3b93c by Duncan Coutts at 2024-04-02T13:22:19-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 136edfdb by Duncan Coutts at 2024-04-02T13:22:19-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - 2433bc3f by Duncan Coutts at 2024-04-02T13:22:19-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - f194aaec by Duncan Coutts at 2024-04-02T13:22:19-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. - - - - - f0545200 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - df660784 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - b402e158 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d694b0fa by Duncan Coutts at 2024-04-02T13:22:19-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - ef60a964 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 14f7ed5c by Duncan Coutts at 2024-04-02T13:22:19-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - c9861100 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - 57abc5d3 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - e891bb2e by Duncan Coutts at 2024-04-02T13:22:19-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - a1905d4d by Duncan Coutts at 2024-04-02T13:22:19-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 13734227 by Duncan Coutts at 2024-04-02T13:22:19-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 1fc6ee4c by Duncan Coutts at 2024-04-02T13:22:19-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 2ac87360 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - b14bb8a2 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - 4922cb30 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Review feedback: simplify ./configure support for I/O managers Have all decisions be automatic without any user influence, rather than automatic with user-specified flags to override. This entails removing the existing --enable-native-io-manager flag. Also simplify the CPP flags defined by ./configure and have more stuff done by IOManager.h instead. This also gives us a place to put sanity checks for there being a default I/O manager. - - - - - 33350cbe by Duncan Coutts at 2024-04-02T13:22:19-04:00 Fixup: make showIOManager public (non-static) declare it in IOManager.h - - - - - 75507feb by Duncan Coutts at 2024-04-02T13:22:19-04:00 Include the default I/O manager in the +RTS --info output - - - - - b5fcc525 by Duncan Coutts at 2024-04-02T13:22:19-04:00 fixup: fix spelling in src/GHC/Internal/IO/SubSystem.hs - - - - - f936ecba by Duncan Coutts at 2024-04-02T13:22:19-04:00 fixup: fix spelling in rts/IOManager.h - - - - - 5b29b688 by Duncan Coutts at 2024-04-02T13:22:19-04:00 review feedback: document the post-condition of awaitCompletedTimeoutsOrIO - - - - - 1f7a18e3 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Document --io-manager flag in the user guide And the -Do debug flag. - - - - - c3cdce8a by Duncan Coutts at 2024-04-02T13:22:19-04:00 Use "unrecognised" rather than "unknown" for io-manager flag parsing Somewhat clearer meaning in the code and error messages. - - - - - 79bfa225 by Duncan Coutts at 2024-04-02T13:22:19-04:00 Re-export IoSubSystem from GHC.RTS.Flags with deprecation warning It was exported here previously. Reinstate the export for ease of migration, now with a deprecation warning for where to get it from instead. See https://github.com/haskell/core-libraries-committee/issues/263 - - - - - 8547e0a0 by Duncan Coutts at 2024-04-02T13:22:19-04:00 FIXUP: base-exports - - - - - 27d1a25b by Rodrigo Mesquita at 2024-04-02T13:22:20-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - 1f26c63b by Sylvain Henry at 2024-04-02T13:22:32-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 2e84acd9 by Sylvain Henry at 2024-04-02T13:22:32-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - 30 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/Language/Haskell/Syntax/Type.hs - docs/users_guide/runtime_control.rst - libraries/base/src/GHC/IO/SubSystem.hs - libraries/base/src/GHC/RTS/Flags.hs - libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs - libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - + m4/ghc_iomanagers.m4 - rts/Capability.c - rts/Capability.h - rts/IOManager.c - rts/IOManager.h - + rts/IOManagerInternals.h - rts/PrimOps.cmm - rts/RaiseAsync.c - rts/RtsFlags.c - rts/RtsFlags.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1c37c47130f1f78137f49a1bfb5e0e3dd322b37...2e84acd912d4db77a25cb68f434de8f41d30b455 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1c37c47130f1f78137f49a1bfb5e0e3dd322b37...2e84acd912d4db77a25cb68f434de8f41d30b455 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 19:53:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 15:53:14 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Message-ID: <660c622a2c0de_f9da2688790693ae@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9e0e56ef by Rodrigo Mesquita at 2024-04-02T15:52:53-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - 088d7cca by Sylvain Henry at 2024-04-02T15:52:56-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - beccd51a by Sylvain Henry at 2024-04-02T15:52:56-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - 1e9737cd by Simon Peyton Jones at 2024-04-02T15:52:57-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - 3dffa742 by Simon Peyton Jones at 2024-04-02T15:52:57-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 26 changed files: - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/Tc/Gen/HsType.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - rts/js/string.js - + testsuite/tests/javascript/Makefile - + testsuite/tests/javascript/T24495.hs - + testsuite/tests/javascript/T24495.stdout - testsuite/tests/javascript/all.T - testsuite/tests/saks/should_compile/saks018.hs - testsuite/tests/saks/should_compile/saks021.hs - testsuite/tests/saks/should_fail/all.T - + testsuite/tests/saks/should_fail/saks018-fail.hs - + testsuite/tests/saks/should_fail/saks018-fail.stderr - + testsuite/tests/saks/should_fail/saks021-fail.hs - + testsuite/tests/saks/should_fail/saks021-fail.stderr - testsuite/tests/typecheck/should_compile/T24470b.hs - + testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604.stderr - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -3023,7 +3023,7 @@ pushCoercionIntoLambda in_scope x e co | otherwise = Nothing -pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion +pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion -> Maybe (DataCon , [Type] -- Universal type args , [CoreExpr]) -- All other args incl existentials @@ -3033,10 +3033,20 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion -- where co :: (T t1 .. tn) ~ to_ty -- The left-hand one must be a T, because exprIsConApp returned True -- but the right-hand one might not be. (Though it usually will.) -pushCoDataCon dc dc_args co - | isReflCo co || from_ty `eqType` to_ty -- try cheap test first - , let (univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args - = Just (dc, map exprToType univ_ty_args, rest_args) +pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args) +pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co) + +push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr]) +push_dc_refl dc dc_args + = (dc, map exprToType univ_ty_args, rest_args) + where + !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args + +push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type + -> Maybe (DataCon, [Type], [CoreExpr]) +push_dc_gen dc dc_args co (Pair from_ty to_ty) + | from_ty `eqType` to_ty -- try cheap test first + = Just $! (push_dc_refl dc dc_args) | Just (to_tc, to_tc_arg_tys) <- splitTyConApp_maybe to_ty , to_tc == dataConTyCon dc @@ -3082,8 +3092,6 @@ pushCoDataCon dc dc_args co | otherwise = Nothing - where - Pair from_ty to_ty = coercionKind co collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr) -- Collect lambda binders, pushing coercions inside if possible ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1211,7 +1211,7 @@ data-con wrappers, and that cure would be worse than the disease. This Note exists solely to document the problem. -} -data ConCont = CC [CoreExpr] Coercion +data ConCont = CC [CoreExpr] MCoercion -- Substitution already applied -- | Returns @Just ([b1..bp], dc, [t1..tk], [x1..xn])@ if the argument @@ -1233,7 +1233,7 @@ exprIsConApp_maybe :: HasDebugCallStack => InScopeEnv -> CoreExpr -> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr]) exprIsConApp_maybe ise@(ISE in_scope id_unf) expr - = go (Left in_scope) [] expr (CC [] (mkRepReflCo (exprType expr))) + = go (Left in_scope) [] expr (CC [] MRefl) where go :: Either InScopeSet Subst -- Left in-scope means "empty substitution" @@ -1246,14 +1246,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr go subst floats (Tick t expr) cont | not (tickishIsCode t) = go subst floats expr cont - go subst floats (Cast expr co1) (CC args co2) + go subst floats (Cast expr co1) (CC args m_co2) | Just (args', m_co1') <- pushCoArgs (subst_co subst co1) args -- See Note [Push coercions in exprIsConApp_maybe] - = case m_co1' of - MCo co1' -> go subst floats expr (CC args' (co1' `mkTransCo` co2)) - MRefl -> go subst floats expr (CC args' co2) + = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2)) - go subst floats (App fun arg) (CC args co) + go subst floats (App fun arg) (CC args mco) | let arg_type = exprType arg , not (isTypeArg arg) && needsCaseBinding arg_type arg -- An unlifted argument that’s not ok for speculation must not simply be @@ -1276,17 +1274,17 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) float = FloatCase arg' bndr DEFAULT [] subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) co) + in go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise - = go subst floats fun (CC (subst_expr subst arg : args) co) + = go subst floats fun (CC (subst_expr subst arg : args) mco) - go subst floats (Lam bndr body) (CC (arg:args) co) + go subst floats (Lam bndr body) (CC (arg:args) mco) | do_beta_by_substitution bndr arg - = go (extend subst bndr arg) floats body (CC args co) + = go (extend subst bndr arg) floats body (CC args mco) | otherwise = let (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' arg) - in go subst' (float:floats) body (CC args co) + in go subst' (float:floats) body (CC args mco) go subst floats (Let (NonRec bndr rhs) expr) cont | not (isJoinId bndr) @@ -1311,12 +1309,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr (lookupIdSubst sub v) cont - go (Left in_scope) floats (Var fun) cont@(CC args co) + go (Left in_scope) floats (Var fun) cont@(CC args mco) | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun = succeedWith in_scope floats $ - pushCoDataCon con args co + pushCoDataCon con args mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1336,7 +1334,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplOptExpr initialises the in-scope set with exprFreeVars, -- but that doesn't account for DFun unfoldings = succeedWith in_scope floats $ - pushCoDataCon con (map (substExpr subst) dfun_args) co + pushCoDataCon con (map (substExpr subst) dfun_args) mco -- Look through unfoldings, but only arity-zero one; -- if arity > 0 we are effectively inlining a function call, @@ -1354,7 +1352,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr , [arg] <- args , Just (LitString str) <- exprIsLiteral_maybe ise arg = succeedWith in_scope floats $ - dealWithStringLiteral fun str co + dealWithStringLiteral fun str mco where unfolding = id_unf fun extend_in_scope unf_fvs @@ -1404,15 +1402,15 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- See Note [exprIsConApp_maybe on literal strings] -dealWithStringLiteral :: Var -> BS.ByteString -> Coercion +dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion -> Maybe (DataCon, [Type], [CoreExpr]) -- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS -- turns those into [] automatically, but just in case something else in GHC -- generates a string literal directly. -dealWithStringLiteral fun str co = +dealWithStringLiteral fun str mco = case utf8UnconsByteString str of - Nothing -> pushCoDataCon nilDataCon [Type charTy] co + Nothing -> pushCoDataCon nilDataCon [Type charTy] mco Just (char, charTail) -> let char_expr = mkConApp charDataCon [mkCharLit char] -- In singleton strings, just add [] instead of unpackCstring# ""#. @@ -1421,7 +1419,7 @@ dealWithStringLiteral fun str co = else App (Var fun) (Lit (LitString charTail)) - in pushCoDataCon consDataCon [Type charTy, char_expr, rest] co + in pushCoDataCon consDataCon [Type charTy, char_expr, rest] mco {- Note [Unfolding DFuns] ===================================== compiler/GHC/StgToJS/Apply.hs ===================================== @@ -46,7 +46,6 @@ import GHC.StgToJS.Rts.Types import GHC.StgToJS.Stack import GHC.StgToJS.Ids -import GHC.Types.Literal import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.CostCentre @@ -60,7 +59,6 @@ import GHC.Core.TyCon import GHC.Core.DataCon import GHC.Core.Type hiding (typeSize) -import GHC.Utils.Encoding import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic @@ -100,22 +98,6 @@ genApp -> G (JStgStat, ExprResult) genApp ctx i args - -- Case: unpackCStringAppend# "some string"# str - -- - -- Generates h$appendToHsStringA(str, "some string"), which has a faster - -- decoding loop. - | [StgLitArg (LitString bs), x] <- args - , [top] <- concatMap typex_expr (ctxTarget ctx) - , getUnique i == unpackCStringAppendIdKey - , d <- utf8DecodeByteString bs - = do - prof <- csProf <$> getSettings - let profArg = if prof then [jCafCCS] else [] - a <- genArg x - return ( top |= app "h$appendToHsStringA" (toJExpr d : a ++ profArg) - , ExprInline - ) - -- let-no-escape | Just n <- ctxLneBindingStackSize ctx i = do ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -60,11 +60,13 @@ import GHC.Types.Var.Set import GHC.Types.Id import GHC.Types.Unique.FM import GHC.Types.RepType +import GHC.Types.Literal import GHC.Stg.Syntax import GHC.Stg.Utils import GHC.Builtin.PrimOps +import GHC.Builtin.Names import GHC.Core hiding (Var) import GHC.Core.TyCon @@ -73,6 +75,7 @@ import GHC.Core.Opt.Arity (isOneShotBndr) import GHC.Core.Type hiding (typeSize) import GHC.Utils.Misc +import GHC.Utils.Encoding import GHC.Utils.Monad import GHC.Utils.Panic import GHC.Utils.Outputable (ppr, renderWithContext, defaultSDocContext) @@ -555,6 +558,36 @@ genCase :: HasDebugCallStack -> LiveVars -> G (JStgStat, ExprResult) genCase ctx bnd e at alts l + -- For: unpackCStringAppend# "some string"# str + -- Generate: h$appendToHsStringA(str, "some string") + -- + -- The latter has a faster decoding loop. + -- + -- Since #23270 and 7e0c8b3bab30, literals strings aren't STG atoms and we + -- need to match the following instead: + -- + -- case "some string"# of b { + -- DEFAULT -> unpackCStringAppend# b str + -- } + -- + -- Wrinkle: it doesn't kick in when literals are floated out to the top level. + -- + | StgLit (LitString bs) <- e + , [GenStgAlt DEFAULT _ rhs] <- alts + , StgApp i args <- rhs + , getUnique i == unpackCStringAppendIdKey + , [StgVarArg b',x] <- args + , bnd == b' + , d <- utf8DecodeByteString bs + , [top] <- concatMap typex_expr (ctxTarget ctx) + = do + prof <- csProf <$> getSettings + let profArg = if prof then [jCafCCS] else [] + a <- genArg x + return ( top |= app "h$appendToHsStringA" (toJExpr d : a ++ profArg) + , ExprInline + ) + | isInlineExpr e = do bndi <- identsForId bnd let ctx' = ctxSetTop bnd ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -191,6 +191,9 @@ genCommonCppDefs profiling = mconcat -- resumable thunks , "#define MAKE_RESUMABLE(closure,stack) { (closure).f = h$resume_e; (closure).d1 = (stack), (closure).d2 = null; }\n" + -- making a thunk + , "#define MK_UPD_THUNK(closure) h$c1(h$upd_thunk_e,(closure))\n" + -- general deconstruction , "#define IS_THUNK(x) ((x).f.t === CLOSURE_TYPE_THUNK)\n" , "#define CONSTR_TAG(x) ((x).f.a)\n" ===================================== compiler/GHC/StgToJS/Rts/Rts.hs ===================================== @@ -448,6 +448,19 @@ rts_gen s = do , r4 |= d4 , returnS (app "h$ap_3_3_fast" []) ]) + , closure (ClosureInfo (TxtI "h$upd_thunk_e") (CIRegs 0 [PtrV]) "updatable thunk" (CILayoutFixed 1 [PtrV]) CIThunk mempty) + (jVar $ \t -> return $ + mconcat [t |= closureField1 r1 + , adjSp' 2 + , stack .! (sp - 1) |= r1 + , stack .! sp |= var "h$upd_frame" + , closureEntry r1 |= var "h$blackhole" + , closureField1 r1 |= var "h$currentThread" + , closureField2 r1 |= null_ + , r1 |= t + , returnS (app "h$ap_0_0_fast" []) + ] + ) -- select first field , closure (ClosureInfo (global "h$select1_e") (CIRegs 0 [PtrV]) "select1" (CILayoutFixed 1 [PtrV]) CIThunk mempty) (jVar \t -> return $ ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2570,9 +2570,11 @@ kcCheckDeclHeader_sig sig_kind name flav ; traceTc "kcCheckDeclHeader_sig {" $ vcat [ text "sig_kind:" <+> ppr sig_kind , text "sig_tcbs:" <+> ppr sig_tcbs - , text "sig_res_kind:" <+> ppr sig_res_kind ] + , text "sig_res_kind:" <+> ppr sig_res_kind + , text "implict_nms:" <+> ppr implicit_nms + , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2615,9 +2617,18 @@ kcCheckDeclHeader_sig sig_kind name flav -- Here p and q both map to the same kind variable k. We don't allow this -- so we must check that they are distinct. A similar thing happens -- in GHC.Tc.TyCl.swizzleTcTyConBinders during inference. + -- + -- With visible dependent quantification, one of the binders involved + -- may be explicit. Consider #24604 + -- type UF :: forall zk -> zk -> Constraint + -- class UF kk (xb :: k) + -- Here `k` and `kk` both denote the same variable; but only `k` is implicit + -- Hence we need to add skol_scoped_tvs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - ; checkForDuplicateScopedTyVars implicit_prs + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs + ; unless (null implicit_nms) $ -- No need if no implicit tyvars + checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs -- Swizzle the Names so that the TyCon uses the user-declared implicit names @@ -2686,6 +2697,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Skolem tyvars brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2696,7 +2708,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2712,17 +2724,22 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- that come from the type declaration, not the kind signature subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } + -- We do a tcExtendTyVarEnv [tv'], so we return tv' in + -- the list of lexically-scoped skolem type variables | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2736,14 +2753,19 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside = return () tc_hs_bndr (KindedTyVar _ _ (L _ hs_nm) lhs_kind) expected_kind = do { sig_kind <- tcLHsKindSig (TyVarBndrKindCtxt hs_nm) lhs_kind + ; traceTc "musd3:unifying" (ppr sig_kind $$ ppr expected_kind) ; discardResult $ -- See Note [discardResult in kcCheckDeclHeader_sig] unifyKind (Just (NameThing hs_nm)) sig_kind expected_kind } -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. @@ -3007,15 +3029,7 @@ checkForDisconnectedScopedTyVars name flav all_tcbs scoped_prs checkForDuplicateScopedTyVars :: [(Name,TcTyVar)] -> TcM () -- Check for duplicates --- E.g. data SameKind (a::k) (b::k) --- data T (a::k1) (b::k2) c = MkT (SameKind a b) c --- Here k1 and k2 start as TyVarTvs, and get unified with each other --- If this happens, things get very confused later, so fail fast --- --- In the CUSK case k1 and k2 are skolems so they won't unify; --- but in the inference case (see generaliseTcTyCon), --- and the type-sig case (see kcCheckDeclHeader_sig), they are --- TcTyVars, so we must check. +-- See Note [Aliasing in type and class declarations] checkForDuplicateScopedTyVars scoped_prs = unless (null err_prs) $ do { mapM_ report_dup err_prs; failM } @@ -3035,8 +3049,43 @@ checkForDuplicateScopedTyVars scoped_prs addErrTc $ TcRnDifferentNamesForTyVar n1 n2 -{- Note [Disconnected type variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Aliasing in type and class declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + data SameKind (a::k) (b::k) + data T1 (a::k1) (b::k2) c = MkT (SameKind a b) c +We do not allow this, because `k1` and `k2` would both stand for the same type +variable -- they are both aliases for `k`. + +Other examples + data T2 (a::k1) = MkT2 (SameKind a Int) -- k1 stands for Type + data T3 @k1 @k2 (a::k1) (b::k2) = MkT (SameKind a b) -- k1 and k2 are aliases + + type UF :: forall zk. zk -> Constraint + class UF @kk (xb :: k) where -- kk and k are aliases + op :: (xs::kk) -> Bool + +See #24604 for an example that crashed GHC. + +There is a design choice here. It would be possible to allow implicit type variables +like `k1` and `k2` in T1's declartion to stand for /abitrary kinds/. This is in fact +the rule we use in /terms/ pattern signatures: + f :: [Int] -> Int + f ((x::a) : xs) = ... +Here `a` stands for `Int`. But in type /signatures/ we make a different choice: + f1 :: forall (a::k1) (b::k2). SameKind a b -> blah + f2 :: forall (a::k). SameKind a Int -> blah + +Here f1's signature is rejected because `k1` and `k2` are aliased; and f2's is +rejected because `k` stands for `Int`. + +Our current choice is that type and class declarations behave more like signatures; +we do not allow aliasing. That is what `checkForDuplicateScopedTyVars` checks. +See !12328 for some design discussion. + + +Note [Disconnected type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This note applies when kind-checking the header of a type/class decl that has a separate, standalone kind signature. See #24083. ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -1,3 +1,4 @@ +{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} ===================================== rts/js/string.js ===================================== @@ -723,7 +723,10 @@ function h$appendToHsStringA(str, appendTo, cc) { function h$appendToHsStringA(str, appendTo) { #endif var i = str.length - 1; - var r = appendTo; + // we need to make an updatable thunk here + // if we embed the given closure in a CONS cell. + // (#24495) + var r = i == 0 ? appendTo : MK_UPD_THUNK(appendTo); while(i>=0) { r = MK_CONS_CC(str.charCodeAt(i), r, cc); --i; ===================================== testsuite/tests/javascript/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +T24495: + '$(TEST_HC)' $(TEST_HC_OPTS) T24495.hs -v0 -O1 -dsuppress-uniques -ddump-js -ddump-to-file + ./T24495 + # check that the optimization occurred + grep -c appendToHsStringA T24495.dump-js ===================================== testsuite/tests/javascript/T24495.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_GHC -O1 #-} +-- -O1 required to make "rest" thunk SingleEntry + +module Main where + +import GHC.CString +import GHC.JS.Prim (JSVal, toJSString) + +foo :: Double -> IO () +foo x = debugString (toJSString ("2 " ++ s)) + where + x' = if x == 0 then "b" else "c" + y' = if x == 0 then "b" else "c" + s = "a" ++ x' ++ " " ++ y' ++ "d" + +main :: IO () +main = foo 0 + + +foreign import javascript "((s) => { console.log(s); })" + debugString :: JSVal -> IO () ===================================== testsuite/tests/javascript/T24495.stdout ===================================== @@ -0,0 +1,2 @@ +2 ab bd +2 ===================================== testsuite/tests/javascript/all.T ===================================== @@ -21,3 +21,4 @@ test('js-mk_tup', extra_files(['test-mk_tup.js']), compile_and_run, ['test-mk_tu test('T23346', normal, compile_and_run, ['']) test('T22455', normal, compile_and_run, ['-ddisable-js-minifier']) test('T23565', normal, compile_and_run, ['']) +test('T24495', normal, makefile_test, ['T24495']) ===================================== testsuite/tests/saks/should_compile/saks018.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_018 where import Data.Kind (Type) type T :: forall k -> k -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_compile/saks021.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_021 where import Data.Kind (Type) type T :: forall k -> forall (xx :: k) -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -36,3 +36,5 @@ test('T18863b', normal, compile_fail, ['']) test('T18863c', normal, compile_fail, ['']) test('T18863d', normal, compile_fail, ['']) test('T20916', normal, compile_fail, ['']) +test('saks018-fail', normal, compile_fail, ['']) +test('saks021-fail', normal, compile_fail, ['']) ===================================== testsuite/tests/saks/should_fail/saks018-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_018 where + +import Data.Kind (Type) + +type T :: forall k -> k -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks018-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks018-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/saks/should_fail/saks021-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_021 where + +import Data.Kind (Type) + +type T :: forall k -> forall (xx :: k) -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks021-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks021-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_compile/T24470b.hs ===================================== @@ -7,4 +7,4 @@ import Data.Kind import Data.Data type SynOK :: forall k. k -> Type -type SynOK @t = Proxy :: j -> Type +type SynOK @j = Proxy :: j -> Type ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -0,0 +1,7 @@ +module T24604 where + +import Data.Kind + +type UF :: forall zk -> zk -> Constraint +class UF kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604.hs:6:10: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -17,4 +17,6 @@ test('T23738_fail_implicit_tv', normal, compile_fail, ['']) test('T23738_fail_var', normal, compile_fail, ['']) test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) -test('T23739_fail_case', normal, compile_fail, ['']) \ No newline at end of file +test('T23739_fail_case', normal, compile_fail, ['']) +test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e84acd912d4db77a25cb68f434de8f41d30b455...3dffa74229386b4a9a8d4c0de2bee084bc53e0ac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e84acd912d4db77a25cb68f434de8f41d30b455...3dffa74229386b4a9a8d4c0de2bee084bc53e0ac You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 20:22:48 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 16:22:48 -0400 Subject: [Git][ghc/ghc][wip/simplifier-tweaks] 18 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660c691883dcf_f9da2b476f0824e4@gitlab.mail> Simon Peyton Jones pushed to branch wip/simplifier-tweaks at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - c93eecf1 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 0a2c3c2d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 6d605aa5 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 447f2ac0 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Spelling, layout, pretty-printing only - - - - - f36b9603 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 7fc8cfc3 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - a818823d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - c471144d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - 346115e0 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Remove a long-commented-out line Pure refactoring - - - - - 57f42293 by Simon Peyton Jones at 2024-04-02T21:20:49+01:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - ec584eaf by Simon Peyton Jones at 2024-04-02T21:21:23+01:00 Testsuite message changes from simplifier improvements - - - - - 9c910ae1 by Simon Peyton Jones at 2024-04-02T21:21:23+01:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 15 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/848f360fe1bcbdac28e9cc0014665bf8ccbfd259...9c910ae1a616e74f5389828ad9b9126d0282764e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/848f360fe1bcbdac28e9cc0014665bf8ccbfd259...9c910ae1a616e74f5389828ad9b9126d0282764e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 20:43:17 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 02 Apr 2024 16:43:17 -0400 Subject: [Git][ghc/ghc][wip/template-haskell-stability] 1033 commits: primops: Introduce unsafeThawByteArray# Message-ID: <660c6de5b5ff6_f9da2f9066c8826f@gitlab.mail> Ben Gamari pushed to branch wip/template-haskell-stability at Glasgow Haskell Compiler / GHC Commits: c30cea53 by Ben Gamari at 2023-07-21T23:23:49-04:00 primops: Introduce unsafeThawByteArray# This addresses an odd asymmetry in the ByteArray# primops, which previously provided unsafeFreezeByteArray# but no corresponding thaw operation. Closes #22710 - - - - - 87f9bd47 by Ben Gamari at 2023-07-21T23:23:49-04:00 testsuite: Elaborate in interface stability README This discussion didn't make it into the original MR. - - - - - e4350b41 by Matthew Pickering at 2023-07-21T23:24:25-04:00 Allow users to override non-essential haddock options in a Flavour We now supply the non-essential options to haddock using the `extraArgs` field, which can be specified in a Flavour so that if an advanced user wants to change how documentation is generated then they can use something other than the `defaultHaddockExtraArgs`. This does have the potential to regress some packaging if a user has overridden `extraArgs` themselves, because now they also need to add the haddock options to extraArgs. This can easily be done by appending `defaultHaddockExtraArgs` to their extraArgs invocation but someone might not notice this behaviour has changed. In any case, I think passing the non-essential options in this manner is the right thing to do and matches what we do for the "ghc" builder, which by default doesn't pass any optmisation levels, and would likewise be very bad if someone didn't pass suitable `-O` levels for builds. Fixes #23625 - - - - - fc186b0c by Ilias Tsitsimpis at 2023-07-21T23:25:03-04:00 ghc-prim: Link against libatomic Commit b4d39adbb58 made 'hs_cmpxchg64()' available to all architectures. Unfortunately this made GHC to fail to build on armel, since armel needs libatomic to support atomic operations on 64-bit word sizes. Configure libraries/ghc-prim/ghc-prim.cabal to link against libatomic, the same way as we do in rts/rts.cabal. - - - - - 4f5538a8 by Matthew Pickering at 2023-07-21T23:25:39-04:00 simplifier: Correct InScopeSet in rule matching The in-scope set passedto the `exprIsLambda_maybe` call lacked all the in-scope binders. @simonpj suggests this fix where we augment the in-scope set with the free variables of expression which fixes this failure mode in quite a direct way. Fixes #23630 - - - - - 5ad8d597 by Krzysztof Gogolewski at 2023-07-21T23:26:17-04:00 Add a test for #23413 It was fixed by commit e1590ddc661d6: Add the SolverStage monad. - - - - - 7e05f6df by sheaf at 2023-07-21T23:26:56-04:00 Finish migration of diagnostics in GHC.Tc.Validity This patch finishes migrating the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It also refactors the error message datatypes for class and family instances, to common them up under a single datatype as much as possible. - - - - - 4876fddc by Matthew Pickering at 2023-07-21T23:27:33-04:00 ci: Enable some more jobs to run in a marge batch In !10907 I made the majority of jobs not run on a validate pipeline but then forgot to renable a select few jobs on the marge batch MR. - - - - - 026991d7 by Jens Petersen at 2023-07-21T23:28:13-04:00 user_guide/flags.py: python-3.12 no longer includes distutils packaging.version seems able to handle this fine - - - - - b91bbc2b by Matthew Pickering at 2023-07-21T23:28:50-04:00 ci: Mention ~full-ci label in MR template We mention that if you need a full validation pipeline then you can apply the ~full-ci label to your MR in order to test against the full validation pipeline (like we do for marge). - - - - - 42b05e9b by sheaf at 2023-07-22T12:36:00-04:00 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 - - - - - a72015d6 by sheaf at 2023-07-22T12:36:01-04:00 Mark plugins-external as broken on Windows This test is broken on Windows, so we explicitly mark it as such now that we stop skipping plugin tests on Windows. - - - - - cb9c93d7 by sheaf at 2023-07-22T12:36:01-04:00 Stop marking plugin tests as fragile on Windows Now that b2bb3e62 has landed we are in a better situation with regards to plugins on Windows, allowing us to unmark many plugin tests as fragile. Fixes #16405 - - - - - a7349217 by Krzysztof Gogolewski at 2023-07-22T12:36:37-04:00 Misc cleanup - Remove unused RDR names - Fix typos in comments - Deriving: simplify boxConTbl and remove unused litConTbl - chmod -x GHC/Exts.hs, this seems accidental - - - - - 33b6850a by Vladislav Zavialov at 2023-07-23T10:27:37-04:00 Visible forall in types of terms: Part 1 (#22326) This patch implements part 1 of GHC Proposal #281, introducing explicit `type` patterns and `type` arguments. Summary of the changes: 1. New extension flag: RequiredTypeArguments 2. New user-facing syntax: `type p` patterns (represented by EmbTyPat) `type e` expressions (represented by HsEmbTy) 3. Functions with required type arguments (visible forall) can now be defined and applied: idv :: forall a -> a -> a -- signature (relevant change: checkVdqOK in GHC/Tc/Validity.hs) idv (type a) (x :: a) = x -- definition (relevant change: tcPats in GHC/Tc/Gen/Pat.hs) x = idv (type Int) 42 -- usage (relevant change: tcInstFun in GHC/Tc/Gen/App.hs) 4. template-haskell support: TH.TypeE corresponds to HsEmbTy TH.TypeP corresponds to EmbTyPat 5. Test cases and a new User's Guide section Changes *not* included here are the t2t (term-to-type) transformation and term variable capture; those belong to part 2. - - - - - 73b5c7ce by sheaf at 2023-07-23T10:28:18-04:00 Add test for #22424 This is a simple Template Haskell test in which we refer to record selectors by their exact Names, in two different ways. Fixes #22424 - - - - - 83cbc672 by Ben Gamari at 2023-07-24T07:40:49+00:00 ghc-toolchain: Initial commit - - - - - 31dcd26c by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 ghc-toolchain: Toolchain Selection This commit integrates ghc-toolchain, the brand new way of configuring toolchains for GHC, with the Hadrian build system, with configure, and extends and improves the first iteration of ghc-toolchain. The general overview is * We introduce a program invoked `ghc-toolchain --triple=...` which, when run, produces a file with a `Target`. A `GHC.Toolchain.Target.Target` describes the properties of a target and the toolchain (executables and configured flags) to produce code for that target * Hadrian was modified to read Target files, and will both * Invoke the toolchain configured in the Target file as needed * Produce a `settings` file for GHC based on the Target file for that stage * `./configure` will invoke ghc-toolchain to generate target files, but it will also generate target files based on the flags configure itself configured (through `.in` files that are substituted) * By default, the Targets generated by configure are still (for now) the ones used by Hadrian * But we additionally validate the Target files generated by ghc-toolchain against the ones generated by configure, to get a head start on catching configuration bugs before we transition completely. * When we make that transition, we will want to drop a lot of the toolchain configuration logic from configure, but keep it otherwise. * For each compiler stage we should have 1 target file (up to a stage compiler we can't run in our machine) * We just have a HOST target file, which we use as the target for stage0 * And a TARGET target file, which we use for stage1 (and later stages, if not cross compiling) * Note there is no BUILD target file, because we only support cross compilation where BUILD=HOST * (for more details on cross-compilation see discussion on !9263) See also * Note [How we configure the bundled windows toolchain] * Note [ghc-toolchain consistency checking] * Note [ghc-toolchain overview] Ticket: #19877 MR: !9263 - - - - - a732b6d3 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Add flag to enable/disable ghc-toolchain based configurations This flag is disabled by default, and we'll use the configure-generated-toolchains by default until we remove the toolchain configuration logic from configure. - - - - - 61eea240 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Split ghc-toolchain executable to new packge In light of #23690, we split the ghc-toolchain executable out of the library package to be able to ship it in the bindist using Hadrian. Ideally, we eventually revert this commit. - - - - - 38e795ff by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Ship ghc-toolchain in the bindist Add the ghc-toolchain binary to the binary distribution we ship to users, and teach the bindist configure to use the existing ghc-toolchain. - - - - - 32cae784 by Matthew Craven at 2023-07-24T16:48:24-04:00 Kill off gen_bytearray_addr_access_ops.py The relevant primop descriptions are now generated directly by genprimopcode. This makes progress toward fixing #23490, but it is not a complete fix since there is more than one way in which cabal-reinstall (hadrian/build build-cabal) is broken. - - - - - 02e6a6ce by Matthew Pickering at 2023-07-24T16:49:00-04:00 compiler: Remove unused `containers.h` include Fixes #23712 - - - - - 822ef66b by Matthew Pickering at 2023-07-25T08:44:50-04:00 Fix pretty printing of WARNING pragmas There is still something quite unsavoury going on with WARNING pragma printing because the printing relies on the fact that for decl deprecations the SourceText of WarningTxt is empty. However, I let that lion sleep and just fixed things directly. Fixes #23465 - - - - - e7b38ede by Matthew Pickering at 2023-07-25T08:45:28-04:00 ci-images: Bump to commit which has 9.6 image The test-bootstrap job has been failing for 9.6 because we accidentally used a non-master commit. - - - - - bb408936 by Matthew Pickering at 2023-07-25T08:45:28-04:00 Update bootstrap plans for 9.6.2 and 9.4.5 - - - - - 355e1792 by Alan Zimmerman at 2023-07-26T10:17:32-04:00 EPA: Simplify GHC/Parser.y comb4/comb5 Use the HasLoc instance from Ast.hs to allow comb4/comb5 to work with anything with a SrcSpan Also get rid of some more now unnecessary reLoc calls. - - - - - 9393df83 by Gavin Zhao at 2023-07-26T10:18:16-04:00 compiler: make -ddump-asm work with wasm backend NCG Fixes #23503. Now the `-ddump-asm` flag is respected in the wasm backend NCG, so developers can directly view the generated ASM instead of needing to pass `-S` or `-keep-tmp-files` and manually find & open the assembly file. Ideally, we should be able to output the assembly files in smaller chunks like in other NCG backends. This would also make dumping assembly stats easier. However, this would require a large refactoring, so for short-term debugging purposes I think the current approach works fine. Signed-off-by: Gavin Zhao <git at gzgz.dev> - - - - - 79463036 by Krzysztof Gogolewski at 2023-07-26T10:18:54-04:00 llvm: Restore accidentally deleted code in 0fc5cb97 Fixes #23711 - - - - - 20db7e26 by Rodrigo Mesquita at 2023-07-26T10:19:33-04:00 configure: Default missing options to False when preparing ghc-toolchain Targets This commit fixes building ghc with 9.2 as the boostrap compiler. The ghc-toolchain patch assumed all _STAGE0 options were available, and forgot to account for this missing information in 9.2. Ghc 9.2 does not have in settings whether ar supports -l, hence can't report it with --info (unliked 9.4 upwards). The fix is to default the missing information (we default "ar supports -l" and other missing options to False) - - - - - fac9e84e by Naïm Favier at 2023-07-26T10:20:16-04:00 docs: Fix typo - - - - - 503fd647 by Bartłomiej Cieślar at 2023-07-26T17:23:10-04:00 This MR is an implementation of the proposal #516. It adds a warning -Wincomplete-record-selectors for usages of a record field access function (either a record selector or getField @"rec"), while trying to silence the warning whenever it can be sure that a constructor without the record field would not be invoked (which would otherwise cause the program to fail). For example: data T = T1 | T2 {x :: Bool} f a = x a -- this would throw an error g T1 = True g a = x a -- this would not throw an error h :: HasField "x" r Bool => r -> Bool h = getField @"x" j :: T -> Bool j = h -- this would throw an error because of the `HasField` -- constraint being solved See the tests DsIncompleteRecSel* and TcIncompleteRecSel for more examples of the warning. See Note [Detecting incomplete record selectors] in GHC.HsToCore.Expr for implementation details - - - - - af6fdf42 by Arnaud Spiwack at 2023-07-26T17:23:52-04:00 Fix user-facing label in MR template - - - - - 5d45b92a by Matthew Pickering at 2023-07-27T05:46:46-04:00 ci: Test bootstrapping configurations with full-ci and on marge batches There have been two incidents recently where bootstrapping has been broken by removing support for building with 9.2.*. The process for bumping the minimum required version starts with bumping the configure version and then other CI jobs such as the bootstrap jobs have to be updated. We must not silently bump the minimum required version. Now we are running a slimmed down validate pipeline it seems worthwile to test these bootstrap configurations in the full-ci pipeline. - - - - - 25d4fee7 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Remove ghc-9_2_* plans We are anticipating shortly making it necessary to use ghc-9.4 to boot the compiler. - - - - - 2f66da16 by Matthew Pickering at 2023-07-27T05:46:46-04:00 Update bootstrap plans for ghc-platform and ghc-toolchain dependencies Fixes #23735 - - - - - c8c6eab1 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Disable -selftest flag from bootstrap plans This saves on building one dependency (QuickCheck) which is unecessary for bootstrapping. - - - - - a80ca086 by Andrew Lelechenko at 2023-07-27T05:47:26-04:00 Link reference paper and package from System.Mem.{StableName,Weak} - - - - - a5319358 by David Knothe at 2023-07-28T13:13:10-04:00 Update Match Datatype EquationInfo currently contains a list of the equation's patterns together with a CoreExpr that is to be evaluated after a successful match on this equation. All the match-functions only operate on the first pattern of an equation - after successfully matching it, match is called recursively on the tail of the pattern list. We can express this more clearly and make the code a little more elegant by updating the datatype of EquationInfo as follows: data EquationInfo = EqnMatch { eqn_pat = Pat GhcTc, eqn_rest = EquationInfo } | EqnDone { eqn_rhs = MatchResult CoreExpr } An EquationInfo now explicitly exposes its first pattern which most functions operate on, and exposes the equation that remains after processing the first pattern. An EqnDone signifies an empty equation where the CoreExpr can now be evaluated. - - - - - 86ad1af9 by David Binder at 2023-07-28T13:13:53-04:00 Improve documentation for Data.Fixed - - - - - f8fa1d08 by Ben Gamari at 2023-07-28T13:14:31-04:00 ghc-prim: Use C11 atomics Previously `ghc-prim`'s atomic wrappers used the legacy `__sync_*` family of C builtins. Here we refactor these to rather use the appropriate C11 atomic equivalents, allowing us to be more explicit about the expected ordering semantics. - - - - - 0bfc8908 by Finley McIlwaine at 2023-07-28T18:46:26-04:00 Include -haddock in DynFlags fingerprint The -haddock flag determines whether or not the resulting .hi files contain haddock documentation strings. If the existing .hi files do not contain haddock documentation strings and the user requests them, we should recompile. - - - - - 40425c50 by Andreas Klebinger at 2023-07-28T18:47:02-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - e9a0fa3f by Andrew Lelechenko at 2023-07-28T18:47:42-04:00 Bump filepath submodule to 1.4.100.4 Resolves #23741 Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T12234 T12425 T13035 T13701 T13719 T16875 T18304 T18698a T18698b T21839c T9198 TcPlugin_RewritePerf hard_hole_fits Metric decrease on Windows can be probably attributed to https://github.com/haskell/filepath/pull/183 - - - - - ee93edfd by Andrew Lelechenko at 2023-07-28T18:48:21-04:00 Add since pragmas to GHC.IO.Handle.FD - - - - - d0369802 by Simon Peyton Jones at 2023-07-30T09:24:48+01:00 Make the occurrence analyser smarter about join points This MR addresses #22404. There is a big Note Note [Occurrence analysis for join points] that explains it all. Significant changes * New field occ_join_points in OccEnv * The NonRec case of occAnalBind splits into two cases: one for existing join points (which does the special magic for Note [Occurrence analysis for join points], and one for other bindings. * mkOneOcc adds in info from occ_join_points. * All "bring into scope" activity is centralised in the new function `addInScope`. * I made a local data type LocalOcc for use inside the occurrence analyser It is like OccInfo, but lacks IAmDead and IAmALoopBreaker, which in turn makes computationns over it simpler and more efficient. * I found quite a bit of allocation in GHC.Core.Rules.getRules so I optimised it a bit. More minor changes * I found I was using (Maybe Arity) a lot, so I defined a new data type JoinPointHood and used it everwhere. This touches a lot of non-occ-anal files, but it makes everything more perspicuous. * Renamed data constructor WithUsageDetails to WUD, and WithTailUsageDetails to WTUD This also fixes #21128, on the way. --------- Compiler perf ----------- I spent quite a time on performance tuning, so even though it does more than before, the occurrence analyser runs slightly faster on average. Here are the compile-time allocation changes over 0.5% CoOpt_Read(normal) ghc/alloc 766,025,520 754,561,992 -1.5% CoOpt_Singletons(normal) ghc/alloc 759,436,840 762,925,512 +0.5% LargeRecord(normal) ghc/alloc 1,814,482,440 1,799,530,456 -0.8% PmSeriesT(normal) ghc/alloc 68,159,272 67,519,720 -0.9% T10858(normal) ghc/alloc 120,805,224 118,746,968 -1.7% T11374(normal) ghc/alloc 164,901,104 164,070,624 -0.5% T11545(normal) ghc/alloc 79,851,808 78,964,704 -1.1% T12150(optasm) ghc/alloc 73,903,664 71,237,544 -3.6% GOOD T12227(normal) ghc/alloc 333,663,200 331,625,864 -0.6% T12234(optasm) ghc/alloc 52,583,224 52,340,344 -0.5% T12425(optasm) ghc/alloc 81,943,216 81,566,720 -0.5% T13056(optasm) ghc/alloc 294,517,928 289,642,512 -1.7% T13253-spj(normal) ghc/alloc 118,271,264 59,859,040 -49.4% GOOD T15164(normal) ghc/alloc 1,102,630,352 1,091,841,296 -1.0% T15304(normal) ghc/alloc 1,196,084,000 1,166,733,000 -2.5% T15630(normal) ghc/alloc 148,729,632 147,261,064 -1.0% T15703(normal) ghc/alloc 379,366,664 377,600,008 -0.5% T16875(normal) ghc/alloc 32,907,120 32,670,976 -0.7% T17516(normal) ghc/alloc 1,658,001,888 1,627,863,848 -1.8% T17836(normal) ghc/alloc 395,329,400 393,080,248 -0.6% T18140(normal) ghc/alloc 71,968,824 73,243,040 +1.8% T18223(normal) ghc/alloc 456,852,568 453,059,088 -0.8% T18282(normal) ghc/alloc 129,105,576 131,397,064 +1.8% T18304(normal) ghc/alloc 71,311,712 70,722,720 -0.8% T18698a(normal) ghc/alloc 208,795,112 210,102,904 +0.6% T18698b(normal) ghc/alloc 230,320,736 232,697,976 +1.0% BAD T19695(normal) ghc/alloc 1,483,648,128 1,504,702,976 +1.4% T20049(normal) ghc/alloc 85,612,024 85,114,376 -0.6% T21839c(normal) ghc/alloc 415,080,992 410,906,216 -1.0% GOOD T4801(normal) ghc/alloc 247,590,920 250,726,272 +1.3% T6048(optasm) ghc/alloc 95,699,416 95,080,680 -0.6% T783(normal) ghc/alloc 335,323,384 332,988,120 -0.7% T9233(normal) ghc/alloc 709,641,224 685,947,008 -3.3% GOOD T9630(normal) ghc/alloc 965,635,712 948,356,120 -1.8% T9675(optasm) ghc/alloc 444,604,152 428,987,216 -3.5% GOOD T9961(normal) ghc/alloc 303,064,592 308,798,800 +1.9% BAD WWRec(normal) ghc/alloc 503,728,832 498,102,272 -1.1% geo. mean -1.0% minimum -49.4% maximum +1.9% In fact these figures seem to vary between platforms; generally worse on i386 for some reason. The Windows numbers vary by 1% espec in benchmarks where the total allocation is low. But the geom mean stays solidly negative, which is good. The "increase/decrease" list below covers all platforms. The big win on T13253-spj comes because it has a big nest of join points, each occurring twice in the next one. The new occ-anal takes only one iteration of the simplifier to do the inlining; the old one took four. Moreover, we get much smaller code with the new one: New: Result size of Tidy Core = {terms: 429, types: 84, coercions: 0, joins: 14/14} Old: Result size of Tidy Core = {terms: 2,437, types: 304, coercions: 0, joins: 10/10} --------- Runtime perf ----------- No significant changes in nofib results, except a 1% reduction in compiler allocation. Metric Decrease: CoOpt_Read T13253-spj T9233 T9630 T9675 T12150 T21839c LargeRecord MultiComponentModulesRecomp T10421 T13701 T10421 T13701 T12425 Metric Increase: T18140 T9961 T18282 T18698a T18698b T19695 - - - - - 42aa7fbd by Julian Ospald at 2023-07-30T17:22:01-04:00 Improve documentation around IOException and ioe_filename See: * https://github.com/haskell/core-libraries-committee/issues/189 * https://github.com/haskell/unix/pull/279 * https://github.com/haskell/unix/pull/289 - - - - - 33598ecb by Sylvain Henry at 2023-08-01T14:45:54-04:00 JS: implement getMonotonicTime (fix #23687) - - - - - d2bedffd by Bartłomiej Cieślar at 2023-08-01T14:46:40-04:00 Implementation of the Deprecated Instances proposal #575 This commit implements the ability to deprecate certain instances, which causes the compiler to emit the desired deprecation message whenever they are instantiated. For example: module A where class C t where instance {-# DEPRECATED "dont use" #-} C Int where module B where import A f :: C t => t f = undefined g :: Int g = f -- "dont use" emitted here The implementation is as follows: - In the parser, we parse deprecations/warnings attached to instances: instance {-# DEPRECATED "msg" #-} Show X deriving instance {-# WARNING "msg2" #-} Eq Y (Note that non-standalone deriving instance declarations do not support this mechanism.) - We store the resulting warning message in `ClsInstDecl` (respectively, `DerivDecl`). In `GHC.Tc.TyCl.Instance.tcClsInstDecl` (respectively, `GHC.Tc.Deriv.Utils.newDerivClsInst`), we pass on that information to `ClsInst` (and eventually store it in `IfaceClsInst` too). - Finally, when we solve a constraint using such an instance, in `GHC.Tc.Instance.Class.matchInstEnv`, we emit the appropriate warning that was stored in `ClsInst`. Note that we only emit a warning when the instance is used in a different module than it is defined, which keeps the behaviour in line with the deprecation of top-level identifiers. Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - d5a65af6 by Ben Gamari at 2023-08-01T14:47:18-04:00 compiler: Style fixes - - - - - 7218c80a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Fix implicit cast This ensures that Task.h can be built with a C++ compiler. - - - - - d6d5aafc by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Fix warning in hs_try_putmvar001 - - - - - d9eddf7a by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Add AtomicModifyIORef test - - - - - f9eea4ba by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce NO_WARN macro This allows fine-grained ignoring of warnings. - - - - - 497b24ec by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Simplify atomicModifyMutVar2# implementation Previously we would perform a redundant load in the non-threaded RTS in atomicModifyMutVar2# implementation for the benefit of the non-moving GC's write barrier. Eliminate this. - - - - - 52ee082b by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce more principled fence operations - - - - - cd3c0377 by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce SET_INFO_RELAXED - - - - - 6df2352a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Style fixes - - - - - 4ef6f319 by Ben Gamari at 2023-08-01T14:47:19-04:00 codeGen/tsan: Rework handling of spilling - - - - - f9ca7e27 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More debug information - - - - - df4153ac by Ben Gamari at 2023-08-01T14:47:19-04:00 Improve TSAN documentation - - - - - fecae988 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More selective TSAN instrumentation - - - - - 465a9a0b by Alan Zimmerman at 2023-08-01T14:47:56-04:00 EPA: Provide correct annotation span for ImportDecl Use the whole declaration, rather than just the span of the 'import' keyword. Metric Decrease: T9961 T5205 Metric Increase: T13035 - - - - - ae63d0fa by Bartłomiej Cieślar at 2023-08-01T14:48:40-04:00 Add cases to T23279: HasField for deprecated record fields This commit adds additional tests from ticket #23279 to ensure that we don't regress on reporting deprecated record fields in conjunction with HasField, either when using overloaded record dot syntax or directly through `getField`. Fixes #23279 - - - - - 00fb6e6b by Andreas Klebinger at 2023-08-01T14:49:17-04:00 AArch NCG: Pure refactor Combine some alternatives. Add some line breaks for overly long lines - - - - - 8f3b3b78 by Andreas Klebinger at 2023-08-01T14:49:54-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - 74a882dc by MorrowM at 2023-08-02T06:00:03-04:00 Add a RULE to make lookup fuse See https://github.com/haskell/core-libraries-committee/issues/175 Metric Increase: T18282 - - - - - cca74dab by Ben Gamari at 2023-08-02T06:00:39-04:00 hadrian: Ensure that way-flags are passed to CC Previously the way-specific compilation flags (e.g. `-DDEBUG`, `-DTHREADED_RTS`) would not be passed to the CC invocations. This meant that C dependency files would not correctly reflect dependencies predicated on the way, resulting in the rather painful #23554. Closes #23554. - - - - - 622b483c by Jaro Reinders at 2023-08-02T06:01:20-04:00 Native 32-bit Enum Int64/Word64 instances This commits adds more performant Enum Int64 and Enum Word64 instances for 32-bit platforms, replacing the Integer-based implementation. These instances are a copy of the Enum Int and Enum Word instances with minimal changes to manipulate Int64 and Word64 instead. On i386 this yields a 1.5x performance increase and for the JavaScript back end it even yields a 5.6x speedup. Metric Decrease: T18964 - - - - - c8bd7fa4 by Sylvain Henry at 2023-08-02T06:02:03-04:00 JS: fix typos in constants (#23650) - - - - - b9d5bfe9 by Josh Meredith at 2023-08-02T06:02:40-04:00 JavaScript: update MK_TUP macros to use current tuple constructors (#23659) - - - - - 28211215 by Matthew Pickering at 2023-08-02T06:03:19-04:00 ci: Pass -Werror when building hadrian in hadrian-ghc-in-ghci job Warnings when building Hadrian can end up cluttering the output of HLS, and we've had bug reports in the past about these warnings when building Hadrian. It would be nice to turn on -Werror on at least one build of Hadrian in CI to avoid a patch introducing warnings when building Hadrian. Fixes #23638 - - - - - aca20a5d by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers By using a proper release store instead of a fence. - - - - - 453c0531 by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that array reads have necessary barriers This was the cause of #23541. - - - - - 93a0d089 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Add test for #23550 - - - - - 6a2f4a20 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Desugar non-recursive lets to non-recursive lets (take 2) This reverts commit 522bd584f71ddeda21efdf0917606ce3d81ec6cc. And takes care of the case that I missed in my previous attempt. Namely the case of an AbsBinds with no type variables and no dictionary variable. Ironically, the comment explaining why non-recursive lets were desugared to recursive lets were pointing specifically at this case as the reason. I just failed to understand that it was until Simon PJ pointed it out to me. See #23550 for more discussion. - - - - - ff81d53f by jade at 2023-08-02T06:05:20-04:00 Expand documentation of List & Data.List This commit aims to improve the documentation and examples of symbols exported from Data.List - - - - - fa4e5913 by Jade at 2023-08-02T06:06:03-04:00 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid - - - - - e2c91bff by Gergő Érdi at 2023-08-03T02:55:46+01:00 Desugar bindings in the context of their evidence Closes #23172 - - - - - 481f4a46 by Gergő Érdi at 2023-08-03T07:48:43+01:00 Add flag to `-f{no-}specialise-incoherents` to enable/disable specialisation of incoherent instances Fixes #23287 - - - - - d751c583 by Profpatsch at 2023-08-04T12:24:26-04:00 base: Improve String & IsString documentation - - - - - 01db1117 by Ben Gamari at 2023-08-04T12:25:02-04:00 rts/win32: Ensure reliability of IO manager shutdown When the Win32 threaded IO manager shuts down, `ioManagerDie` sends an `IO_MANAGER_DIE` event to the IO manager thread using the `io_manager_event` event object. Finally, it will closes the event object, and invalidate `io_manager_event`. Previously, `readIOManagerEvent` would see that `io_manager_event` is invalid and return `0`, suggesting that everything is right with the world. This meant that if `ioManagerDie` invalidated the handle before the event manager was blocked on the event we would end up in a situation where the event manager would never realize it was asked to shut down. Fix this by ensuring that `readIOManagerEvent` instead returns `IO_MANAGER_DIE` when we detect that the event object has been invalidated by `ioManagerDie`. Fixes #23691. - - - - - fdef003a by Ryan Scott at 2023-08-04T12:25:39-04:00 Look through TH splices in splitHsApps This modifies `splitHsApps` (a key function used in typechecking function applications) to look through untyped TH splices and quasiquotes. Not doing so was the cause of #21077. This builds on !7821 by making `splitHsApps` match on `HsUntypedSpliceTop`, which contains the `ThModFinalizers` that must be run as part of invoking the TH splice. See the new `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Along the way, I needed to make the type of `splitHsApps.set` slightly more general to accommodate the fact that the location attached to a quasiquote is a `SrcAnn NoEpAnns` rather than a `SrcSpanAnnA`. Fixes #21077. - - - - - e77a0b41 by Ben Gamari at 2023-08-04T12:26:15-04:00 Bump deepseq submodule to 1.5. And bump bounds (cherry picked from commit 1228d3a4a08d30eaf0138a52d1be25b38339ef0b) - - - - - cebb5819 by Ben Gamari at 2023-08-04T12:26:15-04:00 configure: Bump minimal boot GHC version to 9.4 (cherry picked from commit d3ffdaf9137705894d15ccc3feff569d64163e8e) - - - - - 83766dbf by Ben Gamari at 2023-08-04T12:26:15-04:00 template-haskell: Bump version to 2.21.0.0 Bumps exceptions submodule. (cherry picked from commit bf57fc9aea1196f97f5adb72c8b56434ca4b87cb) - - - - - 1211112a by Ben Gamari at 2023-08-04T12:26:15-04:00 base: Bump version to 4.19 Updates all boot library submodules. (cherry picked from commit 433d99a3c24a55b14ec09099395e9b9641430143) - - - - - 3ab5efd9 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Normalise versions more aggressively In backpack hashes can contain `+` characters. (cherry picked from commit 024861af51aee807d800e01e122897166a65ea93) - - - - - d52be957 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Declare bkpcabal08 as fragile Due to spurious output changes described in #23648. (cherry picked from commit c046a2382420f2be2c4a657c56f8d95f914ea47b) - - - - - e75a58d1 by Ben Gamari at 2023-08-04T12:26:15-04:00 gitlab-ci: Only mark linker_unload_native as broken in static jobs This test passes on dynamically-linked Alpine. (cherry picked from commit f356a7e8ec8ec3d6b2b30fd175598b9b80065d87) - - - - - 8b176514 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Update base-exports - - - - - 4b647936 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite/interface-stability: normalise versions This eliminates spurious changes from version bumps. - - - - - 0eb54c05 by Ben Gamari at 2023-08-04T12:26:51-04:00 linker/PEi386: Don't sign-extend symbol section number Previously we incorrectly interpreted PE section numbers as signed values. However, this isn't the case; rather, it's an unsigned 16-bit number with a few special bit-patterns (0xffff and 0xfffe). This resulted in #22941 as the linker would conclude that the sections were invalid. Fixing this required quite a bit of refactoring. Closes #22941. - - - - - fd7ce39c by Ben Gamari at 2023-08-04T12:27:28-04:00 testsuite: Mark MulMayOflo_full as broken rather than skipping To ensure that we don't accidentally fix it. See #23742. - - - - - 824092f2 by Ben Gamari at 2023-08-04T12:27:28-04:00 nativeGen/AArch64: Fix sign extension in MulMayOflo Previously the 32-bit implementations of MulMayOflo would use the a non-sensical sign-extension mode. Rewrite these to reflect what gcc 11 produces. Also similarly rework the 16- and 8-bit cases. This now passes the MulMayOflo tests in ghc/test-primops> in all four widths, including the precision tests. Fixes #23721. - - - - - 1b15dbc4 by Jan Hrček at 2023-08-04T12:28:08-04:00 Fix haddock markup in code example for coerce - - - - - 46fd8ced by Vladislav Zavialov at 2023-08-04T12:28:44-04:00 Fix (~) and (@) infix operators in TH splices (#23748) 8168b42a "Whitespace-sensitive bang patterns" allows GHC to accept the following infix operators: a ~ b = () a @ b = () But not if TH is used to generate those declarations: $([d| a ~ b = () a @ b = () |]) -- Test.hs:5:2: error: [GHC-55017] -- Illegal variable name: ‘~’ -- When splicing a TH declaration: (~_0) a_1 b_2 = GHC.Tuple.Prim.() This is easily fixed by modifying `reservedOps` in GHC.Utils.Lexeme - - - - - a1899d8f by Aaron Allen at 2023-08-04T12:29:24-04:00 [#23663] Show Flag Suggestions in GHCi Makes suggestions when using `:set` in GHCi with a misspelled flag. This mirrors how invalid flags are handled when passed to GHC directly. Logic for producing flag suggestions was moved to GHC.Driver.Sesssion so it can be shared. resolves #23663 - - - - - 03f2debd by Rodrigo Mesquita at 2023-08-04T12:30:00-04:00 Improve ghc-toolchain validation configure warning Fixes the layout of the ghc-toolchain validation warning produced by configure. - - - - - de25487d by Alan Zimmerman at 2023-08-04T12:30:36-04:00 EPA make getLocA a synonym for getHasLoc This is basically a no-op change, but allows us to make future changes that can rely on the HasLoc instances And I presume this means we can use more precise functions based on class resolution, so the Windows CI build reports Metric Decrease: T12234 T13035 - - - - - 3ac423b9 by Ben Gamari at 2023-08-04T12:31:13-04:00 ghc-platform: Add upper bound on base Hackage upload requires this. - - - - - 8ba20b21 by Matthew Craven at 2023-08-04T17:22:59-04:00 Adjust and clarify handling of primop effects Fixes #17900; fixes #20195. The existing "can_fail" and "has_side_effects" primop attributes that previously governed this were used in inconsistent and confusingly-documented ways, especially with regard to raising exceptions. This patch replaces them with a single "effect" attribute, which has four possible values: NoEffect, CanFail, ThrowsException, and ReadWriteEffect. These are described in Note [Classifying primop effects]. A substantial amount of related documentation has been re-drafted for clarity and accuracy. In the process of making this attribute format change for literally every primop, several existing mis-classifications were detected and corrected. One of these mis-classifications was tagToEnum#, which is now considered CanFail; this particular fix is known to cause a regression in performance for derived Enum instances. (See #23782.) Fixing this is left as future work. New primop attributes "cheap" and "work_free" were also added, and used in the corresponding parts of GHC.Core.Utils. In view of their actual meaning and uses, `primOpOkForSideEffects` and `exprOkForSideEffects` have been renamed to `primOpOkToDiscard` and `exprOkToDiscard`, respectively. Metric Increase: T21839c - - - - - 41bf2c09 by sheaf at 2023-08-04T17:23:42-04:00 Update inert_solved_dicts for ImplicitParams When adding an implicit parameter dictionary to the inert set, we must make sure that it replaces any previous implicit parameter dictionaries that overlap, in order to get the appropriate shadowing behaviour, as in let ?x = 1 in let ?x = 2 in ?x We were already doing this for inert_cans, but we weren't doing the same thing for inert_solved_dicts, which lead to the bug reported in #23761. The fix is thus to make sure that, when handling an implicit parameter dictionary in updInertDicts, we update **both** inert_cans and inert_solved_dicts to ensure a new implicit parameter dictionary correctly shadows old ones. Fixes #23761 - - - - - 43578d60 by Matthew Craven at 2023-08-05T01:05:36-04:00 Bump bytestring submodule to 0.11.5.1 - - - - - 91353622 by Ben Gamari at 2023-08-05T01:06:13-04:00 Initial commit of Note [Thunks, blackholes, and indirections] This Note attempts to summarize the treatment of thunks, thunk update, and indirections. This fell out of work on #23185. - - - - - 8d686854 by sheaf at 2023-08-05T01:06:54-04:00 Remove zonk in tcVTA This removes the zonk in GHC.Tc.Gen.App.tc_inst_forall_arg and its accompanying Note [Visible type application zonk]. Indeed, this zonk is no longer necessary, as we no longer maintain the invariant that types are well-kinded without zonking; only that typeKind does not crash; see Note [The Purely Kinded Type Invariant (PKTI)]. This commit removes this zonking step (as well as a secondary zonk), and replaces the aforementioned Note with the explanatory Note [Type application substitution], which justifies why the substitution performed in tc_inst_forall_arg remains valid without this zonking step. Fixes #23661 - - - - - 19dea673 by Ben Gamari at 2023-08-05T01:07:30-04:00 Bump nofib submodule Ensuring that nofib can be build using the same range of bootstrap compilers as GHC itself. - - - - - aa07402e by Luite Stegeman at 2023-08-05T23:15:55+09:00 JS: Improve compatibility with recent emsdk The JavaScript code in libraries/base/jsbits/base.js had some hardcoded offsets for fields in structs, because we expected the layout of the data structures to remain unchanged. Emsdk 3.1.42 changed the layout of the stat struct, breaking this assumption, and causing code in .hsc files accessing the stat struct to fail. This patch improves compatibility with recent emsdk by removing the assumption that data layouts stay unchanged: 1. offsets of fields in structs used by JavaScript code are now computed by the configure script, so both the .js and .hsc files will automatically use the new layout if anything changes. 2. the distrib/configure script checks that the emsdk version on a user's system is the same version that a bindist was booted with, to avoid data layout inconsistencies See #23641 - - - - - b938950d by Luite Stegeman at 2023-08-07T06:27:51-04:00 JS: Fix missing local variable declarations This fixes some missing local variable declarations that were found by running the testsuite in strict mode. Fixes #23775 - - - - - 6c0e2247 by sheaf at 2023-08-07T13:31:21-04:00 Update Haddock submodule to fix #23368 This submodule update adds the following three commits: bbf1c8ae - Check for puns 0550694e - Remove fake exports for (~), List, and Tuple<n> 5877bceb - Fix pretty-printing of Solo and MkSolo These commits fix the issues with Haddock HTML rendering reported in ticket #23368. Fixes #23368 - - - - - 5b5be3ea by Matthew Pickering at 2023-08-07T13:32:00-04:00 Revert "Bump bytestring submodule to 0.11.5.1" This reverts commit 43578d60bfc478e7277dcd892463cec305400025. Fixes #23789 - - - - - 01961be3 by Ben Gamari at 2023-08-08T02:47:14-04:00 configure: Derive library version from ghc-prim.cabal.in Since ghc-prim.cabal is now generated by Hadrian, we cannot depend upon it. Closes #23726. - - - - - 3b373838 by Ryan Scott at 2023-08-08T02:47:49-04:00 tcExpr: Push expected types for untyped TH splices inwards In !10911, I deleted a `tcExpr` case for `HsUntypedSplice` in favor of a much simpler case that simply delegates to `tcApp`. Although this passed the test suite at the time, this was actually an error, as the previous `tcExpr` case was critically pushing the expected type inwards. This actually matters for programs like the one in #23796, which GHC would not accept with type inference alone—we need full-blown type _checking_ to accept these. I have added back the previous `tcExpr` case for `HsUntypedSplice` and now explain why we have two different `HsUntypedSplice` cases (one in `tcExpr` and another in `splitHsApps`) in `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Fixes #23796. - - - - - 0ef1d8ae by sheaf at 2023-08-08T21:26:51-04:00 Compute all emitted diagnostic codes This commit introduces in GHC.Types.Error.Codes the function constructorCodes :: forall diag. (...) => Map DiagnosticCode String which computes a collection of all the diagnostic codes that correspond to a particular type. In particular, we can compute the collection of all diagnostic codes emitted by GHC using the invocation constructorCodes @GhcMessage We then make use of this functionality in the new "codes" test which checks consistency and coverage of GHC diagnostic codes. It performs three checks: - check 1: all non-outdated GhcDiagnosticCode equations are statically used. - check 2: all outdated GhcDiagnosticCode equations are statically unused. - check 3: all statically used diagnostic codes are covered by the testsuite (modulo accepted exceptions). - - - - - 4bc7b1e5 by Fraser Tweedale at 2023-08-08T21:27:32-04:00 numberToRangedRational: fix edge cases for exp ≈ (maxBound :: Int) Currently a negative exponent less than `minBound :: Int` results in Infinity, which is very surprising and obviously wrong. ``` λ> read "1e-9223372036854775808" :: Double 0.0 λ> read "1e-9223372036854775809" :: Double Infinity ``` There is a further edge case where the exponent can overflow when increased by the number of tens places in the integer part, or underflow when decreased by the number of leading zeros in the fractional part if the integer part is zero: ``` λ> read "10e9223372036854775807" :: Double 0.0 λ> read "0.01e-9223372036854775808" :: Double Infinity ``` To resolve both of these issues, perform all arithmetic and comparisons involving the exponent in type `Integer`. This approach also eliminates the need to explicitly check the exponent against `maxBound :: Int` and `minBound :: Int`, because the allowed range of the exponent (i.e. the result of `floatRange` for the target floating point type) is certainly within those bounds. This change implements CLC proposal 192: https://github.com/haskell/core-libraries-committee/issues/192 - - - - - 6eab07b2 by Alan Zimmerman at 2023-08-08T21:28:10-04:00 EPA: Remove Location from WarningTxt source This is not needed. - - - - - 1a98d673 by Sebastian Graf at 2023-08-09T16:24:29-04:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 2274abc8 by Sebastian Graf at 2023-08-09T16:24:29-04:00 More explicit strictness in GHC.Real - - - - - ce8aa54c by Sebastian Graf at 2023-08-09T16:24:30-04:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - d004a36d by Sebastian Graf at 2023-08-09T16:24:30-04:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 8c73505e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - d8d993f1 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Disable tests RepPolyWrappedVar2 and RepPolyUnsafeCoerce1 in JS backend ... because those coerce between incompatible/unknown PrimReps. - - - - - f06e87e4 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Inlining literals into boring contexts is OK - - - - - 4a6b7c87 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Clarify floating of unsafeEqualityProofs (#23754) - - - - - b0f4752e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 7e0c8b3b by Sebastian Graf at 2023-08-09T16:24:30-04:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Annoyingly, in -O0 we sometimes generate ``` foo = case "blah"# of sat { __DEFAULT -> unpackCString# sat } ``` which makes it a bit harder to spot that we can emit a standard `stg_unpack_cstring` thunk. Fixes #23270. - - - - - 357f2738 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Deactivate -fcatch-nonexhaustive-cases in ghc-bignum (#23345) - - - - - 59202c80 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. In the ghc/alloc perf test `LargeRecord`, we introduce an additional Simplifier iteration due to #17910. E.g., FloatOut produces a binding ``` lvl_s6uK [Occ=Once1] :: GHC.Types.Int [LclId] lvl_s6uK = GHC.Types.I# 2# lvl_s6uL [Occ=Once1] :: GHC.Types.Any [LclId] lvl_s6uL = case Unsafe.Coerce.unsafeEqualityProof ... of { Unsafe.Coerce.UnsafeRefl v2_i6tr -> lvl_s6uK `cast` (... v2_i6tr ...) } ``` That occurs once and hence is pre-inlined unconditionally in the next Simplifier pass. It's non-trivial to find a way around that, but not really harmful otherwise. Hence we accept a 1.2% increase on some architectures. Metric Increase: LargeRecord - - - - - 00d31188 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - bf885d7a by Matthew Craven at 2023-08-09T16:25:07-04:00 Bump bytestring submodule to 0.11.5, again Fixes #23789. The bytestring commit used here is unreleased; a release can be made when necessary. - - - - - 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - c1a04b8e by Ben Gamari at 2024-04-02T16:42:56-04:00 testsuite: Introduce template-haskell-exports test - - - - - 10 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/generate-ci/generate-job-metadata - .gitlab/generate-ci/generate-jobs - .gitlab/issue_templates/bug.md → .gitlab/issue_templates/default.md The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f116f0b61110b2d9b816b12a8a3a4d912bba70b2...c1a04b8edc49486649b788ca8f8d0f60b59fd0a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f116f0b61110b2d9b816b12a8a3a4d912bba70b2...c1a04b8edc49486649b788ca8f8d0f60b59fd0a3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 22:44:37 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 18:44:37 -0400 Subject: [Git][ghc/ghc][wip/T23109] 913 commits: Serialize CmmRetInfo in .rodata Message-ID: <660c8a5545d9_f9da3e90a7c960b@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 37dafd12 by Simon Peyton Jones at 2024-04-02T22:08:07+01:00 Make newtype instances opaque I think this will help with #23109 Wibbles Allow SelCo for newtype classes Experimental change Wibble Furher wibbles Further improvments Further wibbles esp exprIsConLike Run classop rule first Newtype classops are small needs comments - - - - - 10 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/generate-ci/generate-job-metadata - .gitlab/generate-ci/generate-jobs - .gitlab/issue_templates/bug.md → .gitlab/issue_templates/default.md The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f18c7a4b763f05e0cb89fae754919c99f84763a2...37dafd12daa5f6f17b656c5b5494bce4fe7fe80d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f18c7a4b763f05e0cb89fae754919c99f84763a2...37dafd12daa5f6f17b656c5b5494bce4fe7fe80d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 22:47:33 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 02 Apr 2024 18:47:33 -0400 Subject: [Git][ghc/ghc][wip/spj-unf-size] 278 commits: Improve Monad, Functor & Applicative docs Message-ID: <660c8b0549030_f9da4045c649691b@gitlab.mail> Simon Peyton Jones pushed to branch wip/spj-unf-size at Glasgow Haskell Compiler / GHC Commits: 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - c93eecf1 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 0a2c3c2d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 6d605aa5 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 447f2ac0 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Spelling, layout, pretty-printing only - - - - - f36b9603 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 7fc8cfc3 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - a818823d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - c471144d by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - 346115e0 by Simon Peyton Jones at 2024-04-02T21:20:44+01:00 Remove a long-commented-out line Pure refactoring - - - - - 57f42293 by Simon Peyton Jones at 2024-04-02T21:20:49+01:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - ec584eaf by Simon Peyton Jones at 2024-04-02T21:21:23+01:00 Testsuite message changes from simplifier improvements - - - - - 9c910ae1 by Simon Peyton Jones at 2024-04-02T21:21:23+01:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 193a923a by Simon Peyton Jones at 2024-04-02T23:10:24+01:00 Work in progress on unfoldings re-engineering - - - - - 7348c6d5 by Simon Peyton Jones at 2024-04-02T23:12:08+01:00 Fix a bad, subtle bug in exprIsConApp_maybe In extend_in_scope We were simply overwriting useful bindings in the in-scope set, notably ones that had unfoldings. That could lead to repeated simplifier iterations. - - - - - 8047f16e by Simon Peyton Jones at 2024-04-02T23:15:18+01:00 Minor refactoring... Plus: don't be so eager to inline when argument is a non-value, but has some struture. We want *some* incentive though. - - - - - d3d58548 by Simon Peyton Jones at 2024-04-02T23:17:05+01:00 Adjust * Reduce caseElimDiscount to 10 Example: f_nand in spectral/hartel/event is quite big but was still getting inlined; that make f_simulate too big for SpecConstr * Increase jumpSize. Not so much cheaper than tail calls. I'm trying making them the same size. - - - - - eb4d3511 by Simon Peyton Jones at 2024-04-02T23:17:05+01:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 25ba0892 by Simon Peyton Jones at 2024-04-02T23:17:06+01:00 Wibbles - - - - - 322f618a by Simon Peyton Jones at 2024-04-02T23:17:06+01:00 Wibble - - - - - 17174a9f by Simon Peyton Jones at 2024-04-02T23:47:03+01:00 Wibbles - - - - - 18 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a01474d0107062ecd2fe6101d271897c9658b3c7...17174a9f2574c5186a7f82a68496f40b25de8e03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a01474d0107062ecd2fe6101d271897c9658b3c7...17174a9f2574c5186a7f82a68496f40b25de8e03 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 2 23:09:52 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Tue, 02 Apr 2024 19:09:52 -0400 Subject: [Git][ghc/ghc][wip/expansions-appdo] make applicative breakpoint work Message-ID: <660c904041916_f9da437e728999eb@gitlab.mail> Apoorv Ingle pushed to branch wip/expansions-appdo at Glasgow Haskell Compiler / GHC Commits: f76e8cfd by Apoorv Ingle at 2024-04-02T18:09:39-05:00 make applicative breakpoint work - - - - - 9 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/Language/Haskell/Syntax/Expr.hs - testsuite/tests/ghci.debugger/scripts/break029.stdout Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -476,7 +476,7 @@ type instance XXExpr GhcTc = XXExprGhcTc -- | The different source constructs that we use to instantiate the "original" field -- in an `XXExprGhcRn original expansion` data HsThingRn = OrigExpr (HsExpr GhcRn) - | OrigStmt (ExprLStmt GhcRn) HsDoFlavour + | OrigStmt (ExprLStmt GhcRn) HsDoFlavour -- ^ which kind of do-block did this statement come from | OrigPat (LPat GhcRn) (Maybe (HsDoFlavour, ExprLStmt GhcRn)) isHsThingRnExpr, isHsThingRnStmt, isHsThingRnPat :: HsThingRn -> Bool @@ -1794,7 +1794,7 @@ pprArg (ApplicativeArgMany _ stmts return pat ctxt) = ppr pat <+> text "<-" <+> pprDo ctxt (stmts ++ - [noLocA (LastStmt noExtField (noLocA return) Nothing noSyntaxExpr)]) + [noLocA (LastStmt noExtField return Nothing noSyntaxExpr)]) pprTransformStmt :: (OutputableBndrId p) => [IdP (GhcPass p)] -> LHsExpr (GhcPass p) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -782,8 +782,8 @@ dsDo ctx stmts do_arg (ApplicativeArgOne fail_op pat expr _) = ((pat, fail_op), dsLExpr expr) - do_arg (ApplicativeArgMany _ stmts ret pat _) = - ((pat, Nothing), dsDo ctx (stmts ++ [noLocA $ mkLastStmt (noLocA ret)])) + do_arg (ApplicativeArgMany _ stmts ret@(L ret_loc _) pat _) = + ((pat, Nothing), dsDo ctx (stmts ++ [L ret_loc $ mkLastStmt ret])) ; rhss' <- sequence rhss ===================================== compiler/GHC/HsToCore/Ticks.hs ===================================== @@ -774,7 +774,7 @@ addTickApplicativeArg isGuard (op, arg) = addTickArg (ApplicativeArgMany x stmts ret pat ctxt) = (ApplicativeArgMany x) <$> addTickLStmts isGuard stmts - <*> (unLoc <$> addTickLHsExpr (L (noAnnSrcSpan hpcSrcSpan) ret)) + <*> addTickLHsExpr ret <*> addTickLPat pat <*> pure ctxt ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -2230,12 +2230,12 @@ stmtTreeToStmts monad_names ctxt (StmtTreeApplicative trees) tail tail_fvs = do (stmts',fvs2) <- stmtTreeToStmts monad_names ctxt tree [] pvarset (mb_ret, fvs1) <- if | L _ ApplicativeStmt{} <- last stmts' -> - return (unLoc tup, emptyNameSet) + return (tup, emptyNameSet) | otherwise -> do -- Need 'pureAName' and not 'returnMName' here, so that it requires -- 'Applicative' and not 'Monad' whenever possible (until #20540 is fixed). (ret, _) <- lookupQualifiedDoExpr (HsDoStmt ctxt) pureAName - let expr = HsApp noExtField (noLocA ret) tup + let expr = noLocA (HsApp noExtField (noLocA ret) tup) return (expr, emptyFVs) return ( ApplicativeArgMany { xarg_app_arg_many = noExtField ===================================== compiler/GHC/Tc/Gen/Do.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Tc.Gen.Do (expandDoStmts) where import GHC.Prelude -import GHC.Rename.Utils ( wrapGenSpan, genHsExpApps, genHsApp, genHsLet, +import GHC.Rename.Utils ( wrapGenSpan, genHsExpApps, genHsApp, genHsLet, genLHsApp, genHsLamDoExp, genHsCaseAltDoExp, genWildPat ) import GHC.Tc.Utils.Monad import GHC.Tc.Gen.Pat @@ -88,9 +88,9 @@ expand_do_stmts flav [stmt@(L loc (LastStmt _ (L body_loc body) _ ret_expr))] -- Last statement is just body if we are not in ListComp context. See Syntax.Expr.LastStmt = do appDo <- xoptM LangExt.ApplicativeDo if appDo - then do traceTc "expand_do_stmts last no pop" (ppr ret_expr) + then do traceTc "expand_do_stmts last no pop" (ppr $ (L body_loc body)) return $ mkExpandedStmtAt loc stmt flav body - else do traceTc "expand_do_stmts last pop" (ppr ret_expr) + else do traceTc "expand_do_stmts last pop" (ppr $ (L body_loc body)) return $ mkExpandedStmtPopAt loc stmt flav body | SyntaxExprRn ret <- ret_expr @@ -191,17 +191,17 @@ expand_do_stmts doFlavour -- and potentially loop forever -expand_do_stmts doFlavour ((L loc (ApplicativeStmt _ args mb_join)): lstmts) = +expand_do_stmts doFlavour ((L _ (ApplicativeStmt _ args mb_join)): lstmts) = -- See Note [Applicative BodyStmt] -- -- stmts ~~> stmts' -- ------------------------------------------------------------------------- --- [(<$>, \ x -> e1), (<*>, e2), (<*>, e3), .. ] ; stmts ~~> (\ x -> stmts') <$> e1 <*> e2 ... +-- [(fmap, \ x -> e1), (<*>, e2), (<*>, e3), .. ] ; stmts ~~> (\ x -> stmts') <$> e1 <*> e2 ... -- -- Very similar to HsToCore.Expr.dsDo -- args are [(<$>, e1), (<*>, e2), .., ] - do { expr' <- unLoc <$> expand_do_stmts doFlavour lstmts + do { expr' <- expand_do_stmts doFlavour lstmts -- extracts pats and arg bodies (rhss) from args ; (pats_can_fail, rhss) <- unzip <$> mapM (do_arg . snd) args @@ -213,9 +213,10 @@ expand_do_stmts doFlavour ((L loc (ApplicativeStmt _ args mb_join)): lstmts) = -- wrap the expanded expression with a `join` if needed ; let final_expr = case mb_join of - Just (SyntaxExprRn join_op) -> wrapGenSpan $ genHsApp join_op (wrapGenSpan expand_ado_expr) - _ -> L loc expand_ado_expr + Just (SyntaxExprRn join_op) -> genLHsApp join_op expand_ado_expr + _ -> expand_ado_expr ; traceTc "expand_do_stmts AppStmt" (vcat [ text "args:" <+> ppr args + , text "lstmts:" <+> ppr lstmts , text "mb_join:" <+> ppr mb_join , text "expansion:" <+> ppr final_expr]) ; return final_expr @@ -226,28 +227,34 @@ expand_do_stmts doFlavour ((L loc (ApplicativeStmt _ args mb_join)): lstmts) = { xarg_app_arg_one = mb_fail_op , app_arg_pattern = pat , arg_expr = (L rhs_loc rhs) + , is_body_stmt = is_body_stmt }) = - return ((pat, mb_fail_op) - , mkExpandedStmtAt rhs_loc (L rhs_loc (BindStmt xbsn pat (L rhs_loc rhs))) doFlavour rhs) - do_arg (ApplicativeArgMany _ stmts ret pat ctxt) = - do { expr <- expand_do_stmts ctxt $ stmts ++ [wrapGenSpan $ mkLastStmt (wrapGenSpan ret)] + do traceTc "do_arg" (text "OneArg" <+> ppr (L rhs_loc rhs)) + return ((pat, mb_fail_op) + , mkExpandedStmtAt rhs_loc stmt doFlavour rhs) + where stmt = if is_body_stmt + then (L rhs_loc (BodyStmt NoExtField (L rhs_loc rhs) NoSyntaxExprRn NoSyntaxExprRn)) + else (L rhs_loc (BindStmt xbsn pat (L rhs_loc rhs))) + do_arg (ApplicativeArgMany _ stmts ret@(L ret_loc _) pat ctxt) = + do { expr <- expand_do_stmts ctxt $ stmts ++ [L ret_loc $ mkLastStmt ret] ; return ((pat, Nothing) , expr) } - match_args :: ((LPat GhcRn, FailOperator GhcRn), LHsExpr GhcRn) -> HsExpr GhcRn -> TcM (HsExpr GhcRn) - match_args ((pat, fail_op), stmt_expr) body = unLoc <$> mk_failable_expr doFlavour stmt_ctxt pat (wrapGenSpan body) fail_op + match_args :: ((LPat GhcRn, FailOperator GhcRn), LHsExpr GhcRn) -> LHsExpr GhcRn -> TcM (LHsExpr GhcRn) + match_args ((pat, fail_op), stmt_expr) body = mk_failable_expr doFlavour stmt_ctxt pat body fail_op where stmt_ctxt = case unLoc stmt_expr of XExpr (ExpandedThingRn (OrigStmt s _) _) -> Just (doFlavour, s) _ -> Nothing - mk_apps :: HsExpr GhcRn -> (SyntaxExprRn, LHsExpr GhcRn) -> HsExpr GhcRn + mk_apps :: LHsExpr GhcRn -> (SyntaxExprRn, LHsExpr GhcRn) -> LHsExpr GhcRn mk_apps l_expr (op, r_expr) = case op of SyntaxExprRn op -> case r_expr of - L _ (XExpr (ExpandedThingRn (OrigStmt (L l s) flav) e)) -> XExpr (ExpandedThingRn (OrigStmt (L l s) flav) - (genHsExpApps op [ wrapGenSpan l_expr - , wrapGenSpan e ])) - _ -> genHsExpApps op [ wrapGenSpan l_expr, r_expr ] + L loc (XExpr (ExpandedThingRn (OrigStmt (L l s) flav) e)) + -> L loc $ XExpr (ExpandedThingRn (OrigStmt (L l s) flav) + (genHsExpApps op [ l_expr + , L loc e ])) + _ -> wrapGenSpan $ genHsExpApps op [ l_expr, r_expr ] NoSyntaxExprRn -> pprPanic "expand_do_stmts applicative op:" (ppr op) xbsn :: XBindStmtRn ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -1146,7 +1146,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside = do { (stmts', (ret',pat')) <- tcStmtsAndThen (HsDoStmt ctxt) tcDoStmt stmts (mkCheckExpType exp_ty) $ \res_ty -> do - { ret' <- tcExpr ret res_ty + { ret' <- tcMonoExprNC ret res_ty ; (pat', _) <- tcCheckPat (StmtCtxt (HsDoStmt ctxt)) pat (unrestricted pat_ty) $ return () ; return (ret', pat') ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -1453,7 +1453,7 @@ zonkStmt _zBody (ApplicativeStmt body_ty args mb_join) ; return (ApplicativeArgOne new_fail pat new_expr isBody) } zonk_arg (ApplicativeArgMany x stmts ret pat ctxt) = runZonkBndrT (zonkStmts zonkLExpr stmts) $ \ new_stmts -> - do { new_ret <- zonkExpr ret + do { new_ret <- zonkLExpr ret ; return (ApplicativeArgMany x new_stmts new_ret pat ctxt) } ------------------------------------------------------------------------- ===================================== compiler/Language/Haskell/Syntax/Expr.hs ===================================== @@ -1271,7 +1271,7 @@ data ApplicativeArg idL | ApplicativeArgMany -- do { stmts; return vars } { xarg_app_arg_many :: XApplicativeArgMany idL , app_stmts :: [ExprLStmt idL] -- stmts - , final_expr :: HsExpr idL -- return (v1,..,vn), or just (v1,..,vn) + , final_expr :: LHsExpr idL -- return (v1,..,vn), or just (v1,..,vn) , bv_pattern :: LPat idL -- (v1,...,vn) , stmt_context :: HsDoFlavour -- ^ context of the do expression, used in pprArg ===================================== testsuite/tests/ghci.debugger/scripts/break029.stdout ===================================== @@ -4,7 +4,7 @@ x :: Int = 3 Stopped in Main.f, break029.hs:5:8-21 _result :: IO Int = _ x :: Int = 3 -Stopped in Main.f, break029.hs:6:11-15 +Stopped in Main.f, break029.hs:6:3-16 _result :: Int = _ y :: Int = _ 4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f76e8cfdb0cb7780828257fab5990a404325dbee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f76e8cfdb0cb7780828257fab5990a404325dbee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 00:13:44 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 20:13:44 -0400 Subject: [Git][ghc/ghc][master] th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Message-ID: <660c9f381197a_f9da4d8869c1079da@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - 1 changed file: - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -1,3 +1,4 @@ +{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/817e89362e74b5177c02deee31f16cec862052cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/817e89362e74b5177c02deee31f16cec862052cc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 00:14:33 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 20:14:33 -0400 Subject: [Git][ghc/ghc][master] 2 commits: JS: reenable h$appendToHsString optimization (#24495) Message-ID: <660c9f69b022e_f9da4f328e41128bc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - 9 changed files: - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Rts/Rts.hs - rts/js/string.js - + testsuite/tests/javascript/Makefile - + testsuite/tests/javascript/T24495.hs - + testsuite/tests/javascript/T24495.stdout - testsuite/tests/javascript/all.T Changes: ===================================== compiler/GHC/StgToJS/Apply.hs ===================================== @@ -46,7 +46,6 @@ import GHC.StgToJS.Rts.Types import GHC.StgToJS.Stack import GHC.StgToJS.Ids -import GHC.Types.Literal import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.CostCentre @@ -60,7 +59,6 @@ import GHC.Core.TyCon import GHC.Core.DataCon import GHC.Core.Type hiding (typeSize) -import GHC.Utils.Encoding import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic @@ -100,22 +98,6 @@ genApp -> G (JStgStat, ExprResult) genApp ctx i args - -- Case: unpackCStringAppend# "some string"# str - -- - -- Generates h$appendToHsStringA(str, "some string"), which has a faster - -- decoding loop. - | [StgLitArg (LitString bs), x] <- args - , [top] <- concatMap typex_expr (ctxTarget ctx) - , getUnique i == unpackCStringAppendIdKey - , d <- utf8DecodeByteString bs - = do - prof <- csProf <$> getSettings - let profArg = if prof then [jCafCCS] else [] - a <- genArg x - return ( top |= app "h$appendToHsStringA" (toJExpr d : a ++ profArg) - , ExprInline - ) - -- let-no-escape | Just n <- ctxLneBindingStackSize ctx i = do ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -60,11 +60,13 @@ import GHC.Types.Var.Set import GHC.Types.Id import GHC.Types.Unique.FM import GHC.Types.RepType +import GHC.Types.Literal import GHC.Stg.Syntax import GHC.Stg.Utils import GHC.Builtin.PrimOps +import GHC.Builtin.Names import GHC.Core hiding (Var) import GHC.Core.TyCon @@ -73,6 +75,7 @@ import GHC.Core.Opt.Arity (isOneShotBndr) import GHC.Core.Type hiding (typeSize) import GHC.Utils.Misc +import GHC.Utils.Encoding import GHC.Utils.Monad import GHC.Utils.Panic import GHC.Utils.Outputable (ppr, renderWithContext, defaultSDocContext) @@ -555,6 +558,36 @@ genCase :: HasDebugCallStack -> LiveVars -> G (JStgStat, ExprResult) genCase ctx bnd e at alts l + -- For: unpackCStringAppend# "some string"# str + -- Generate: h$appendToHsStringA(str, "some string") + -- + -- The latter has a faster decoding loop. + -- + -- Since #23270 and 7e0c8b3bab30, literals strings aren't STG atoms and we + -- need to match the following instead: + -- + -- case "some string"# of b { + -- DEFAULT -> unpackCStringAppend# b str + -- } + -- + -- Wrinkle: it doesn't kick in when literals are floated out to the top level. + -- + | StgLit (LitString bs) <- e + , [GenStgAlt DEFAULT _ rhs] <- alts + , StgApp i args <- rhs + , getUnique i == unpackCStringAppendIdKey + , [StgVarArg b',x] <- args + , bnd == b' + , d <- utf8DecodeByteString bs + , [top] <- concatMap typex_expr (ctxTarget ctx) + = do + prof <- csProf <$> getSettings + let profArg = if prof then [jCafCCS] else [] + a <- genArg x + return ( top |= app "h$appendToHsStringA" (toJExpr d : a ++ profArg) + , ExprInline + ) + | isInlineExpr e = do bndi <- identsForId bnd let ctx' = ctxSetTop bnd ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -191,6 +191,9 @@ genCommonCppDefs profiling = mconcat -- resumable thunks , "#define MAKE_RESUMABLE(closure,stack) { (closure).f = h$resume_e; (closure).d1 = (stack), (closure).d2 = null; }\n" + -- making a thunk + , "#define MK_UPD_THUNK(closure) h$c1(h$upd_thunk_e,(closure))\n" + -- general deconstruction , "#define IS_THUNK(x) ((x).f.t === CLOSURE_TYPE_THUNK)\n" , "#define CONSTR_TAG(x) ((x).f.a)\n" ===================================== compiler/GHC/StgToJS/Rts/Rts.hs ===================================== @@ -448,6 +448,19 @@ rts_gen s = do , r4 |= d4 , returnS (app "h$ap_3_3_fast" []) ]) + , closure (ClosureInfo (TxtI "h$upd_thunk_e") (CIRegs 0 [PtrV]) "updatable thunk" (CILayoutFixed 1 [PtrV]) CIThunk mempty) + (jVar $ \t -> return $ + mconcat [t |= closureField1 r1 + , adjSp' 2 + , stack .! (sp - 1) |= r1 + , stack .! sp |= var "h$upd_frame" + , closureEntry r1 |= var "h$blackhole" + , closureField1 r1 |= var "h$currentThread" + , closureField2 r1 |= null_ + , r1 |= t + , returnS (app "h$ap_0_0_fast" []) + ] + ) -- select first field , closure (ClosureInfo (global "h$select1_e") (CIRegs 0 [PtrV]) "select1" (CILayoutFixed 1 [PtrV]) CIThunk mempty) (jVar \t -> return $ ===================================== rts/js/string.js ===================================== @@ -723,7 +723,10 @@ function h$appendToHsStringA(str, appendTo, cc) { function h$appendToHsStringA(str, appendTo) { #endif var i = str.length - 1; - var r = appendTo; + // we need to make an updatable thunk here + // if we embed the given closure in a CONS cell. + // (#24495) + var r = i == 0 ? appendTo : MK_UPD_THUNK(appendTo); while(i>=0) { r = MK_CONS_CC(str.charCodeAt(i), r, cc); --i; ===================================== testsuite/tests/javascript/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +T24495: + '$(TEST_HC)' $(TEST_HC_OPTS) T24495.hs -v0 -O1 -dsuppress-uniques -ddump-js -ddump-to-file + ./T24495 + # check that the optimization occurred + grep -c appendToHsStringA T24495.dump-js ===================================== testsuite/tests/javascript/T24495.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_GHC -O1 #-} +-- -O1 required to make "rest" thunk SingleEntry + +module Main where + +import GHC.CString +import GHC.JS.Prim (JSVal, toJSString) + +foo :: Double -> IO () +foo x = debugString (toJSString ("2 " ++ s)) + where + x' = if x == 0 then "b" else "c" + y' = if x == 0 then "b" else "c" + s = "a" ++ x' ++ " " ++ y' ++ "d" + +main :: IO () +main = foo 0 + + +foreign import javascript "((s) => { console.log(s); })" + debugString :: JSVal -> IO () ===================================== testsuite/tests/javascript/T24495.stdout ===================================== @@ -0,0 +1,2 @@ +2 ab bd +2 ===================================== testsuite/tests/javascript/all.T ===================================== @@ -21,3 +21,4 @@ test('js-mk_tup', extra_files(['test-mk_tup.js']), compile_and_run, ['test-mk_tu test('T23346', normal, compile_and_run, ['']) test('T22455', normal, compile_and_run, ['-ddisable-js-minifier']) test('T23565', normal, compile_and_run, ['']) +test('T24495', normal, makefile_test, ['T24495']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/817e89362e74b5177c02deee31f16cec862052cc...527616e950fd8942c182be903d176f4b9890ee5a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/817e89362e74b5177c02deee31f16cec862052cc...527616e950fd8942c182be903d176f4b9890ee5a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 00:15:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 20:15:45 -0400 Subject: [Git][ghc/ghc][master] Deal with duplicate tyvars in type declarations Message-ID: <660c9fb13e7db_f9da5179af8121168@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - 14 changed files: - compiler/GHC/Tc/Gen/HsType.hs - testsuite/tests/saks/should_compile/saks018.hs - testsuite/tests/saks/should_compile/saks021.hs - testsuite/tests/saks/should_fail/all.T - + testsuite/tests/saks/should_fail/saks018-fail.hs - + testsuite/tests/saks/should_fail/saks018-fail.stderr - + testsuite/tests/saks/should_fail/saks021-fail.hs - + testsuite/tests/saks/should_fail/saks021-fail.stderr - testsuite/tests/typecheck/should_compile/T24470b.hs - + testsuite/tests/vdq-rta/should_fail/T24604.hs - + testsuite/tests/vdq-rta/should_fail/T24604.stderr - + testsuite/tests/vdq-rta/should_fail/T24604a.hs - + testsuite/tests/vdq-rta/should_fail/T24604a.stderr - testsuite/tests/vdq-rta/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -2570,9 +2570,11 @@ kcCheckDeclHeader_sig sig_kind name flav ; traceTc "kcCheckDeclHeader_sig {" $ vcat [ text "sig_kind:" <+> ppr sig_kind , text "sig_tcbs:" <+> ppr sig_tcbs - , text "sig_res_kind:" <+> ppr sig_res_kind ] + , text "sig_res_kind:" <+> ppr sig_res_kind + , text "implict_nms:" <+> ppr implicit_nms + , text "hs_tv_bndrs:" <+> ppr hs_tv_bndrs ] - ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind)))) + ; (tclvl, wanted, (implicit_tvs, (skol_tcbs, skol_scoped_tvs, (extra_tcbs, tycon_res_kind)))) <- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687 bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind -> @@ -2615,9 +2617,18 @@ kcCheckDeclHeader_sig sig_kind name flav -- Here p and q both map to the same kind variable k. We don't allow this -- so we must check that they are distinct. A similar thing happens -- in GHC.Tc.TyCl.swizzleTcTyConBinders during inference. + -- + -- With visible dependent quantification, one of the binders involved + -- may be explicit. Consider #24604 + -- type UF :: forall zk -> zk -> Constraint + -- class UF kk (xb :: k) + -- Here `k` and `kk` both denote the same variable; but only `k` is implicit + -- Hence we need to add skol_scoped_tvs ; implicit_tvs <- liftZonkM $ zonkTcTyVarsToTcTyVars implicit_tvs ; let implicit_prs = implicit_nms `zip` implicit_tvs - ; checkForDuplicateScopedTyVars implicit_prs + dup_chk_prs = implicit_prs ++ mkTyVarNamePairs skol_scoped_tvs + ; unless (null implicit_nms) $ -- No need if no implicit tyvars + checkForDuplicateScopedTyVars dup_chk_prs ; checkForDisconnectedScopedTyVars name flav all_tcbs implicit_prs -- Swizzle the Names so that the TyCon uses the user-declared implicit names @@ -2686,6 +2697,7 @@ matchUpSigWithDecl -> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope -- Argument is excess TyConBinders and tail kind -> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars + , [TcTyVar] -- Skolem tyvars brought into lexical scope by this matching-up , a ) -- See Note [Matching a kind signature with a declaration] -- Invariant: Length of returned TyConBinders + length of excess TyConBinders @@ -2696,7 +2708,7 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside go subst tcbs [] = do { let (subst', tcbs') = substTyConBindersX subst tcbs ; res <- thing_inside tcbs' (substTy subst' sig_res_kind) - ; return ([], res) } + ; return ([], [], res) } go _ [] hs_bndrs = failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs) @@ -2712,17 +2724,22 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside -- that come from the type declaration, not the kind signature subst' = extendTCvSubstWithClone subst tv tv' ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv') - ; (tcbs', res) <- tcExtendTyVarEnv [tv'] $ - go subst' tcbs' hs_bndrs' - ; return (Bndr tv' vis : tcbs', res) } + ; traceTc "musd1" (ppr tcb $$ ppr hs_bndr $$ ppr tv') + ; (tcbs', tvs, res) <- tcExtendTyVarEnv [tv'] $ + go subst' tcbs' hs_bndrs' + ; return (Bndr tv' vis : tcbs', tv':tvs, res) } + -- We do a tcExtendTyVarEnv [tv'], so we return tv' in + -- the list of lexically-scoped skolem type variables | skippable (binderFlag tcb) = -- Invisible TyConBinder, so do not consume one of the hs_bndrs do { let (subst', tcb') = substTyConBinderX subst tcb - ; (tcbs', res) <- go subst' tcbs' hs_bndrs + ; traceTc "musd2" (ppr tcb $$ ppr hs_bndr $$ ppr tcb') + ; (tcbs', tvs, res) <- go subst' tcbs' hs_bndrs -- NB: pass on hs_bndrs unchanged; we do not consume a -- HsTyVarBndr for an invisible TyConBinder - ; return (tcb' : tcbs', res) } + ; return (tcb' : tcbs', tvs, res) } + -- Return `tvs`; no new lexically-scoped TyVars brought into scope | otherwise = -- At this point we conclude that: @@ -2736,14 +2753,19 @@ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside = return () tc_hs_bndr (KindedTyVar _ _ (L _ hs_nm) lhs_kind) expected_kind = do { sig_kind <- tcLHsKindSig (TyVarBndrKindCtxt hs_nm) lhs_kind + ; traceTc "musd3:unifying" (ppr sig_kind $$ ppr expected_kind) ; discardResult $ -- See Note [discardResult in kcCheckDeclHeader_sig] unifyKind (Just (NameThing hs_nm)) sig_kind expected_kind } -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. + -- In particular: we match up if + -- (a) HsBndr looks like @k, and TyCon binder is forall k. (NamedTCB Specified) + -- (b) HsBndr looks like a, and TyCon binder is forall k -> (NamedTCB Required) + -- or k -> (AnonTCB) zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool - zippable vis (HsBndrRequired _) = isVisibleTcbVis vis - zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis + zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis -- (a) + zippable vis (HsBndrRequired _) = isVisibleTcbVis vis -- (b) -- See GHC Proposal #425, section "Kind checking", -- where zippable and skippable are defined. @@ -3007,15 +3029,7 @@ checkForDisconnectedScopedTyVars name flav all_tcbs scoped_prs checkForDuplicateScopedTyVars :: [(Name,TcTyVar)] -> TcM () -- Check for duplicates --- E.g. data SameKind (a::k) (b::k) --- data T (a::k1) (b::k2) c = MkT (SameKind a b) c --- Here k1 and k2 start as TyVarTvs, and get unified with each other --- If this happens, things get very confused later, so fail fast --- --- In the CUSK case k1 and k2 are skolems so they won't unify; --- but in the inference case (see generaliseTcTyCon), --- and the type-sig case (see kcCheckDeclHeader_sig), they are --- TcTyVars, so we must check. +-- See Note [Aliasing in type and class declarations] checkForDuplicateScopedTyVars scoped_prs = unless (null err_prs) $ do { mapM_ report_dup err_prs; failM } @@ -3035,8 +3049,43 @@ checkForDuplicateScopedTyVars scoped_prs addErrTc $ TcRnDifferentNamesForTyVar n1 n2 -{- Note [Disconnected type variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Aliasing in type and class declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + data SameKind (a::k) (b::k) + data T1 (a::k1) (b::k2) c = MkT (SameKind a b) c +We do not allow this, because `k1` and `k2` would both stand for the same type +variable -- they are both aliases for `k`. + +Other examples + data T2 (a::k1) = MkT2 (SameKind a Int) -- k1 stands for Type + data T3 @k1 @k2 (a::k1) (b::k2) = MkT (SameKind a b) -- k1 and k2 are aliases + + type UF :: forall zk. zk -> Constraint + class UF @kk (xb :: k) where -- kk and k are aliases + op :: (xs::kk) -> Bool + +See #24604 for an example that crashed GHC. + +There is a design choice here. It would be possible to allow implicit type variables +like `k1` and `k2` in T1's declartion to stand for /abitrary kinds/. This is in fact +the rule we use in /terms/ pattern signatures: + f :: [Int] -> Int + f ((x::a) : xs) = ... +Here `a` stands for `Int`. But in type /signatures/ we make a different choice: + f1 :: forall (a::k1) (b::k2). SameKind a b -> blah + f2 :: forall (a::k). SameKind a Int -> blah + +Here f1's signature is rejected because `k1` and `k2` are aliased; and f2's is +rejected because `k` stands for `Int`. + +Our current choice is that type and class declarations behave more like signatures; +we do not allow aliasing. That is what `checkForDuplicateScopedTyVars` checks. +See !12328 for some design discussion. + + +Note [Disconnected type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This note applies when kind-checking the header of a type/class decl that has a separate, standalone kind signature. See #24083. ===================================== testsuite/tests/saks/should_compile/saks018.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_018 where import Data.Kind (Type) type T :: forall k -> k -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_compile/saks021.hs ===================================== @@ -6,4 +6,4 @@ module SAKS_021 where import Data.Kind (Type) type T :: forall k -> forall (xx :: k) -> Type -data T k (x :: hk) +data T j (x :: j) ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -36,3 +36,5 @@ test('T18863b', normal, compile_fail, ['']) test('T18863c', normal, compile_fail, ['']) test('T18863d', normal, compile_fail, ['']) test('T20916', normal, compile_fail, ['']) +test('saks018-fail', normal, compile_fail, ['']) +test('saks021-fail', normal, compile_fail, ['']) ===================================== testsuite/tests/saks/should_fail/saks018-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_018 where + +import Data.Kind (Type) + +type T :: forall k -> k -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks018-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks018-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/saks/should_fail/saks021-fail.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE PolyKinds, ExplicitForAll #-} + +module SAKS_021 where + +import Data.Kind (Type) + +type T :: forall k -> forall (xx :: k) -> Type +data T k (x :: hk) ===================================== testsuite/tests/saks/should_fail/saks021-fail.stderr ===================================== @@ -0,0 +1,4 @@ + +saks021-fail.hs:9:8: error: [GHC-17370] + • Different names for the same type variable: ‘hk’ and ‘k’ + • In the data type declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_compile/T24470b.hs ===================================== @@ -7,4 +7,4 @@ import Data.Kind import Data.Data type SynOK :: forall k. k -> Type -type SynOK @t = Proxy :: j -> Type +type SynOK @j = Proxy :: j -> Type ===================================== testsuite/tests/vdq-rta/should_fail/T24604.hs ===================================== @@ -0,0 +1,7 @@ +module T24604 where + +import Data.Kind + +type UF :: forall zk -> zk -> Constraint +class UF kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604.hs:6:10: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeAbstractions #-} + +module T24604a where + +import Data.Kind + +type UF :: forall zk. zk -> Constraint +class UF @kk (xb :: k) where + op :: (xs::kk) -> Bool ===================================== testsuite/tests/vdq-rta/should_fail/T24604a.stderr ===================================== @@ -0,0 +1,4 @@ + +T24604a.hs:8:11: error: [GHC-17370] + • Different names for the same type variable: ‘k’ and ‘kk’ + • In the class declaration for ‘UF’ ===================================== testsuite/tests/vdq-rta/should_fail/all.T ===================================== @@ -17,4 +17,6 @@ test('T23738_fail_implicit_tv', normal, compile_fail, ['']) test('T23738_fail_var', normal, compile_fail, ['']) test('T24176', normal, compile_fail, ['']) test('T23739_fail_ret', normal, compile_fail, ['']) -test('T23739_fail_case', normal, compile_fail, ['']) \ No newline at end of file +test('T23739_fail_case', normal, compile_fail, ['']) +test('T24604', normal, compile_fail, ['']) +test('T24604a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/faa30b41a6f941627ddeeba805815b2742d312d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/faa30b41a6f941627ddeeba805815b2742d312d1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 00:16:10 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 20:16:10 -0400 Subject: [Git][ghc/ghc][master] Try using MCoercion in exprIsConApp_maybe Message-ID: <660c9fca59232_f9da52b8b94121395@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 2 changed files: - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/SimpleOpt.hs Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -3023,7 +3023,7 @@ pushCoercionIntoLambda in_scope x e co | otherwise = Nothing -pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion +pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion -> Maybe (DataCon , [Type] -- Universal type args , [CoreExpr]) -- All other args incl existentials @@ -3033,10 +3033,20 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion -- where co :: (T t1 .. tn) ~ to_ty -- The left-hand one must be a T, because exprIsConApp returned True -- but the right-hand one might not be. (Though it usually will.) -pushCoDataCon dc dc_args co - | isReflCo co || from_ty `eqType` to_ty -- try cheap test first - , let (univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args - = Just (dc, map exprToType univ_ty_args, rest_args) +pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args) +pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co) + +push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr]) +push_dc_refl dc dc_args + = (dc, map exprToType univ_ty_args, rest_args) + where + !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args + +push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type + -> Maybe (DataCon, [Type], [CoreExpr]) +push_dc_gen dc dc_args co (Pair from_ty to_ty) + | from_ty `eqType` to_ty -- try cheap test first + = Just $! (push_dc_refl dc dc_args) | Just (to_tc, to_tc_arg_tys) <- splitTyConApp_maybe to_ty , to_tc == dataConTyCon dc @@ -3082,8 +3092,6 @@ pushCoDataCon dc dc_args co | otherwise = Nothing - where - Pair from_ty to_ty = coercionKind co collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr) -- Collect lambda binders, pushing coercions inside if possible ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1211,7 +1211,7 @@ data-con wrappers, and that cure would be worse than the disease. This Note exists solely to document the problem. -} -data ConCont = CC [CoreExpr] Coercion +data ConCont = CC [CoreExpr] MCoercion -- Substitution already applied -- | Returns @Just ([b1..bp], dc, [t1..tk], [x1..xn])@ if the argument @@ -1233,7 +1233,7 @@ exprIsConApp_maybe :: HasDebugCallStack => InScopeEnv -> CoreExpr -> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr]) exprIsConApp_maybe ise@(ISE in_scope id_unf) expr - = go (Left in_scope) [] expr (CC [] (mkRepReflCo (exprType expr))) + = go (Left in_scope) [] expr (CC [] MRefl) where go :: Either InScopeSet Subst -- Left in-scope means "empty substitution" @@ -1246,14 +1246,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr go subst floats (Tick t expr) cont | not (tickishIsCode t) = go subst floats expr cont - go subst floats (Cast expr co1) (CC args co2) + go subst floats (Cast expr co1) (CC args m_co2) | Just (args', m_co1') <- pushCoArgs (subst_co subst co1) args -- See Note [Push coercions in exprIsConApp_maybe] - = case m_co1' of - MCo co1' -> go subst floats expr (CC args' (co1' `mkTransCo` co2)) - MRefl -> go subst floats expr (CC args' co2) + = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2)) - go subst floats (App fun arg) (CC args co) + go subst floats (App fun arg) (CC args mco) | let arg_type = exprType arg , not (isTypeArg arg) && needsCaseBinding arg_type arg -- An unlifted argument that’s not ok for speculation must not simply be @@ -1276,17 +1274,17 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) float = FloatCase arg' bndr DEFAULT [] subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) co) + in go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise - = go subst floats fun (CC (subst_expr subst arg : args) co) + = go subst floats fun (CC (subst_expr subst arg : args) mco) - go subst floats (Lam bndr body) (CC (arg:args) co) + go subst floats (Lam bndr body) (CC (arg:args) mco) | do_beta_by_substitution bndr arg - = go (extend subst bndr arg) floats body (CC args co) + = go (extend subst bndr arg) floats body (CC args mco) | otherwise = let (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' arg) - in go subst' (float:floats) body (CC args co) + in go subst' (float:floats) body (CC args mco) go subst floats (Let (NonRec bndr rhs) expr) cont | not (isJoinId bndr) @@ -1311,12 +1309,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr (lookupIdSubst sub v) cont - go (Left in_scope) floats (Var fun) cont@(CC args co) + go (Left in_scope) floats (Var fun) cont@(CC args mco) | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun = succeedWith in_scope floats $ - pushCoDataCon con args co + pushCoDataCon con args mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1336,7 +1334,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplOptExpr initialises the in-scope set with exprFreeVars, -- but that doesn't account for DFun unfoldings = succeedWith in_scope floats $ - pushCoDataCon con (map (substExpr subst) dfun_args) co + pushCoDataCon con (map (substExpr subst) dfun_args) mco -- Look through unfoldings, but only arity-zero one; -- if arity > 0 we are effectively inlining a function call, @@ -1354,7 +1352,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr , [arg] <- args , Just (LitString str) <- exprIsLiteral_maybe ise arg = succeedWith in_scope floats $ - dealWithStringLiteral fun str co + dealWithStringLiteral fun str mco where unfolding = id_unf fun extend_in_scope unf_fvs @@ -1404,15 +1402,15 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- See Note [exprIsConApp_maybe on literal strings] -dealWithStringLiteral :: Var -> BS.ByteString -> Coercion +dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion -> Maybe (DataCon, [Type], [CoreExpr]) -- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS -- turns those into [] automatically, but just in case something else in GHC -- generates a string literal directly. -dealWithStringLiteral fun str co = +dealWithStringLiteral fun str mco = case utf8UnconsByteString str of - Nothing -> pushCoDataCon nilDataCon [Type charTy] co + Nothing -> pushCoDataCon nilDataCon [Type charTy] mco Just (char, charTail) -> let char_expr = mkConApp charDataCon [mkCharLit char] -- In singleton strings, just add [] instead of unpackCstring# ""#. @@ -1421,7 +1419,7 @@ dealWithStringLiteral fun str co = else App (Var fun) (Lit (LitString charTail)) - in pushCoDataCon consDataCon [Type charTy, char_expr, rest] co + in pushCoDataCon consDataCon [Type charTy, char_expr, rest] mco {- Note [Unfolding DFuns] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0b0c71716e700d3fb5fc2aec8c14ac588f60636 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0b0c71716e700d3fb5fc2aec8c14ac588f60636 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 02:17:16 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 02 Apr 2024 22:17:16 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 43 commits: th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Message-ID: <660cbc2c59760_f9da60e53841280b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 5c8e7c14 by Duncan Coutts at 2024-04-02T22:17:04-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 3e7ba020 by Duncan Coutts at 2024-04-02T22:17:04-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - e9f09f3e by Duncan Coutts at 2024-04-02T22:17:04-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - e02025fa by Duncan Coutts at 2024-04-02T22:17:04-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - a6432a0a by Duncan Coutts at 2024-04-02T22:17:04-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - dd62b661 by Duncan Coutts at 2024-04-02T22:17:04-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 67f72a0c by Duncan Coutts at 2024-04-02T22:17:04-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - bf4b90b9 by Duncan Coutts at 2024-04-02T22:17:05-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - a82d71c7 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - 32bba262 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - 50dc8e81 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - c9940d85 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 6b9cfb49 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 7a622337 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - 20ac84f6 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 960f33c5 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - a6efa561 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - a103818d by Duncan Coutts at 2024-04-02T22:17:05-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - 0ccb581f by Duncan Coutts at 2024-04-02T22:17:05-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 1f26d687 by Duncan Coutts at 2024-04-02T22:17:05-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 0e0c825f by Duncan Coutts at 2024-04-02T22:17:05-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 27d0bf61 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - df6c03ec by Duncan Coutts at 2024-04-02T22:17:05-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 91004efb by Duncan Coutts at 2024-04-02T22:17:05-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 139e2c9e by Duncan Coutts at 2024-04-02T22:17:05-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - b65f6118 by Duncan Coutts at 2024-04-02T22:17:05-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - 90d6aea7 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - c0efce1f by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 3b9a1de8 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 2d065c65 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Spelling, layout, pretty-printing only - - - - - 7f10d2db by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - dc1dd17d by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - af2df69f by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - af30fae8 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - 23738641 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Remove a long-commented-out line Pure refactoring - - - - - 7389f48b by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 08e36400 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Testsuite message changes from simplifier improvements - - - - - 944ef992 by Simon Peyton Jones at 2024-04-02T22:17:06-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 14 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dffa74229386b4a9a8d4c0de2bee084bc53e0ac...944ef9924c37b108174b8ed1006112dde4e7cc28 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dffa74229386b4a9a8d4c0de2bee084bc53e0ac...944ef9924c37b108174b8ed1006112dde4e7cc28 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 05:27:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 01:27:52 -0400 Subject: [Git][ghc/ghc][master] 26 commits: Initial ./configure support for selecting I/O managers Message-ID: <660ce8d8711c3_2ed9481567998110098@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - 30 changed files: - docs/users_guide/runtime_control.rst - libraries/base/src/GHC/RTS/Flags.hs - libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs - libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc - + m4/ghc_iomanagers.m4 - rts/Capability.c - rts/Capability.h - rts/IOManager.c - rts/IOManager.h - + rts/IOManagerInternals.h - rts/PrimOps.cmm - rts/RaiseAsync.c - rts/RtsFlags.c - rts/RtsFlags.h - rts/RtsStartup.c - rts/RtsSymbols.c - rts/RtsUtils.c - rts/Schedule.c - rts/Trace.h - rts/configure.ac - rts/include/rts/Flags.h - rts/posix/Select.c - rts/posix/Select.h - rts/posix/Signals.c - rts/sm/Scav.c - rts/win32/AsyncMIO.c - rts/win32/AwaitEvent.c - + rts/win32/AwaitEvent.h - rts/win32/ConsoleHandler.c - testsuite/tests/interface-stability/base-exports.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0b0c71716e700d3fb5fc2aec8c14ac588f60636...8d95096857dbea39b80befacab35182e0f64ae62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0b0c71716e700d3fb5fc2aec8c14ac588f60636...8d95096857dbea39b80befacab35182e0f64ae62 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 05:28:42 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 01:28:42 -0400 Subject: [Git][ghc/ghc][master] 12 commits: Several improvements to the handling of coercions Message-ID: <660ce90a5f0cc_2ed948175d7201192ac@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 14 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d95096857dbea39b80befacab35182e0f64ae62...271a7812cbb47494c74b1dc3b7d2a26fd8d88365 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d95096857dbea39b80befacab35182e0f64ae62...271a7812cbb47494c74b1dc3b7d2a26fd8d88365 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 05:53:54 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Wed, 03 Apr 2024 01:53:54 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/invis-pats-change-ast] 54 commits: EPA: Fix FamDecl range Message-ID: <660ceef28ae2b_2ed9481ac3bf811941e@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/invis-pats-change-ast at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 8fbc07b8 by Andrei Borzenkov at 2024-04-03T09:53:39+04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 16 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64339f17846405e046f8c6d241ef1a2887ffe37d...8fbc07b8ac00a88fd704f6d91ed4a25f7689e448 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64339f17846405e046f8c6d241ef1a2887ffe37d...8fbc07b8ac00a88fd704f6d91ed4a25f7689e448 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 07:02:48 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 03 Apr 2024 03:02:48 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660cff1854a84_2ed94822dab0c124861@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: 6c1cd800 by Fendor at 2024-04-03T09:02:29+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 16 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,19 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , unsafeDecodeUtf + , unsafeEncodeUtf + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import System.OsPath +import Data.Either + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsPath -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,9 +455,9 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. @@ -488,14 +490,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +505,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +514,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +545,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +583,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> OsPath -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +602,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +675,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +728,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,7 @@ where import GHC.Prelude import GHC.Unit +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -16,6 +17,7 @@ import GHC.Platform.Ways import Data.IORef import GHC.Data.FastString import qualified Data.Set as Set +import System.OsPath (OsPath) -- | The 'FinderCache' maps modules to the result of -- searching for that module. It records the results of searching for @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsPath + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsPath + , finder_dynHiSuf :: OsPath + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsPath + , finder_dynObjectSuf :: OsPath + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,10 +7,19 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude + +import GHC.Data.OsPath +import qualified GHC.Data.Strict as Strict import GHC.Unit.Types import GHC.Utils.Outputable @@ -39,30 +48,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +80,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +91,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +104,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- + +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c1cd8009d9c8cf2666adb9af7449efafc7adcbb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c1cd8009d9c8cf2666adb9af7449efafc7adcbb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 09:35:24 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 03 Apr 2024 05:35:24 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <660d22dce6909_2422d3ad57c8119855@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 4c0c2287 by David Knothe at 2024-04-03T11:35:14+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4c0c228760e1e960756e36e1e632f115b14f2fb8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4c0c228760e1e960756e36e1e632f115b14f2fb8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 10:02:37 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 06:02:37 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660d293db1d48_2422d31111470140883@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: c77a4119 by Rodrigo Mesquita at 2024-04-03T11:02:21+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 0bca53c2 by Rodrigo Mesquita at 2024-04-03T11:02:21+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -634,6 +634,7 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { @@ -643,16 +644,20 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; } -# endif const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,55 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent); + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+1,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2befe7f0d625968b12c2e2637b3731cdeb2d1234...0bca53c232f1b65fb49d7b1c89bb553346ff4032 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2befe7f0d625968b12c2e2637b3731cdeb2d1234...0bca53c232f1b65fb49d7b1c89bb553346ff4032 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 10:22:16 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 03 Apr 2024 06:22:16 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660d2dd8d1378_4ce5c2c23c45979a@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: 2622622f by Fendor at 2024-04-03T12:21:59+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 18 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,19 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , unsafeDecodeUtf + , unsafeEncodeUtf + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import System.OsPath +import Data.Either + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsPath -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,9 +455,9 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. @@ -488,14 +490,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +505,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +514,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +545,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +583,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> OsPath -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +602,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +675,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +728,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,7 @@ where import GHC.Prelude import GHC.Unit +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -16,6 +17,7 @@ import GHC.Platform.Ways import Data.IORef import GHC.Data.FastString import qualified Data.Set as Set +import System.OsPath (OsPath) -- | The 'FinderCache' maps modules to the result of -- searching for that module. It records the results of searching for @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsPath + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsPath + , finder_dynHiSuf :: OsPath + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsPath + , finder_dynObjectSuf :: OsPath + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,10 +7,19 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude + +import GHC.Data.OsPath +import qualified GHC.Data.Strict as Strict import GHC.Unit.Types import GHC.Utils.Outputable @@ -39,30 +48,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +80,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +91,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +104,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- + +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -69,6 +69,7 @@ GHC.Data.List.Infinite GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList +GHC.Data.OsPath GHC.Data.Pair GHC.Data.Strict GHC.Data.StringBuffer ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -70,6 +70,7 @@ GHC.Data.List.Infinite GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList +GHC.Data.OsPath GHC.Data.Pair GHC.Data.Strict GHC.Data.StringBuffer ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2622622f9be367bda8740c7fcbb578dede2f9c55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2622622f9be367bda8740c7fcbb578dede2f9c55 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 10:34:43 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 06:34:43 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660d30c3df713_4ce5c49fdb8621e9@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: d6f0aa80 by Rodrigo Mesquita at 2024-04-03T11:34:30+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - afebba1e by Rodrigo Mesquita at 2024-04-03T11:34:31+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -634,6 +634,7 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { @@ -643,16 +644,20 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; } -# endif const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if (!(res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent))) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0bca53c232f1b65fb49d7b1c89bb553346ff4032...afebba1e237fd597ac452b342ac2f359715e77d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0bca53c232f1b65fb49d7b1c89bb553346ff4032...afebba1e237fd597ac452b342ac2f359715e77d4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 10:37:01 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 06:37:01 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660d314deba50_4ce5c593b986247c@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 07d9215b by Rodrigo Mesquita at 2024-04-03T11:36:48+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - f821f42c by Rodrigo Mesquita at 2024-04-03T11:36:49+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -634,6 +634,7 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { @@ -643,16 +644,20 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; } -# endif const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if (res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent)) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/afebba1e237fd597ac452b342ac2f359715e77d4...f821f42c7f1ca417128a148c1bcaee222437f8ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/afebba1e237fd597ac452b342ac2f359715e77d4...f821f42c7f1ca417128a148c1bcaee222437f8ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 10:38:17 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 06:38:17 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: fixup! rts: lookupSymbolInNativeObj in Windows Message-ID: <660d3199521cf_4ce5c6a9dd46275@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 46813433 by Rodrigo Mesquita at 2024-04-03T11:38:03+01:00 fixup! rts: lookupSymbolInNativeObj in Windows - - - - - 8e59449e by Rodrigo Mesquita at 2024-04-03T11:38:03+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 9 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - rts/Linker.c - rts/linker/LoadNativeObjPosix.c - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== rts/Linker.c ===================================== @@ -634,6 +634,7 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { @@ -643,16 +644,20 @@ void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif RELEASE_LOCK(&linker_mutex); return result; } -# endif const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) char *errmsg; if (loadNativeObj(dll_name, &errmsg)) { return NULL; @@ -660,13 +665,6 @@ const char *addDLL(pathchar* dll_name) ASSERT(errmsg != NULL); return errmsg; } - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1861,12 +1859,19 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void * loadNativeObj (pathchar *path, char **errmsg) { - IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%s'\n", path)); + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); +#else + barf("loadNativeObj: not implemented on this platform"); +#endif #if defined(OBJFORMAT_ELF) if (!r) { @@ -1879,15 +1884,6 @@ void * loadNativeObj (pathchar *path, char **errmsg) RELEASE_LOCK(&linker_mutex); return r; } -#else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); - barf("loadNativeObj: not implemented on this platform"); -} -#endif static HsInt unloadNativeObj_(void *handle) { ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -1,7 +1,10 @@ -#include "CheckUnload.h" -#include "ForeignExports.h" #include "LinkerInternals.h" #include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" #include "RtsUtils.h" #include "Profiling.h" @@ -208,4 +211,4 @@ success: return retval; } - +#endif /* elf + macho */ ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if ((res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent))) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f821f42c7f1ca417128a148c1bcaee222437f8ad...8e59449effd9630750533bf536a975eff1b7b6e8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f821f42c7f1ca417128a148c1bcaee222437f8ad...8e59449effd9630750533bf536a975eff1b7b6e8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 11:03:30 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 03 Apr 2024 07:03:30 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <660d3782743d4_4ce5ca096f067070@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: df358de7 by David Knothe at 2024-04-03T13:03:07+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/deSugar/should_run/Or5.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df358de773d27609d1da7ce3a3afe7d322c844e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df358de773d27609d1da7ce3a3afe7d322c844e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 11:04:52 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 03 Apr 2024 07:04:52 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <660d37d493b5e_4ce5cad6f3868251@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 2bfed745 by David Knothe at 2024-04-03T13:04:46+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/deSugar/should_run/Or5.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2bfed745a67e4b461db8ccb241bc734996972e3f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2bfed745a67e4b461db8ccb241bc734996972e3f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 11:58:26 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 03 Apr 2024 07:58:26 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <660d4462d6bbe_4ce5c11c74c87947d@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 413b0ba9 by Fendor at 2024-04-03T13:57:05+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. - - - - - 54a9bfea by Fendor at 2024-04-03T13:57:58+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 13 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -54,6 +53,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import Data.Functor.Identity +import Data.Bifunctor (Bifunctor(second)) +import Data.Coerce -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -75,7 +77,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +123,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +139,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +150,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +158,33 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) - - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) - - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) - - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) - --- | Write an interface file + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + tables :: [SomeReaderTable IO] + tables = + [ SomeReaderTable initFastStringReaderTable + , SomeReaderTable (initReadNameCachedBinary name_cache) + , SomeReaderTable @IO @NonBindingName (coerce (initReadNameCachedBinary name_cache)) + ] + + tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables + + final_bh <- foldM (\bh (SomeReaderTable (tbl' :: Identity (ReaderTable a))) -> do + let tbl = runIdentity tbl' + res <- Binary.forwardGet bh (getTable tbl bh) + let newDecoder = mkReaderFromTable tbl res + pure $ addReaderToUserData (mkSomeBinaryReader newDecoder) bh + ) bh tables + + pure final_bh + +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +197,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +214,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +238,40 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + writerTables = + [ SomeWriterTable initFastStringWriterTable + , SomeWriterTable initWriteNameTable + , SomeWriterTable (fmap (second (\(BinaryWriter f) -> BinaryWriter (\bh name -> f bh (getNonBindingName name)))) initWriteNameTable) + ] + + tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + + let writerUserData = + mkWriterUserData $ + map + (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) + tables + + let bh = setWriterUserData bh' writerUserData + (fs_count : name_count : _, r) <- + putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +283,108 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be duplicated 'FastString's and 'Name's. +To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ │ +│ ModIface │ +│ Payload │ +│ │ +├──────────────┤ +│ Ptr FS ├───────────┐ +├──────────────┤ │ +│ Ptr Name ├────────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄───────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄──────────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) +initReadNameCachedBinary cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +393,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +414,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +438,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +463,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +482,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter Proxy bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh name data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,14 +140,14 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh (NonBindingName ac) get bh = do aa <- get bh ab <- get bh - ac <- get bh - return (FieldLabel aa ab ac) + ac <- case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + return (FieldLabel aa ab $ getNonBindingName ac) flIsOverloaded :: FieldLabel -> Bool flIsOverloaded fl = ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,30 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + SomeReaderTable(..), + ReaderTable(..), + SomeWriterTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + NonBindingName(..), ) where import GHC.Prelude @@ -93,6 +111,7 @@ import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +123,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +140,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +174,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +269,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,42 +293,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -279,20 +352,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -313,7 +389,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -329,7 +405,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -350,8 +426,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -372,39 +448,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -412,7 +486,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -425,7 +499,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -437,7 +511,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -458,10 +532,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -484,15 +558,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -509,15 +583,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -533,15 +607,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -561,15 +635,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -980,63 +1054,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1044,14 +1118,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1062,7 +1136,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1081,73 +1157,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise non-binding names differently to 'Name'. +-- See Note [Binary UserData] +newtype NonBindingName = NonBindingName { getNonBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader + } + +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @NonBindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_non_binding_name bh (getNonBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data SomeReaderTable f = forall a . Typeable a => + SomeReaderTable (f (ReaderTable a)) + +data SomeWriterTable f = forall a . Typeable a => + SomeWriterTable (f (WriterTable, BinaryWriter a)) + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1156,34 +1356,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1212,43 +1390,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1260,12 +1437,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3b37648179355fde9e450a55a56e09bc3a12944...54a9bfea91adfb6d72315e1b9570793b3ed9ebca -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3b37648179355fde9e450a55a56e09bc3a12944...54a9bfea91adfb6d72315e1b9570793b3ed9ebca You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 12:26:45 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 03 Apr 2024 08:26:45 -0400 Subject: [Git][ghc/ghc][wip/T24463] 54 commits: EPA: Extend StringLiteral range to include trailing commas Message-ID: <660d4b05e596a_4ce5c15b8f7883323@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24463 at Glasgow Haskell Compiler / GHC Commits: 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 6c2b98a6 by Simon Peyton Jones at 2024-04-03T10:23:55+01:00 Clone in CorePrep - - - - - 2a6a8249 by Simon Peyton Jones at 2024-04-03T10:23:55+01:00 Wibble - - - - - 19be874d by Simon Peyton Jones at 2024-04-03T10:23:55+01:00 Wibble - - - - - 15 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c445c97492dfe9a5d12fb2b13d4291a4daa30c2...19be874ddb1318946d3332adc0264ac0f3074145 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c445c97492dfe9a5d12fb2b13d4291a4daa30c2...19be874ddb1318946d3332adc0264ac0f3074145 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 12:43:36 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 03 Apr 2024 08:43:36 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660d4ef8c283b_4ce5c17fe79c921aa@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 1e2705b0 by Fendor at 2024-04-03T14:43:14+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -77,7 +77,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -139,7 +139,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -150,7 +150,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -158,7 +158,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do let -- The order of these entries matters! @@ -197,14 +197,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -214,7 +214,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -238,7 +238,7 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do let -- The order of these entries matters! @@ -384,7 +384,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -393,7 +393,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -414,7 +414,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -438,7 +438,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -464,7 +464,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -112,9 +112,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -122,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -182,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -191,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -214,7 +214,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -233,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -261,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -277,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -335,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -346,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -39,7 +39,7 @@ computeFingerprint put_nonbinding_name a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter Proxy bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Control.Monad +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -87,7 +89,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding @@ -173,70 +174,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -255,23 +269,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -279,42 +293,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -323,20 +352,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -357,7 +389,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -373,7 +405,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -394,8 +426,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -416,39 +448,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -456,7 +486,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -469,7 +499,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -481,7 +511,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -502,10 +532,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -528,15 +558,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -553,15 +583,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -577,15 +607,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -605,15 +635,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1024,63 +1054,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1088,14 +1118,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1190,31 +1220,31 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } deriving (Functor) data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -findUserDataReader :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader -findUserDataWriter :: forall a . Typeable a => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) @@ -1231,8 +1261,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1241,11 +1271,11 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_non_binding_name put_binding_name put_fs = mkWriterUserData @@ -1265,12 +1295,12 @@ data SomeWriterTable f = forall a . Typeable a => SomeWriterTable (f (WriterTable, BinaryWriter a)) data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int } --------------------------------------------------------- @@ -1310,14 +1340,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1326,12 +1356,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1368,34 +1398,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit c641b7349239c497cbd64a64cd21fd388f431b9f +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2705b08f39e87ccb4396739f0c67ef999e8d88 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2705b08f39e87ccb4396739f0c67ef999e8d88 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 13:32:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 09:32:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 41 commits: Initial ./configure support for selecting I/O managers Message-ID: <660d5a697c0f5_4ce5c1efa5c81158c4@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - a11d1a57 by Ben Gamari at 2024-04-03T09:31:53-04:00 testsuite: Introduce template-haskell-exports test - - - - - 799caa34 by Luite Stegeman at 2024-04-03T09:32:00-04:00 Update correct counter in bumpTickyAllocd - - - - - a5f45a7f by Andrei Borzenkov at 2024-04-03T09:32:00-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 15 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/944ef9924c37b108174b8ed1006112dde4e7cc28...a5f45a7f00c7686d9f01075295370d205a6ad84c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/944ef9924c37b108174b8ed1006112dde4e7cc28...a5f45a7f00c7686d9f01075295370d205a6ad84c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 14:39:54 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 03 Apr 2024 10:39:54 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] 2 commits: Revert "Use TemplateHaskellQuotes in TH.Syntax to construct Names" Message-ID: <660d6a3a6e123_4ce5c26ff99412667e@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 2a1c7a73 by Teo Camarasu at 2024-04-03T14:00:32+01:00 Revert "Use TemplateHaskellQuotes in TH.Syntax to construct Names" This reverts commit 983ce55815f2dd57f84ee86eee97febf7d80b470. - - - - - 85e4fe45 by Teo Camarasu at 2024-04-03T15:25:07+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. We introduce two new packages: template-haskell-in-tree and ghc-boot-th-in-tree. These package are carbon copies of template-haskell and ghc-boot-th respectively. They only differ in their name. When compiling the stage1 compiler we use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As these two packages are identical, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 13 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - + libraries/template-haskell-in-tree/template-haskell-in-tree.cabal - libraries/template-haskell/Language/Haskell/TH/Syntax.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,11 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +120,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +129,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellInTree , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,11 +54,11 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, + osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThInTree = lib "ghc-boot-th-in-tree" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellInTree = lib "template-haskell-in-tree" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -23,10 +23,12 @@ import Rules.Libffi import Settings import Target import Utilities +import Debug.Trace import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp)) import GHC.Toolchain.Program import GHC.Platform.ArchOS +import qualified System.Directory as IO -- | Track this file to rebuild generated files whenever it changes. trackGenerateHs :: Expr () @@ -119,6 +121,7 @@ generatePackageCode context@(Context stage pkg _ _) = do let dir = buildDir context generated f = (root -/- dir -/- "**/*.hs") ?== f && not ("//autogen/*" ?== f) go gen file = generate file context gen + generated ?> \file -> do let unpack = fromMaybe . error $ "No generator for " ++ file ++ "." (src, builder) <- unpack <$> findGenerator context file @@ -143,6 +146,22 @@ generatePackageCode context@(Context stage pkg _ _) = do when (pkg == ghcBoot) $ do root -/- "**" -/- dir -/- "GHC/Version.hs" %> go generateVersionHs root -/- "**" -/- dir -/- "GHC/Platform/Host.hs" %> go generatePlatformHostHs + when (pkg == ghcBootThInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + createFileLink (cwd -/- "libraries/ghc-boot-th" -/- makeRelative prefix file) file + when (pkg == templateHaskellInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + let rel = makeRelative prefix file + let rootCandidate = cwd -/- "libraries/template-haskell" -/- rel + let vendoredCandidate = cwd -/- "libraries/template-haskell" -/- "vendored-filepath" -/- rel + exists <- liftIO $ IO.doesFileExist rootCandidate + if exists + then createFileLink rootCandidate file + else createFileLink vendoredCandidate file when (pkg == compiler) $ do root -/- primopsTxt stage %> \file -> do @@ -325,6 +344,7 @@ templateRules = do templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal" $ projectVersion templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion @@ -348,7 +368,6 @@ templateRules = do , interpolateVar "LlvmMaxVersion" $ replaceEq '.' ',' <$> setting LlvmMaxVersion ] - -- Generators -- | GHC wrapper scripts used for passing the path to the right package database ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,8 +172,8 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text + , templateHaskellInTree , transformers , semaphoreCompat , unlit -- # executable ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellInTree , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- we don't keep ghc-boot-in-tree and template-haskell-in-tree + -- as they are only needed for bootstrapping Template Haskell + | p == ghcBootThInTree = False + | p == templateHaskellInTree = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -78,6 +78,7 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ andM [expr ghcWithInterpreter, notStage0] `cabalFlag` "internal-interpreter" + , stage0 `cabalFlag` "bootstrap-th" , notM cross `cabalFlag` "terminfo" , arg "-build-tool-depends" , flag UseLibzstd `cabalFlag` "with-libzstd" @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat [ + ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th.cabal is automatically generated from +-- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. + +name: ghc-boot-th-in-tree +version: 9.11 +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th.cabal is automatically generated from +-- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. + +name: ghc-boot-th-in-tree +version: @ProjectVersionMunged@ +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -81,7 +86,12 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + build-depends: + ghc-boot-th-in-tree == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,11 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +89,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell-in-tree/template-haskell-in-tree.cabal ===================================== @@ -0,0 +1,71 @@ +-- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- ../../configure. Make sure you are editing template-haskell.cabal.in, not +-- template-haskell.cabal. + +name: template-haskell-in-tree +version: 2.22.0.0 +-- NOTE: Don't forget to update ./changelog.md +license: BSD3 +license-file: LICENSE +category: Template Haskell +maintainer: libraries at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Support library for Template Haskell +build-type: Simple +Cabal-Version: >= 1.10 +description: + This package provides modules containing facilities for manipulating + Haskell source code using Template Haskell. + . + See for more + information. + +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/template-haskell-in-tree + +Library + default-language: Haskell2010 + other-extensions: + BangPatterns + CPP + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + FlexibleInstances + RankNTypes + RoleAnnotations + ScopedTypeVariables + + exposed-modules: + Language.Haskell.TH + Language.Haskell.TH.Lib + Language.Haskell.TH.Ppr + Language.Haskell.TH.PprLib + Language.Haskell.TH.Quote + Language.Haskell.TH.Syntax + Language.Haskell.TH.LanguageExtensions + Language.Haskell.TH.CodeDo + Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + + build-depends: + base >= 4.11 && < 4.21, + ghc-boot-th-in-tree == 9.11, + ghc-prim, + pretty == 1.1.* + + other-modules: + System.FilePath + System.FilePath.Posix + System.FilePath.Windows + hs-source-dirs: ./vendored-filepath . + default-extensions: + ImplicitPrelude + + ghc-options: -Wall ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -7,7 +7,6 @@ BangPatterns, RecordWildCards, ImplicitParams #-} {-# OPTIONS_GHC -fno-warn-inline-rule-shadowing #-} -{-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE StandaloneKindSignatures #-} ----------------------------------------------------------------------------- @@ -69,6 +68,7 @@ import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Stack import Data.Array.Byte (ByteArray(..)) import GHC.Exts @@ -1083,7 +1083,8 @@ instance Lift (Fixed.Fixed a) where ex <- lift x return (ConE mkFixedName `AppE` ex) where - mkFixedName = 'Fixed.MkFixed + mkFixedName = + mkNameG DataName "base" "Data.Fixed" "MkFixed" instance Integral a => Lift (Ratio a) where liftTyped x = unsafeCodeCoerce (lift x) @@ -1152,8 +1153,19 @@ instance Lift ByteArray where ptr :: ForeignPtr Word8 ptr = ForeignPtr (byteArrayContents# pb) (PlainPtr (unsafeCoerce# pb)) + +-- We can't use a TH quote in this module because we're in the template-haskell +-- package, so we conconct this quite defensive solution to make the correct name +-- which will work if the package name or module name changes in future. addrToByteArrayName :: Name -addrToByteArrayName = 'addrToByteArray +addrToByteArrayName = helper + where + helper :: HasCallStack => Name + helper = + case getCallStack ?callStack of + [] -> error "addrToByteArrayName: empty call stack" + (_, SrcLoc{..}) : _ -> mkNameG_v srcLocPackage srcLocModule "addrToByteArray" + addrToByteArray :: Int -> Addr# -> ByteArray addrToByteArray (I# len) addr = runST $ ST $ @@ -1371,24 +1383,23 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) trueName, falseName :: Name -trueName = 'True -falseName = 'False +trueName = mkNameG DataName "ghc-prim" "GHC.Types" "True" +falseName = mkNameG DataName "ghc-prim" "GHC.Types" "False" nothingName, justName :: Name -nothingName = 'Nothing -justName = 'Just +nothingName = mkNameG DataName "ghc-internal" "GHC.Internal.Maybe" "Nothing" +justName = mkNameG DataName "ghc-internal" "GHC.Internal.Maybe" "Just" leftName, rightName :: Name -leftName = 'Left -rightName = 'Right +leftName = mkNameG DataName "ghc-internal" "GHC.Internal.Data.Either" "Left" +rightName = mkNameG DataName "ghc-internal" "GHC.Internal.Data.Either" "Right" nonemptyName :: Name -nonemptyName = '(:|) +nonemptyName = mkNameG DataName "ghc-internal" "GHC.Internal.Base" ":|" oneName, manyName :: Name -oneName = 'One -manyName = 'Many - +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- -- Generic Lift implementations View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e9290c3e65208709854b1419e649228d37816194...85e4fe4520970b390b6cd6eacaf0e59d2d63f2b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e9290c3e65208709854b1419e649228d37816194...85e4fe4520970b390b6cd6eacaf0e59d2d63f2b7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 14:57:21 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 03 Apr 2024 10:57:21 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660d6e50e8b14_231e18855c045868@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: d3f22b9f by Teo Camarasu at 2024-04-03T15:55:45+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. We introduce two new packages: template-haskell-in-tree and ghc-boot-th-in-tree. These package are carbon copies of template-haskell and ghc-boot-th respectively. They only differ in their name. When compiling the stage1 compiler we use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As these two packages are identical, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 12 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - + libraries/template-haskell-in-tree/template-haskell-in-tree.cabal Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,11 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +120,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +129,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellInTree , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,11 +54,11 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, + osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThInTree = lib "ghc-boot-th-in-tree" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellInTree = lib "template-haskell-in-tree" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -27,6 +27,7 @@ import Utilities import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp)) import GHC.Toolchain.Program import GHC.Platform.ArchOS +import qualified System.Directory as IO -- | Track this file to rebuild generated files whenever it changes. trackGenerateHs :: Expr () @@ -119,6 +120,7 @@ generatePackageCode context@(Context stage pkg _ _) = do let dir = buildDir context generated f = (root -/- dir -/- "**/*.hs") ?== f && not ("//autogen/*" ?== f) go gen file = generate file context gen + generated ?> \file -> do let unpack = fromMaybe . error $ "No generator for " ++ file ++ "." (src, builder) <- unpack <$> findGenerator context file @@ -143,6 +145,22 @@ generatePackageCode context@(Context stage pkg _ _) = do when (pkg == ghcBoot) $ do root -/- "**" -/- dir -/- "GHC/Version.hs" %> go generateVersionHs root -/- "**" -/- dir -/- "GHC/Platform/Host.hs" %> go generatePlatformHostHs + when (pkg == ghcBootThInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + createFileLink (cwd -/- "libraries/ghc-boot-th" -/- makeRelative prefix file) file + when (pkg == templateHaskellInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + let rel = makeRelative prefix file + let rootCandidate = cwd -/- "libraries/template-haskell" -/- rel + let vendoredCandidate = cwd -/- "libraries/template-haskell" -/- "vendored-filepath" -/- rel + exists <- liftIO $ IO.doesFileExist rootCandidate + if exists + then createFileLink rootCandidate file + else createFileLink vendoredCandidate file when (pkg == compiler) $ do root -/- primopsTxt stage %> \file -> do @@ -325,6 +343,7 @@ templateRules = do templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal" $ projectVersion templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion @@ -348,7 +367,6 @@ templateRules = do , interpolateVar "LlvmMaxVersion" $ replaceEq '.' ',' <$> setting LlvmMaxVersion ] - -- Generators -- | GHC wrapper scripts used for passing the path to the right package database ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,8 +172,8 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text + , templateHaskellInTree , transformers , semaphoreCompat , unlit -- # executable ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellInTree , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- we don't keep ghc-boot-in-tree and template-haskell-in-tree + -- as they are only needed for bootstrapping Template Haskell + | p == ghcBootThInTree = False + | p == templateHaskellInTree = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -78,6 +78,7 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ andM [expr ghcWithInterpreter, notStage0] `cabalFlag` "internal-interpreter" + , stage0 `cabalFlag` "bootstrap-th" , notM cross `cabalFlag` "terminfo" , arg "-build-tool-depends" , flag UseLibzstd `cabalFlag` "with-libzstd" @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat [ + ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th.cabal is automatically generated from +-- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. + +name: ghc-boot-th-in-tree +version: 9.11 +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th-in-tree.cabal is automatically generated from +-- ghc-boot-th.cabal-in-tree.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal-in-tree.in, not ghc-boot-th-in-tree.cabal. + +name: ghc-boot-th-in-tree +version: @ProjectVersionMunged@ +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th-in-tree + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -81,7 +86,12 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + build-depends: + ghc-boot-th-in-tree == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,11 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +89,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell-in-tree/template-haskell-in-tree.cabal ===================================== @@ -0,0 +1,71 @@ +-- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- ../../configure. Make sure you are editing template-haskell.cabal.in, not +-- template-haskell.cabal. + +name: template-haskell-in-tree +version: 2.22.0.0 +-- NOTE: Don't forget to update ./changelog.md +license: BSD3 +license-file: LICENSE +category: Template Haskell +maintainer: libraries at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Support library for Template Haskell +build-type: Simple +Cabal-Version: >= 1.10 +description: + This package provides modules containing facilities for manipulating + Haskell source code using Template Haskell. + . + See for more + information. + +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/template-haskell-in-tree + +Library + default-language: Haskell2010 + other-extensions: + BangPatterns + CPP + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + FlexibleInstances + RankNTypes + RoleAnnotations + ScopedTypeVariables + + exposed-modules: + Language.Haskell.TH + Language.Haskell.TH.Lib + Language.Haskell.TH.Ppr + Language.Haskell.TH.PprLib + Language.Haskell.TH.Quote + Language.Haskell.TH.Syntax + Language.Haskell.TH.LanguageExtensions + Language.Haskell.TH.CodeDo + Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + + build-depends: + base >= 4.11 && < 4.21, + ghc-boot-th-in-tree == 9.11, + ghc-prim, + pretty == 1.1.* + + other-modules: + System.FilePath + System.FilePath.Posix + System.FilePath.Windows + hs-source-dirs: ./vendored-filepath . + default-extensions: + ImplicitPrelude + + ghc-options: -Wall View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3f22b9f04663d4db5b9b73ffa5ad09397ba6185 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3f22b9f04663d4db5b9b73ffa5ad09397ba6185 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 14:57:31 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 10:57:31 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660d6e5b65e0_231e1885b74459ee@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 19a7bf09 by Rodrigo Mesquita at 2024-04-03T15:55:00+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - f7fae3a0 by Rodrigo Mesquita at 2024-04-03T15:55:00+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 18 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/ObjLink.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -74,7 +74,7 @@ lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) lookupSymbolInDLL dll str_in = do let str = prefixUnderscore str_in withCAString str $ \c_str -> do - addr <- c_lookupSymbolInDLL dll c_str + addr <- c_lookupSymbolInNativeObj dll c_str if addr == nullPtr then return Nothing else return (Just addr) @@ -112,7 +112,7 @@ loadDLL str0 = do -- (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> alloca $ \errmsg_ptr -> (,) - <$> c_addDLL dll errmsg_ptr + <$> c_loadNativeObj dll errmsg_ptr <*> peek errmsg_ptr if maybe_handle == nullPtr @@ -176,8 +176,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) -foreign import ccall unsafe "lookupSymbolInDLL" c_lookupSymbolInDLL :: Ptr LoadedDLL -> CString -> IO (Ptr a) +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInNativeObj) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,87 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static void * -internal_dlopen(const char *dll_name, const char **errmsg_ptr) -{ - OpenedSO* o_so; - void *hdl; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - char *errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - char *errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - *errmsg_ptr = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return hdl; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -657,11 +571,10 @@ internal_dlopen(const char *dll_name, const char **errmsg_ptr) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -669,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -722,98 +634,37 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif -void *lookupSymbolInDLL(void *handle, const char *symbol_name) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ACQUIRE_LOCK(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif + + RELEASE_LOCK(&linker_mutex); return result; } -# endif -void *addDLL(pathchar* dll_name, const char **errmsg_ptr) +const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - void *handle; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - handle = internal_dlopen(dll_name, &errmsg); - - if (handle != NULL) { - return handle; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - *errmsg_ptr = errmsg; // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - handle = internal_dlopen(line+match[2].rm_so, errmsg_ptr); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return handle; - -# elif defined(OBJFORMAT_PEi386) - // FIXME - return addDLL_PEi386(dll_name, NULL); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1240,10 +1091,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1908,12 +1759,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -2000,25 +1859,33 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); - RELEASE_LOCK(&linker_mutex); - return r; -} + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); #else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); barf("loadNativeObj: not implemented on this platform"); -} #endif -HsInt unloadNativeObj (void *handle) +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + + RELEASE_LOCK(&linker_mutex); + return r; +} + +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2051,11 +1918,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -509,6 +509,7 @@ extern char **environ; SymI_HasDataProto(stg_block_putmvar) \ MAIN_CAP_SYM \ SymI_HasProto(addDLL) \ + SymI_HasProto(loadNativeObj) \ SymI_HasProto(addLibrarySearchPath) \ SymI_HasProto(removeLibrarySearchPath) \ SymI_HasProto(findSystemLibrary) \ @@ -619,7 +620,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ - SymI_HasProto(lookupSymbolInDLL) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,10 +90,10 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); -/* load a dynamic library */ -void *addDLL(pathchar* dll_name, const char **errmsg); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); -void *lookupSymbolInDLL(void *handle, const char *symbol_name); +/* load a dynamic library */ +const char *addDLL(pathchar* dll_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,214 @@ +#include "LinkerInternals.h" +#include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + +#endif /* elf + macho */ ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if ((res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent))) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %ls\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e59449effd9630750533bf536a975eff1b7b6e8...f7fae3a08236c0243cdb691ebfdfe53b95606148 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e59449effd9630750533bf536a975eff1b7b6e8...f7fae3a08236c0243cdb691ebfdfe53b95606148 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 14:57:39 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 10:57:39 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 3 commits: linker: Avoid linear search when looking up Haskell symbols via dlsym Message-ID: <660d6e634dfb2_231e18af488461e7@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 4e470201 by Alexis King at 2024-04-03T15:55:42+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 2a219c62 by Rodrigo Mesquita at 2024-04-03T15:55:42+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 39e5cb6c by Rodrigo Mesquita at 2024-04-03T15:55:42+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 26 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - testsuite/tests/rts/linker/T2615.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -24,6 +24,7 @@ import GHCi.RemoteTypes import GHCi.ResolvedBCO import GHC.Builtin.PrimOps +import GHC.Builtin.PrimOps.Ids import GHC.Builtin.Names import GHC.Unit.Types @@ -38,6 +39,8 @@ import GHC.Utils.Outputable import GHC.Types.Name import GHC.Types.Name.Env +import qualified GHC.Types.Id as Id +import GHC.Types.Unique.DFM import Language.Haskell.Syntax.Module.Name @@ -52,31 +55,32 @@ import GHC.Exts linkBCO :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO -linkBCO interp le bco_ix +linkBCO interp pkgs_loaded le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) - ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0) + lits <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le) (ssElts lits0) + ptrs <- mapM (resolvePtr interp pkgs_loaded le bco_ix) (ssElts ptrs0) return (ResolvedBCO isLittleEndian arity insns bitmap (listArray (0, fromIntegral (sizeSS lits0)-1) lits) (addListToSS emptySS ptrs)) -lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word -lookupLiteral interp le ptr = case ptr of +lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> BCONPtr -> IO Word +lookupLiteral interp pkgs_loaded le ptr = case ptr of BCONPtrWord lit -> return lit BCONPtrLbl sym -> do Ptr a# <- lookupStaticPtr interp sym return (W# (int2Word# (addr2Int# a#))) BCONPtrItbl nm -> do - Ptr a# <- lookupIE interp (itbl_env le) nm + Ptr a# <- lookupIE interp pkgs_loaded (itbl_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrAddr nm -> do - Ptr a# <- lookupAddr interp (addr_env le) nm + Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm return (W# (int2Word# (addr2Int# a#))) BCONPtrStr _ -> -- should be eliminated during assembleBCOs @@ -90,19 +94,19 @@ lookupStaticPtr interp addr_of_label_string = do Nothing -> linkFail "GHC.ByteCode.Linker: can't find label" (unpackFS addr_of_label_string) -lookupIE :: Interp -> ItblEnv -> Name -> IO (Ptr ()) -lookupIE interp ie con_nm = +lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ()) +lookupIE interp pkgs_loaded ie con_nm = case lookupNameEnv ie con_nm of Just (_, ItblPtr a) -> return (fromRemotePtr (castRemotePtr a)) Nothing -> do -- try looking up in the object files. let sym_to_find1 = nameToCLabel con_nm "con_info" - m <- lookupSymbol interp sym_to_find1 + m <- lookupHsSymbol interp pkgs_loaded con_nm "con_info" case m of Just addr -> return addr Nothing -> do -- perhaps a nullary constructor? let sym_to_find2 = nameToCLabel con_nm "static_info" - n <- lookupSymbol interp sym_to_find2 + n <- lookupHsSymbol interp pkgs_loaded con_nm "static_info" case n of Just addr -> return addr Nothing -> linkFail "GHC.ByteCode.Linker.lookupIE" @@ -110,34 +114,35 @@ lookupIE interp ie con_nm = unpackFS sym_to_find2) -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode -lookupAddr :: Interp -> AddrEnv -> Name -> IO (Ptr ()) -lookupAddr interp ae addr_nm = do +lookupAddr :: Interp -> PkgsLoaded -> AddrEnv -> Name -> IO (Ptr ()) +lookupAddr interp pkgs_loaded ae addr_nm = do case lookupNameEnv ae addr_nm of Just (_, AddrPtr ptr) -> return (fromRemotePtr ptr) Nothing -> do -- try looking up in the object files. let sym_to_find = nameToCLabel addr_nm "bytes" -- see Note [Bytes label] in GHC.Cmm.CLabel - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded addr_nm "bytes" case m of Just ptr -> return ptr Nothing -> linkFail "GHC.ByteCode.Linker.lookupAddr" (unpackFS sym_to_find) -lookupPrimOp :: Interp -> PrimOp -> IO (RemotePtr ()) -lookupPrimOp interp primop = do +lookupPrimOp :: Interp -> PkgsLoaded -> PrimOp -> IO (RemotePtr ()) +lookupPrimOp interp pkgs_loaded primop = do let sym_to_find = primopToCLabel primop "closure" - m <- lookupSymbol interp (mkFastString sym_to_find) + m <- lookupHsSymbol interp pkgs_loaded (Id.idName $ primOpId primop) "closure" case m of Just p -> return (toRemotePtr p) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" sym_to_find resolvePtr :: Interp + -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> BCOPtr -> IO ResolvedBCOPtr -resolvePtr interp le bco_ix ptr = case ptr of +resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of BCOPtrName nm | Just ix <- lookupNameEnv bco_ix nm -> return (ResolvedBCORef ix) -- ref to another BCO in this group @@ -149,20 +154,38 @@ resolvePtr interp le bco_ix ptr = case ptr of -> assertPpr (isExternalName nm) (ppr nm) $ do let sym_to_find = nameToCLabel nm "closure" - m <- lookupSymbol interp sym_to_find + m <- lookupHsSymbol interp pkgs_loaded nm "closure" case m of Just p -> return (ResolvedBCOStaticPtr (toRemotePtr p)) Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (unpackFS sym_to_find) BCOPtrPrimOp op - -> ResolvedBCOStaticPtr <$> lookupPrimOp interp op + -> ResolvedBCOStaticPtr <$> lookupPrimOp interp pkgs_loaded op BCOPtrBCO bco - -> ResolvedBCOPtrBCO <$> linkBCO interp le bco_ix bco + -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco BCOPtrBreakArray breakarray -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba) +lookupHsSymbol :: Interp -> PkgsLoaded -> Name -> String -> IO (Maybe (Ptr ())) +lookupHsSymbol interp pkgs_loaded nm sym_suffix = do + massertPpr (isExternalName nm) (ppr nm) + let sym_to_find = nameToCLabel nm sym_suffix + pkg_id = moduleUnitId $ nameModule nm + loaded_dlls = maybe [] loaded_pkg_hs_dlls $ lookupUDFM pkgs_loaded pkg_id + + go (dll:dlls) = do + mb_ptr <- lookupSymbolInDLL interp dll sym_to_find + case mb_ptr of + Just ptr -> pure (Just ptr) + Nothing -> go dlls + go [] = + -- See Note [Symbols may not be found in pkgs_loaded] in GHC.Linker.Types + lookupSymbol interp sym_to_find + + go loaded_dlls + linkFail :: String -> String -> IO a linkFail who what = throwGhcExceptionIO (ProgramError $ ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Driver/Plugins.hs ===================================== @@ -420,12 +420,12 @@ loadExternalPluginLib :: FilePath -> IO () loadExternalPluginLib path = do -- load library loadDLL path >>= \case - Just errmsg -> pprPanic "loadExternalPluginLib" - (vcat [ text "Can't load plugin library" - , text " Library path: " <> text path - , text " Error : " <> text errmsg - ]) - Nothing -> do + Left errmsg -> pprPanic "loadExternalPluginLib" + (vcat [ text "Can't load plugin library" + , text " Library path: " <> text path + , text " Error : " <> text errmsg + ]) + Right _ -> do -- TODO: use returned LoadedDLL? -- resolve objects resolveObjs >>= \case True -> return () ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Tc.Utils.Monad import GHC.Runtime.Interpreter import GHCi.RemoteTypes import GHC.Iface.Load +import GHCi.Message (LoadedDLL) import GHC.ByteCode.Linker import GHC.ByteCode.Asm @@ -172,7 +173,7 @@ emptyLoaderState = LoaderState -- -- The linker's symbol table is populated with RTS symbols using an -- explicit list. See rts/Linker.c for details. - where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] emptyUniqDSet) + where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet) extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO () extendLoadedEnv interp new_bindings = @@ -221,8 +222,8 @@ loadDependencies -> SrcSpan -> [Module] -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required +-- When called, the loader state must have been initialized (see `initLoaderState`) loadDependencies interp hsc_env pls span needed_mods = do --- initLoaderState (hsc_dflags hsc_env) dl let opts = initLinkDepsOpts hsc_env -- Find what packages and linkables are required @@ -512,25 +513,25 @@ preloadLib interp hsc_env lib_paths framework_paths pls lib_spec = do DLL dll_unadorned -> do maybe_errstr <- loadDLL interp (platformSOName platform dll_unadorned) case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm | platformOS platform /= OSDarwin -> + Right _ -> maybePutStrLn logger "done" + Left mm | platformOS platform /= OSDarwin -> preloadFailed mm lib_paths lib_spec - Just mm | otherwise -> do + Left mm | otherwise -> do -- As a backup, on Darwin, try to also load a .so file -- since (apparently) some things install that way - see -- ticket #8770. let libfile = ("lib" ++ dll_unadorned) <.> "so" err2 <- loadDLL interp libfile case err2 of - Nothing -> maybePutStrLn logger "done" - Just _ -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left _ -> preloadFailed mm lib_paths lib_spec return pls DLLPath dll_path -> do do maybe_errstr <- loadDLL interp dll_path case maybe_errstr of - Nothing -> maybePutStrLn logger "done" - Just mm -> preloadFailed mm lib_paths lib_spec + Right _ -> maybePutStrLn logger "done" + Left mm -> preloadFailed mm lib_paths lib_spec return pls Framework framework -> @@ -614,7 +615,7 @@ loadExpr interp hsc_env span root_ul_bco = do -- Load the necessary packages and linkables let le = linker_env pls bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)] - resolved <- linkBCO interp le bco_ix root_ul_bco + resolved <- linkBCO interp (pkgs_loaded pls) le bco_ix root_ul_bco [root_hvref] <- createBCOs interp [resolved] fhv <- mkFinalizedHValue interp root_hvref return (pls, fhv) @@ -678,7 +679,7 @@ loadDecls interp hsc_env span cbc at CompiledByteCode{..} = do , addr_env = plusNameEnv (addr_env le) bc_strs } -- Link the necessary packages and linkables - new_bindings <- linkSomeBCOs interp le2 [cbc] + new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 [cbc] nms_fhvs <- makeForeignNamedHValueRefs interp new_bindings let ce2 = extendClosureEnv (closure_env le2) nms_fhvs !pls2 = pls { linker_env = le2 { closure_env = ce2 } } @@ -860,8 +861,8 @@ dynLoadObjs interp hsc_env pls at LoaderState{..} objs = do changeTempFilesLifetime tmpfs TFL_GhcSession [soFile] m <- loadDLL interp soFile case m of - Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos } - Just err -> linkFail msg err + Right _ -> return $! pls { temp_sos = (libPath, libName) : temp_sos } + Left err -> linkFail msg err where msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed" @@ -901,7 +902,7 @@ dynLinkBCOs interp pls bcos = do ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs) le2 = le1 { itbl_env = ie2, addr_env = ae2 } - names_and_refs <- linkSomeBCOs interp le2 cbcs + names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs -- We only want to add the external ones to the ClosureEnv let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs @@ -916,6 +917,7 @@ dynLinkBCOs interp pls bcos = do -- Link a bunch of BCOs and return references to their values linkSomeBCOs :: Interp + -> PkgsLoaded -> LinkerEnv -> [CompiledByteCode] -> IO [(Name,HValueRef)] @@ -923,7 +925,7 @@ linkSomeBCOs :: Interp -- the incoming unlinked BCOs. Each gives the -- value of the corresponding unlinked BCO -linkSomeBCOs interp le mods = foldr fun do_link mods [] +linkSomeBCOs interp pkgs_loaded le mods = foldr fun do_link mods [] where fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) @@ -932,7 +934,7 @@ linkSomeBCOs interp le mods = foldr fun do_link mods [] let flat = [ bco | bcos <- mods, bco <- bcos ] names = map unlinkedBCOName flat bco_ix = mkNameEnv (zip names [0..]) - resolved <- sequence [ linkBCO interp le bco_ix bco | bco <- flat ] + resolved <- sequence [ linkBCO interp pkgs_loaded le bco_ix bco | bco <- flat ] hvrefs <- createBCOs interp resolved return (zip names hvrefs) @@ -1094,18 +1096,18 @@ loadPackages' interp hsc_env new_pks pls = do -- Link dependents first ; pkgs' <- link pkgs deps -- Now link the package itself - ; (hs_cls, extra_cls) <- loadPackage interp hsc_env pkg_cfg + ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg | dep_pkg <- deps , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg) ] - ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls trans_deps)) } + ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) } | otherwise = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg))) -loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec]) +loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL]) loadPackage interp hsc_env pkg = do let dflags = hsc_dflags hsc_env @@ -1147,7 +1149,9 @@ loadPackage interp hsc_env pkg let classifieds = hs_classifieds ++ extra_classifieds -- Complication: all the .so's must be loaded before any of the .o's. - let known_dlls = [ dll | DLLPath dll <- classifieds ] + let known_hs_dlls = [ dll | DLLPath dll <- hs_classifieds ] + known_extra_dlls = [ dll | DLLPath dll <- extra_classifieds ] + known_dlls = known_hs_dlls ++ known_extra_dlls #if defined(CAN_LOAD_DLL) dlls = [ dll | DLL dll <- classifieds ] #endif @@ -1168,10 +1172,13 @@ loadPackage interp hsc_env pkg loadFrameworks interp platform pkg -- See Note [Crash early load_dyn and locateLib] -- Crash early if can't load any of `known_dlls` - mapM_ (load_dyn interp hsc_env True) known_dlls + mapM_ (load_dyn interp hsc_env True) known_extra_dlls + loaded_dlls <- mapMaybeM (load_dyn interp hsc_env True) known_hs_dlls -- For remaining `dlls` crash early only when there is surely -- no package's DLL around ... (not is_dyn) mapM_ (load_dyn interp hsc_env (not is_dyn) . platformSOName platform) dlls +#else + let loaded_dlls = [] #endif -- After loading all the DLLs, we can load the static objects. -- Ordering isn't important here, because we do one final link @@ -1191,7 +1198,7 @@ loadPackage interp hsc_env pkg if succeeded ok then do maybePutStrLn logger "done." - return (hs_classifieds, extra_classifieds) + return (hs_classifieds, extra_classifieds, loaded_dlls) else let errmsg = text "unable to load unit `" <> pprUnitInfoForUser pkg <> text "'" in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg)) @@ -1244,19 +1251,20 @@ restriction very easily. -- can be passed directly to loadDLL. They are either fully-qualified -- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so"). In the latter case, -- loadDLL is going to search the system paths to find the library. -load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO () +load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO (Maybe (RemotePtr LoadedDLL)) load_dyn interp hsc_env crash_early dll = do r <- loadDLL interp dll case r of - Nothing -> return () - Just err -> + Right loaded_dll -> pure (Just loaded_dll) + Left err -> if crash_early then cmdLineErrorIO err - else + else do when (diag_wopt Opt_WarnMissedExtraSharedLib diag_opts) $ logMsg logger (mkMCDiagnostic diag_opts (WarningWithFlag Opt_WarnMissedExtraSharedLib) Nothing) noSrcSpan $ withPprStyle defaultUserStyle (note err) + pure Nothing where diag_opts = initDiagOpts (hsc_dflags hsc_env) logger = hsc_logger hsc_env ===================================== compiler/GHC/Linker/MacOS.hs ===================================== @@ -172,6 +172,6 @@ loadFramework interp extraPaths rootname findLoadDLL (p:ps) errs = do { dll <- loadDLL interp (p fwk_file) ; case dll of - Nothing -> return Nothing - Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs) + Right _ -> return Nothing + Left err -> findLoadDLL ps ((p ++ ": " ++ err):errs) } ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -40,7 +40,8 @@ import GHC.Prelude import GHC.Unit ( UnitId, Module ) import GHC.ByteCode.Types ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type ( Fingerprint ) -import GHCi.RemoteTypes ( ForeignHValue ) +import GHCi.RemoteTypes ( ForeignHValue, RemotePtr ) +import GHCi.Message ( LoadedDLL ) import GHC.Types.Var ( Id ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnvList, filterNameEnv ) @@ -75,6 +76,56 @@ initialised. The LinkerEnv maps Names to actual closures (for interpreted code only), for use during linking. + +Note [Looking up symbols in the relevant objects] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In #23415, we determined that a lot of time (>10s, or even up to >35s!) was +being spent on dynamically loading symbols before actually interpreting code +when `:main` was run in GHCi. The root cause was that for each symbol we wanted +to lookup, we would traverse the list of loaded objects and try find the symbol +in each of them with dlsym (i.e. looking up a symbol was, worst case, linear in +the amount of loaded objects). + +To drastically improve load time (from +-38 seconds down to +-2s), we now: + +1. For every of the native objects loaded for a given unit, store the handles returned by `dlopen`. + - In `pkgs_loaded` of the `LoaderState`, which maps `UnitId`s to + `LoadedPkgInfo`s, where the handles live in its field `loaded_pkg_hs_dlls`. + +2. When looking up a Name (e.g. `lookupHsSymbol`), find that name's `UnitId` in + the `pkgs_loaded` mapping, + +3. And only look for the symbol (with `dlsym`) on the /handles relevant to that + unit/, rather than in every loaded object. + +Note [Symbols may not be found in pkgs_loaded] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Despite storing and looking for symbols in the relevant loaded libraries +handles for a given unit-id, as described in the note above, we may still have +to fallback to the "slow" `lookupSymbol` function (see its "fallback" call in +`lookupHsSymbol`). + +TODO: Ben: my understanding here is flawed; could you make this clearer?. + +This fallback is still needed because a given unit may be associated with +static objects (`loaded_pkg_hs_objs`) only and no dynamic libraries, but we +only `lookupSymbolInDLL` for loaded dynamic libraries. In that case, +`lookupSymbol` will do the right thing because, besides looking up the symbol +in every loaded dylib, it will end up searching the static name table and find those symbols. + +Arguably, we should rather generalise `lookupSymbolInDLL` to +`lookupSymbolInObject`, where an object may be a DLL/native object (as in +`loadNativeObj`), or e.g. a static archive, instead of having a special case +for dynamic libraries. + +This fallback is further needed because we don't look in the haskell objects +loaded for the home units (see the call to `loadModuleLinkables` in +`loadDependencies`, as opposed to the call to `loadPackages'` in the same +function which updates `pkgs_loaded`). We should ultimately keep track of the +objects loaded (probably in `objs_loaded`, for which `LinkableSet` is a bit +unsatisfactory, see a suggestion in 51c5c4eb1f2a33e4dc88e6a37b7b7c135234ce9b) +and be able to lookup symbols specifically in them too (similarly to +`lookupSymbolInDLL`). -} newtype Loader = Loader { loader_state :: MVar (Maybe LoaderState) } @@ -146,11 +197,13 @@ data LoadedPkgInfo { loaded_pkg_uid :: !UnitId , loaded_pkg_hs_objs :: ![LibrarySpec] , loaded_pkg_non_hs_objs :: ![LibrarySpec] + , loaded_pkg_hs_dlls :: ![RemotePtr LoadedDLL] + -- ^ See Note [Looking up symbols in the relevant objects] , loaded_pkg_trans_deps :: UniqDSet UnitId } instance Outputable LoadedPkgInfo where - ppr (LoadedPkgInfo uid hs_objs non_hs_objs trans_deps) = + ppr (LoadedPkgInfo uid hs_objs non_hs_objs _ trans_deps) = vcat [ppr uid , ppr hs_objs , ppr non_hs_objs @@ -159,10 +212,10 @@ instance Outputable LoadedPkgInfo where -- | Information we can use to dynamically link modules into the compiler data Linkable = LM { - linkableTime :: !UTCTime, -- ^ Time at which this linkable was built + linkableTime :: !UTCTime, -- ^ Time at which this linkable was built -- (i.e. when the bytecodes were produced, -- or the mod date on the files) - linkableModule :: !Module, -- ^ The linkable module itself + linkableModule :: !Module, -- ^ The linkable module itself linkableUnlinked :: [Unlinked] -- ^ Those files and chunks of code we have yet to link. -- ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -35,6 +35,7 @@ module GHC.Runtime.Interpreter -- * The object-code linker , initObjLinker , lookupSymbol + , lookupSymbolInDLL , lookupClosure , loadDLL , loadArchive @@ -151,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -440,57 +441,78 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + +lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of +#if defined(HAVE_INTERNAL_INTERPRETER) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) +#endif + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either -- an absolute pathname to the file, or a relative filename -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. --- --- Returns: --- --- Nothing => success --- Just err_msg => failure -loadDLL :: Interp -> String -> IO (Maybe String) +loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL)) loadDLL interp str = interpCmd interp (LoadDLL str) loadArchive :: Interp -> String -> IO () @@ -549,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/Message.hs ===================================== @@ -23,6 +23,7 @@ module GHCi.Message , getMessage, putMessage, getTHMessage, putTHMessage , Pipe(..), remoteCall, remoteTHCall, readPipe, writePipe , BreakModule + , LoadedDLL ) where import Prelude -- See note [Why do we import Prelude here?] @@ -73,8 +74,9 @@ data Message a where -- These all invoke the corresponding functions in the RTS Linker API. InitLinker :: Message () LookupSymbol :: String -> Message (Maybe (RemotePtr ())) + LookupSymbolInDLL :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ())) LookupClosure :: String -> Message (Maybe HValueRef) - LoadDLL :: String -> Message (Maybe String) + LoadDLL :: String -> Message (Either String (RemotePtr LoadedDLL)) LoadArchive :: String -> Message () -- error? LoadObj :: String -> Message () -- error? UnloadObj :: String -> Message () -- error? @@ -415,6 +417,9 @@ instance Binary a => Binary (EvalResult a) -- that type isn't available here. data BreakModule +-- | A dummy type that tags pointers returned by 'LoadDLL'. +data LoadedDLL + -- SomeException can't be serialized because it contains dynamic -- types. However, we do very limited things with the exceptions that -- are thrown by interpreted computations: @@ -544,6 +549,7 @@ getMessage = do 37 -> Msg <$> return RtsRevertCAFs 38 -> Msg <$> (ResumeSeq <$> get) 39 -> Msg <$> (NewBreakModule <$> get) + 40 -> Msg <$> (LookupSymbolInDLL <$> get <*> get) _ -> error $ "Unknown Message code " ++ (show b) putMessage :: Message a -> Put @@ -588,7 +594,8 @@ putMessage m = case m of Seq a -> putWord8 36 >> put a RtsRevertCAFs -> putWord8 37 ResumeSeq a -> putWord8 38 >> put a - NewBreakModule name -> putWord8 39 >> put name + NewBreakModule name -> putWord8 39 >> put name + LookupSymbolInDLL dll str -> putWord8 40 >> put dll >> put str {- Note [Parallelize CreateBCOs serialization] ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -18,6 +18,7 @@ module GHCi.ObjLink , unloadObj , purgeObj , lookupSymbol + , lookupSymbolInDLL , lookupClosure , resolveObjs , addLibrarySearchPath @@ -27,18 +28,17 @@ module GHCi.ObjLink import Prelude -- See note [Why do we import Prelude here?] import GHCi.RemoteTypes +import GHCi.Message (LoadedDLL) import Control.Exception (throwIO, ErrorCall(..)) import Control.Monad ( when ) import Foreign.C -import Foreign.Marshal.Alloc ( free ) -import Foreign ( nullPtr ) +import Foreign.Marshal.Alloc ( alloca, free ) +import Foreign ( nullPtr, peek ) import GHC.Exts import System.Posix.Internals ( CFilePath, withFilePath, peekFilePath ) import System.FilePath ( dropExtension, normalise ) - - -- --------------------------------------------------------------------------- -- RTS Linker Interface -- --------------------------------------------------------------------------- @@ -70,6 +70,15 @@ lookupSymbol str_in = do then return Nothing else return (Just addr) +lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) +lookupSymbolInDLL dll str_in = do + let str = prefixUnderscore str_in + withCAString str $ \c_str -> do + addr <- c_lookupSymbolInNativeObj dll c_str + if addr == nullPtr + then return Nothing + else return (Just addr) + lookupClosure :: String -> IO (Maybe HValueRef) lookupClosure str = do m <- lookupSymbol str @@ -89,7 +98,7 @@ prefixUnderscore -- (e.g. "libfoo.so" or "foo.dll"). In the latter case, loadDLL -- searches the standard locations for the appropriate library. -- -loadDLL :: String -> IO (Maybe String) +loadDLL :: String -> IO (Either String (Ptr LoadedDLL)) -- Nothing => success -- Just err_msg => failure loadDLL str0 = do @@ -101,12 +110,16 @@ loadDLL str0 = do str | isWindowsHost = dropExtension str0 | otherwise = str0 -- - maybe_errmsg <- withFilePath (normalise str) $ \dll -> c_addDLL dll - if maybe_errmsg == nullPtr - then return Nothing - else do str <- peekCString maybe_errmsg - free maybe_errmsg - return (Just str) + (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> + alloca $ \errmsg_ptr -> (,) + <$> c_loadNativeObj dll errmsg_ptr + <*> peek errmsg_ptr + + if maybe_handle == nullPtr + then do str <- peekCString maybe_errmsg + free maybe_errmsg + return (Left str) + else return (Right maybe_handle) loadArchive :: String -> IO () loadArchive str = do @@ -163,7 +176,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> IO CString +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== libraries/ghci/GHCi/Run.hs ===================================== @@ -66,7 +66,7 @@ run m = case m of LookupClosure str -> lookupJSClosure str #else InitLinker -> initObjLinker RetainCAFs - LoadDLL str -> loadDLL str + LoadDLL str -> fmap toRemotePtr <$> loadDLL str LoadArchive str -> loadArchive str LoadObj str -> loadObj str UnloadObj str -> unloadObj str @@ -81,6 +81,8 @@ run m = case m of #endif RtsRevertCAFs -> rts_revertCAFs LookupSymbol str -> fmap toRemotePtr <$> lookupSymbol str + LookupSymbolInDLL dll str -> + fmap toRemotePtr <$> lookupSymbolInDLL (fromRemotePtr dll) str FreeHValueRefs rs -> mapM_ freeRemoteRef rs AddSptEntry fpr r -> localRef r >>= sptAddEntry fpr EvalStmt opts r -> evalStmt opts r ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInNativeObj) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,90 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static const char * -internal_dlopen(const char *dll_name) -{ - OpenedSO* o_so; - void *hdl; - const char *errmsg; - char *errmsg_copy; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - errmsg = NULL; - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - errmsg = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return errmsg; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -660,11 +571,10 @@ internal_dlopen(const char *dll_name) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -672,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -727,81 +636,35 @@ internal_dlsym(const char *symbol) { } # endif -const char * -addDLL( pathchar *dll_name ) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; + ACQUIRE_LOCK(&linker_mutex); - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - errmsg = internal_dlopen(dll_name); +#if defined(OBJFORMAT_MACHO) + CHECK(symbol_name[0] == '_'); + symbol_name = symbol_name+1; +#endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + void *result = dlsym(handle, symbol_name); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif - if (errmsg == NULL) { - return NULL; - } + RELEASE_LOCK(&linker_mutex); + return result; +} - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - return errmsg; // return original error if open fails - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - errmsg = internal_dlopen(line+match[2].rm_so); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); +const char *addDLL(pathchar* dll_name) +{ + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return errmsg; - -# elif defined(OBJFORMAT_PEi386) - return addDLL_PEi386(dll_name, NULL); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1228,10 +1091,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1896,12 +1759,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -1988,25 +1859,33 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); - RELEASE_LOCK(&linker_mutex); - return r; -} + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); #else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); barf("loadNativeObj: not implemented on this platform"); -} #endif -HsInt unloadNativeObj (void *handle) +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + + RELEASE_LOCK(&linker_mutex); + return r; +} + +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2039,11 +1918,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -509,6 +509,7 @@ extern char **environ; SymI_HasDataProto(stg_block_putmvar) \ MAIN_CAP_SYM \ SymI_HasProto(addDLL) \ + SymI_HasProto(loadNativeObj) \ SymI_HasProto(addLibrarySearchPath) \ SymI_HasProto(removeLibrarySearchPath) \ SymI_HasProto(findSystemLibrary) \ @@ -619,6 +620,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,8 +90,10 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); + /* load a dynamic library */ -const char *addDLL( pathchar* dll_name ); +const char *addDLL(pathchar* dll_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,214 @@ +#include "LinkerInternals.h" +#include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + +#endif /* elf + macho */ ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if ((res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent))) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %ls\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where ===================================== testsuite/tests/rts/linker/T2615.hs ===================================== @@ -6,5 +6,5 @@ main = do initObjLinker RetainCAFs result <- loadDLL library_name case result of - Nothing -> putStrLn (library_name ++ " loaded successfully") - Just x -> putStrLn ("error: " ++ x) + Right _ -> putStrLn (library_name ++ " loaded successfully") + Left x -> putStrLn ("error: " ++ x) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7fae3a08236c0243cdb691ebfdfe53b95606148...39e5cb6c7092073f18a6442fac858d1a0fc70fdf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7fae3a08236c0243cdb691ebfdfe53b95606148...39e5cb6c7092073f18a6442fac858d1a0fc70fdf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 16:23:33 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 03 Apr 2024 12:23:33 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660d8285d69f5_231e18b07458632c6@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: b39d3b68 by Teo Camarasu at 2024-04-03T17:23:17+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. We introduce two new packages: template-haskell-in-tree and ghc-boot-th-in-tree. These package are carbon copies of template-haskell and ghc-boot-th respectively. They only differ in their name. When compiling the stage1 compiler we use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As these two packages are identical, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 13 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - + libraries/template-haskell-in-tree/template-haskell-in-tree.cabal - libraries/template-haskell/Language/Haskell/TH/Syntax.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,11 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +120,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +129,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellInTree , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,11 +54,11 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, + osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThInTree = lib "ghc-boot-th-in-tree" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellInTree = lib "template-haskell-in-tree" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -27,6 +27,7 @@ import Utilities import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp)) import GHC.Toolchain.Program import GHC.Platform.ArchOS +import qualified System.Directory as IO -- | Track this file to rebuild generated files whenever it changes. trackGenerateHs :: Expr () @@ -119,6 +120,7 @@ generatePackageCode context@(Context stage pkg _ _) = do let dir = buildDir context generated f = (root -/- dir -/- "**/*.hs") ?== f && not ("//autogen/*" ?== f) go gen file = generate file context gen + generated ?> \file -> do let unpack = fromMaybe . error $ "No generator for " ++ file ++ "." (src, builder) <- unpack <$> findGenerator context file @@ -143,6 +145,22 @@ generatePackageCode context@(Context stage pkg _ _) = do when (pkg == ghcBoot) $ do root -/- "**" -/- dir -/- "GHC/Version.hs" %> go generateVersionHs root -/- "**" -/- dir -/- "GHC/Platform/Host.hs" %> go generatePlatformHostHs + when (pkg == ghcBootThInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + createFileLink (cwd -/- "libraries/ghc-boot-th" -/- makeRelative prefix file) file + when (pkg == templateHaskellInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + let rel = makeRelative prefix file + let rootCandidate = cwd -/- "libraries/template-haskell" -/- rel + let vendoredCandidate = cwd -/- "libraries/template-haskell" -/- "vendored-filepath" -/- rel + exists <- liftIO $ IO.doesFileExist rootCandidate + if exists + then createFileLink rootCandidate file + else createFileLink vendoredCandidate file when (pkg == compiler) $ do root -/- primopsTxt stage %> \file -> do @@ -325,6 +343,7 @@ templateRules = do templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal" $ projectVersion templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion @@ -348,7 +367,6 @@ templateRules = do , interpolateVar "LlvmMaxVersion" $ replaceEq '.' ',' <$> setting LlvmMaxVersion ] - -- Generators -- | GHC wrapper scripts used for passing the path to the right package database ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,8 +172,8 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text + , templateHaskellInTree , transformers , semaphoreCompat , unlit -- # executable ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellInTree , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- we don't keep ghc-boot-in-tree and template-haskell-in-tree + -- as they are only needed for bootstrapping Template Haskell + | p == ghcBootThInTree = False + | p == templateHaskellInTree = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -78,6 +78,7 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ andM [expr ghcWithInterpreter, notStage0] `cabalFlag` "internal-interpreter" + , stage0 `cabalFlag` "bootstrap-th" , notM cross `cabalFlag` "terminfo" , arg "-build-tool-depends" , flag UseLibzstd `cabalFlag` "with-libzstd" @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat [ + ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th-in-tree.cabal is automatically generated from +-- ghc-boot-th.cabal-in-tree.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal-in-tree.in, not ghc-boot-th-in-tree.cabal. + +name: ghc-boot-th-in-tree +version: 9.11 +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th-in-tree + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th-in-tree.cabal is automatically generated from +-- ghc-boot-th.cabal-in-tree.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal-in-tree.in, not ghc-boot-th-in-tree.cabal. + +name: ghc-boot-th-in-tree +version: @ProjectVersionMunged@ +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th-in-tree + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -81,7 +86,12 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + build-depends: + ghc-boot-th-in-tree == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,11 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +89,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell-in-tree/template-haskell-in-tree.cabal ===================================== @@ -0,0 +1,72 @@ +-- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- ../../configure. Make sure you are editing template-haskell.cabal.in, not +-- template-haskell.cabal. + +name: template-haskell-in-tree +version: 2.22.0.0 +-- NOTE: Don't forget to update ./changelog.md +license: BSD3 +license-file: LICENSE +category: Template Haskell +maintainer: libraries at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Support library for Template Haskell +build-type: Simple +Cabal-Version: >= 1.10 +description: + This package provides modules containing facilities for manipulating + Haskell source code using Template Haskell. + . + See for more + information. + +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/template-haskell-in-tree + +Library + default-language: Haskell2010 + other-extensions: + BangPatterns + CPP + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + FlexibleInstances + RankNTypes + RoleAnnotations + ScopedTypeVariables + + exposed-modules: + Language.Haskell.TH + Language.Haskell.TH.Lib + Language.Haskell.TH.Ppr + Language.Haskell.TH.PprLib + Language.Haskell.TH.Quote + Language.Haskell.TH.Syntax + Language.Haskell.TH.LanguageExtensions + Language.Haskell.TH.CodeDo + Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + + build-depends: + base >= 4.11 && < 4.21, + ghc-boot-th-in-tree == 9.11, + ghc-prim, + pretty == 1.1.* + + other-modules: + System.FilePath + System.FilePath.Posix + System.FilePath.Windows + hs-source-dirs: ./vendored-filepath . + default-extensions: + ImplicitPrelude + + ghc-options: -Wall + cpp-options: -DBOOTSTRAP_TH ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,13 +34,11 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) import Control.Applicative (Applicative(..)) @@ -48,35 +46,42 @@ import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1023,7 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1390,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b39d3b6856075fc776cf1eca5780b791c1d09be7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b39d3b6856075fc776cf1eca5780b791c1d09be7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 16:30:21 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 03 Apr 2024 12:30:21 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660d841da5fdb_231e18c63270645c1@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 3ff2cd57 by Teo Camarasu at 2024-04-03T17:29:51+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. We introduce two new packages: template-haskell-in-tree and ghc-boot-th-in-tree. These package are carbon copies of template-haskell and ghc-boot-th respectively. They only differ in their name. When compiling the stage1 compiler we use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As these two packages are identical, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 13 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal - + libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - + libraries/template-haskell-in-tree/template-haskell-in-tree.cabal - libraries/template-haskell/Language/Haskell/TH/Syntax.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,11 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +120,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +129,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellInTree , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,11 +54,11 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThInTree, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, + osString, parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellInTree, terminfo, text, time, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThInTree = lib "ghc-boot-th-in-tree" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellInTree = lib "template-haskell-in-tree" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -27,6 +27,7 @@ import Utilities import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp)) import GHC.Toolchain.Program import GHC.Platform.ArchOS +import qualified System.Directory as IO -- | Track this file to rebuild generated files whenever it changes. trackGenerateHs :: Expr () @@ -119,6 +120,7 @@ generatePackageCode context@(Context stage pkg _ _) = do let dir = buildDir context generated f = (root -/- dir -/- "**/*.hs") ?== f && not ("//autogen/*" ?== f) go gen file = generate file context gen + generated ?> \file -> do let unpack = fromMaybe . error $ "No generator for " ++ file ++ "." (src, builder) <- unpack <$> findGenerator context file @@ -143,6 +145,22 @@ generatePackageCode context@(Context stage pkg _ _) = do when (pkg == ghcBoot) $ do root -/- "**" -/- dir -/- "GHC/Version.hs" %> go generateVersionHs root -/- "**" -/- dir -/- "GHC/Platform/Host.hs" %> go generatePlatformHostHs + when (pkg == ghcBootThInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + createFileLink (cwd -/- "libraries/ghc-boot-th" -/- makeRelative prefix file) file + when (pkg == templateHaskellInTree) $ do + let prefix = root -/- dir + prefix -/- "**/*.hs" %> \file -> do + cwd <- liftIO $ IO.getCurrentDirectory + let rel = makeRelative prefix file + let rootCandidate = cwd -/- "libraries/template-haskell" -/- rel + let vendoredCandidate = cwd -/- "libraries/template-haskell" -/- "vendored-filepath" -/- rel + exists <- liftIO $ IO.doesFileExist rootCandidate + if exists + then createFileLink rootCandidate file + else createFileLink vendoredCandidate file when (pkg == compiler) $ do root -/- primopsTxt stage %> \file -> do @@ -325,6 +343,7 @@ templateRules = do templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal" $ projectVersion templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion @@ -348,7 +367,6 @@ templateRules = do , interpolateVar "LlvmMaxVersion" $ replaceEq '.' ',' <$> setting LlvmMaxVersion ] - -- Generators -- | GHC wrapper scripts used for passing the path to the right package database ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,8 +172,8 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text + , templateHaskellInTree , transformers , semaphoreCompat , unlit -- # executable ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThInTree , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellInTree , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- we don't keep ghc-boot-in-tree and template-haskell-in-tree + -- as they are only needed for bootstrapping Template Haskell + | p == ghcBootThInTree = False + | p == templateHaskellInTree = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -78,6 +78,7 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ andM [expr ghcWithInterpreter, notStage0] `cabalFlag` "internal-interpreter" + , stage0 `cabalFlag` "bootstrap-th" , notM cross `cabalFlag` "terminfo" , arg "-build-tool-depends" , flag UseLibzstd `cabalFlag` "with-libzstd" @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat [ + ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th-in-tree.cabal is automatically generated from +-- ghc-boot-th.cabal-in-tree.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal-in-tree.in, not ghc-boot-th-in-tree.cabal. + +name: ghc-boot-th-in-tree +version: 9.11 +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th-in-tree + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot-th-in-tree/ghc-boot-th-in-tree.cabal.in ===================================== @@ -0,0 +1,39 @@ +-- WARNING: ghc-boot-th-in-tree.cabal is automatically generated from +-- ghc-boot-th.cabal-in-tree.in by ../../configure. Make sure you are editing +-- ghc-boot-th.cabal-in-tree.in, not ghc-boot-th-in-tree.cabal. + +name: ghc-boot-th-in-tree +version: @ProjectVersionMunged@ +license: BSD3 +license-file: LICENSE +category: GHC +maintainer: ghc-devs at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Shared functionality between GHC and the @template-haskell@ + library +description: This library contains various bits shared between the @ghc@ and + @template-haskell@ libraries. + . + This package exists to ensure that @template-haskell@ has a + minimal set of transitive dependencies, since it is intended to + be depended upon by user code. +cabal-version: >=1.10 +build-type: Simple +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/ghc-boot-th-in-tree + +Library + default-language: Haskell2010 + other-extensions: DeriveGeneric + default-extensions: NoImplicitPrelude + + exposed-modules: + GHC.LanguageExtensions.Type + GHC.ForeignSrcLang.Type + GHC.Lexeme + + build-depends: base >= 4.7 && < 4.21 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -81,7 +86,12 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + build-depends: + ghc-boot-th-in-tree == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,11 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +89,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + Build-Depends: + template-haskell-in-tree == 2.22.* + else + Build-Depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell-in-tree/template-haskell-in-tree.cabal ===================================== @@ -0,0 +1,72 @@ +-- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- ../../configure. Make sure you are editing template-haskell.cabal.in, not +-- template-haskell.cabal. + +name: template-haskell-in-tree +version: 2.22.0.0 +-- NOTE: Don't forget to update ./changelog.md +license: BSD3 +license-file: LICENSE +category: Template Haskell +maintainer: libraries at haskell.org +bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +synopsis: Support library for Template Haskell +build-type: Simple +Cabal-Version: >= 1.10 +description: + This package provides modules containing facilities for manipulating + Haskell source code using Template Haskell. + . + See for more + information. + +extra-source-files: changelog.md + +source-repository head + type: git + location: https://gitlab.haskell.org/ghc/ghc.git + subdir: libraries/template-haskell-in-tree + +Library + default-language: Haskell2010 + other-extensions: + BangPatterns + CPP + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + FlexibleInstances + RankNTypes + RoleAnnotations + ScopedTypeVariables + + exposed-modules: + Language.Haskell.TH + Language.Haskell.TH.Lib + Language.Haskell.TH.Ppr + Language.Haskell.TH.PprLib + Language.Haskell.TH.Quote + Language.Haskell.TH.Syntax + Language.Haskell.TH.LanguageExtensions + Language.Haskell.TH.CodeDo + Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + + build-depends: + base >= 4.11 && < 4.21, + ghc-boot-th-in-tree == 9.11, + ghc-prim, + pretty == 1.1.* + + other-modules: + System.FilePath + System.FilePath.Posix + System.FilePath.Windows + hs-source-dirs: ./vendored-filepath . + default-extensions: + ImplicitPrelude + + ghc-options: -Wall + cpp-options: -DBOOTSTRAP_TH ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,13 +34,11 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) import Control.Applicative (Applicative(..)) @@ -48,35 +46,42 @@ import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1023,7 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1390,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ff2cd57e34e21ff3ea70f3f797b97972578f898 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ff2cd57e34e21ff3ea70f3f797b97972578f898 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 16:43:34 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 03 Apr 2024 12:43:34 -0400 Subject: [Git][ghc/ghc][wip/T23109] 44 commits: th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Message-ID: <660d873667f2_231e18e3bc5065477@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - ded706c6 by Simon Peyton Jones at 2024-04-03T12:16:56+01:00 Make newtype instances opaque I think this will help with #23109 Wibbles Allow SelCo for newtype classes Experimental change Wibble Furher wibbles Further improvments Further wibbles esp exprIsConLike Run classop rule first Newtype classops are small needs comments - - - - - 15 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37dafd12daa5f6f17b656c5b5494bce4fe7fe80d...ded706c61bca3c762b6fdc4ab1ea8b6790066383 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37dafd12daa5f6f17b656c5b5494bce4fe7fe80d...ded706c61bca3c762b6fdc4ab1ea8b6790066383 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 16:43:58 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 03 Apr 2024 12:43:58 -0400 Subject: [Git][ghc/ghc][wip/spj-unf-size] 47 commits: th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Message-ID: <660d874e8b23d_231e18f05b54663e3@gitlab.mail> Simon Peyton Jones pushed to branch wip/spj-unf-size at Glasgow Haskell Compiler / GHC Commits: 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - d3453235 by Simon Peyton Jones at 2024-04-03T12:19:16+01:00 Work in progress on unfoldings re-engineering - - - - - 33629f76 by Simon Peyton Jones at 2024-04-03T12:21:03+01:00 Fix a bad, subtle bug in exprIsConApp_maybe In extend_in_scope We were simply overwriting useful bindings in the in-scope set, notably ones that had unfoldings. That could lead to repeated simplifier iterations. - - - - - fb548752 by Simon Peyton Jones at 2024-04-03T12:21:03+01:00 Minor refactoring... Plus: don't be so eager to inline when argument is a non-value, but has some struture. We want *some* incentive though. - - - - - 1a2c37f0 by Simon Peyton Jones at 2024-04-03T12:23:33+01:00 Adjust * Reduce caseElimDiscount to 10 Example: f_nand in spectral/hartel/event is quite big but was still getting inlined; that make f_simulate too big for SpecConstr * Increase jumpSize. Not so much cheaper than tail calls. I'm trying making them the same size. - - - - - 15 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17174a9f2574c5186a7f82a68496f40b25de8e03...1a2c37f050c7bd8258fc37c1d4b8997f8cb81708 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17174a9f2574c5186a7f82a68496f40b25de8e03...1a2c37f050c7bd8258fc37c1d4b8997f8cb81708 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 16:44:27 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 03 Apr 2024 12:44:27 -0400 Subject: [Git][ghc/ghc][wip/T24462] 50 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660d876b8861c_231e18f331446711a@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24462 at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 084d00c6 by Simon Peyton Jones at 2024-04-03T10:24:59+01:00 Don't inline any old coercion Just an experiment for #24462 - - - - - 15 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81e4315aec692d4c8bf2c2133ab4f7ee463b7ec9...084d00c6100356e20e0e51f490775cfe4cdae62f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81e4315aec692d4c8bf2c2133ab4f7ee463b7ec9...084d00c6100356e20e0e51f490775cfe4cdae62f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 17:53:23 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 03 Apr 2024 13:53:23 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 2 commits: rts: Make addDLL a wrapper around loadNativeObj Message-ID: <660d9793cdf7b_231e18173c4e4770ba@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 37b17f4e by Rodrigo Mesquita at 2024-04-03T18:53:01+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 83e7e694 by Rodrigo Mesquita at 2024-04-03T18:53:01+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 18 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/ObjLink.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -394,6 +394,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.FM import GHC.Unit import GHC.Unit.Env @@ -673,6 +674,7 @@ setTopSessionDynFlags :: GhcMonad m => DynFlags -> m () setTopSessionDynFlags dflags = do hsc_env <- getSession logger <- getLogger + lookup_cache <- liftIO $ newMVar emptyUFM -- Interpreter interp <- if @@ -702,7 +704,7 @@ setTopSessionDynFlags dflags = do } s <- liftIO $ newMVar InterpPending loader <- liftIO Loader.uninitializedLoader - return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader)) + return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) -- JavaScript interpreter | ArchJavaScript <- platformArch (targetPlatform dflags) @@ -720,7 +722,7 @@ setTopSessionDynFlags dflags = do , jsInterpFinderOpts = initFinderOpts dflags , jsInterpFinderCache = hsc_FC hsc_env } - return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader)) + return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache)) -- Internal interpreter | otherwise @@ -728,7 +730,7 @@ setTopSessionDynFlags dflags = do #if defined(HAVE_INTERNAL_INTERPRETER) do loader <- liftIO Loader.uninitializedLoader - return (Just (Interp InternalInterp loader)) + return (Just (Interp InternalInterp loader lookup_cache)) #else return Nothing #endif ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -2665,7 +2665,7 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do case interp of -- always generate JS code for the JS interpreter (no bytecode!) - Interp (ExternalInterp (ExtJS i)) _ -> + Interp (ExternalInterp (ExtJS i)) _ _ -> jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id _ -> do ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -152,22 +152,22 @@ The main pieces are: - implementation of Template Haskell (GHCi.TH) - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external - server. This is a fairly simple wrapper, most of the functionality +- top-level iserv directory, containing the code for the external + server. This is a fairly simple wrapper, most of the functionality is provided by modules in libraries/ghci. - This module which provides the interface to the server used by the rest of GHC. -GHC works with and without -fexternal-interpreter. With the flag, all -interpreted code is run by the iserv binary. Without the flag, +GHC works with and without -fexternal-interpreter. With the flag, all +interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC. Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dynCompileExpr cannot work, because we have no way to run code of an -unknown type in the remote process. This API fails with an error +unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter. Other Notes on Remote GHCi @@ -441,52 +441,71 @@ initObjLinker :: Interp -> IO () initObjLinker interp = interpCmd interp InitLinker lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ())) -lookupSymbol interp str = case interpInstance interp of +lookupSymbol interp str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif - - ExternalInterp ext -> case ext of - ExtIServ i -> withIServ i $ \inst -> do - -- Profiling of GHCi showed a lot of time and allocation spent - -- making cross-process LookupSymbol calls, so I added a GHC-side - -- cache which sped things up quite a lot. We have to be careful - -- to purge this cache when unloading code though. - cache <- readMVar (instLookupSymbolCache inst) - case lookupUFM cache str of - Just p -> return (Just p) - Nothing -> do - m <- uninterruptibleMask_ $ - sendMessage inst (LookupSymbol (unpackFS str)) - case m of - Nothing -> return Nothing - Just r -> do - let p = fromRemotePtr r - cache' = addToUFM cache str p - modifyMVar_ (instLookupSymbolCache inst) (const (pure cache')) - return (Just p) - - ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbol (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ())) -lookupSymbolInDLL interp dll str = case interpInstance interp of +lookupSymbolInDLL interp dll str = withSymbolCache interp str $ + case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) + InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str)) #endif - ExternalInterp _ -> panic "lookupSymbolInDLL: not implemented for external interpreter" -- FIXME + ExternalInterp ext -> case ext of + ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do + uninterruptibleMask_ $ + sendMessage inst (LookupSymbolInDLL dll (unpackFS str)) + ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str = interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache' +-- which maps symbols to the address where they are loaded. +-- When there's a cache hit we simply return the cached address, when there is +-- a miss we run the action which determines the symbol's address and populate +-- the cache with the answer. +withSymbolCache :: Interp + -> FastString + -- ^ The symbol we are looking up in the cache + -> IO (Maybe (Ptr ())) + -- ^ An action which determines the address of the symbol we + -- are looking up in the cache, which is run if there is a + -- cache miss. The result will be cached. + -> IO (Maybe (Ptr ())) +withSymbolCache interp str determine_addr = do + + -- Profiling of GHCi showed a lot of time and allocation spent + -- making cross-process LookupSymbol calls, so I added a GHC-side + -- cache which sped things up quite a lot. We have to be careful + -- to purge this cache when unloading code though. + -- + -- The analysis in #23415 further showed this cache should also benefit the + -- internal interpreter's loading times, and needn't be used by the external + -- interpreter only. + cache <- readMVar (interpLookupSymbolCache interp) + case lookupUFM cache str of + Just p -> return (Just p) + Nothing -> do + + maddr <- determine_addr + case maddr of + Nothing -> return Nothing + Just p -> do + let upd_cache cache' = addToUFM cache' str p + modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache) + return (Just p) + purgeLookupSymbolCache :: Interp -> IO () -purgeLookupSymbolCache interp = case interpInstance interp of -#if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> pure () -#endif - ExternalInterp ext -> withExtInterpMaybe ext $ \case - Nothing -> pure () -- interpreter stopped, nothing to do - Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM)) +purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM)) -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows). It takes either @@ -552,11 +571,9 @@ spawnIServ conf = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = process , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = () } pure inst ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -41,7 +41,6 @@ import GHC.Utils.Panic import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString -import GHC.Types.Unique.FM import Control.Concurrent import Control.Monad @@ -178,11 +177,9 @@ spawnJSInterp cfg = do } pending_frees <- newMVar [] - lookup_cache <- newMVar emptyUFM let inst = ExtInterpInstance { instProcess = proc , instPendingFrees = pending_frees - , instLookupSymbolCache = lookup_cache , instExtra = extra } ===================================== compiler/GHC/Runtime/Interpreter/Types.hs ===================================== @@ -51,6 +51,9 @@ data Interp = Interp , interpLoader :: !Loader -- ^ Interpreter loader + + , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) + -- ^ LookupSymbol cache } data InterpInstance @@ -108,9 +111,6 @@ data ExtInterpInstance c = ExtInterpInstance -- Finalizers for ForeignRefs can append values to this list -- asynchronously. - , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ()))) - -- ^ LookupSymbol cache - , instExtra :: !c -- ^ Instance specific extra fields } ===================================== libraries/ghci/GHCi/ObjLink.hs ===================================== @@ -74,7 +74,7 @@ lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a)) lookupSymbolInDLL dll str_in = do let str = prefixUnderscore str_in withCAString str $ \c_str -> do - addr <- c_lookupSymbolInDLL dll c_str + addr <- c_lookupSymbolInNativeObj dll c_str if addr == nullPtr then return Nothing else return (Just addr) @@ -99,8 +99,6 @@ prefixUnderscore -- searches the standard locations for the appropriate library. -- loadDLL :: String -> IO (Either String (Ptr LoadedDLL)) --- Nothing => success --- Just err_msg => failure loadDLL str0 = do let -- On Windows, addDLL takes a filename without an extension, because @@ -112,7 +110,7 @@ loadDLL str0 = do -- (maybe_handle, maybe_errmsg) <- withFilePath (normalise str) $ \dll -> alloca $ \errmsg_ptr -> (,) - <$> c_addDLL dll errmsg_ptr + <$> c_loadNativeObj dll errmsg_ptr <*> peek errmsg_ptr if maybe_handle == nullPtr @@ -176,8 +174,8 @@ resolveObjs = do -- Foreign declarations to RTS entry points which does the real work; -- --------------------------------------------------------------------------- -foreign import ccall unsafe "addDLL" c_addDLL :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) -foreign import ccall unsafe "lookupSymbolInDLL" c_lookupSymbolInDLL :: Ptr LoadedDLL -> CString -> IO (Ptr a) +foreign import ccall unsafe "loadNativeObj" c_loadNativeObj :: CFilePath -> Ptr CString -> IO (Ptr LoadedDLL) +foreign import ccall unsafe "lookupSymbolInNativeObj" c_lookupSymbolInNativeObj :: Ptr LoadedDLL -> CString -> IO (Ptr a) foreign import ccall unsafe "initLinker_" c_initLinker_ :: CInt -> IO () foreign import ccall unsafe "lookupSymbol" c_lookupSymbol :: CString -> IO (Ptr a) foreign import ccall unsafe "loadArchive" c_loadArchive :: CFilePath -> IO Int ===================================== rts/Linker.c ===================================== @@ -77,6 +77,10 @@ # include #endif +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) +# include "linker/LoadNativeObjPosix.h" +#endif + #if defined(dragonfly_HOST_OS) #include #endif @@ -130,7 +134,7 @@ extern void iconv(); - Indexing (e.g. ocVerifyImage and ocGetNames) - Initialization (e.g. ocResolve) - RunInit (e.g. ocRunInit) - - Lookup (e.g. lookupSymbol) + - Lookup (e.g. lookupSymbol/lookupSymbolInNativeObj) This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will @@ -417,11 +421,8 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; -static regex_t re_invalid; -static regex_t re_realso; -#if defined(THREADED_RTS) -Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section -#endif +regex_t re_invalid; +regex_t re_realso; #endif void initLinker (void) @@ -455,9 +456,6 @@ initLinker_ (int retain_cafs) #if defined(THREADED_RTS) initMutex(&linker_mutex); -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - initMutex(&dl_mutex); -#endif #endif symhash = allocStrHashTable(); @@ -520,9 +518,6 @@ exitLinker( void ) { if (linker_init_done == 1) { regfree(&re_invalid); regfree(&re_realso); -#if defined(THREADED_RTS) - closeMutex(&dl_mutex); -#endif } #endif if (linker_init_done == 1) { @@ -556,87 +551,6 @@ exitLinker( void ) { # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -/* Suppose in ghci we load a temporary SO for a module containing - f = 1 - and then modify the module, recompile, and load another temporary - SO with - f = 2 - Then as we don't unload the first SO, dlsym will find the - f = 1 - symbol whereas we want the - f = 2 - symbol. We therefore need to keep our own SO handle list, and - try SOs in the right order. */ - -typedef - struct _OpenedSO { - struct _OpenedSO* next; - void *handle; - } - OpenedSO; - -/* A list thereof. */ -static OpenedSO* openedSOs = NULL; - -static void * -internal_dlopen(const char *dll_name, const char **errmsg_ptr) -{ - OpenedSO* o_so; - void *hdl; - - // omitted: RTLD_NOW - // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - IF_DEBUG(linker, - debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); - - //-------------- Begin critical section ------------------ - // This critical section is necessary because dlerror() is not - // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) - // Also, the error message returned must be copied to preserve it - // (see POSIX also) - - ACQUIRE_LOCK(&dl_mutex); - - // When dlopen() loads a profiled dynamic library, it calls the - // ctors which will call registerCcsList() to append the defined - // CostCentreStacks to CCS_LIST. This execution path starting from - // addDLL() was only protected by dl_mutex previously. However, - // another thread may be doing other things with the RTS linker - // that transitively calls refreshProfilingCCSs() which also - // accesses CCS_LIST, and those execution paths are protected by - // linker_mutex. So there's a risk of data race that may lead to - // segfaults (#24423), and we need to ensure the ctors are also - // protected by ccs_mutex. -#if defined(PROFILING) - ACQUIRE_LOCK(&ccs_mutex); -#endif - - hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ - -#if defined(PROFILING) - RELEASE_LOCK(&ccs_mutex); -#endif - - if (hdl == NULL) { - /* dlopen failed; return a ptr to the error msg. */ - char *errmsg = dlerror(); - if (errmsg == NULL) errmsg = "addDLL: unknown error"; - char *errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); - strcpy(errmsg_copy, errmsg); - *errmsg_ptr = errmsg_copy; - } else { - o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); - o_so->handle = hdl; - o_so->next = openedSOs; - openedSOs = o_so; - } - - RELEASE_LOCK(&dl_mutex); - //--------------- End critical section ------------------- - - return hdl; -} - /* Note [RTLD_LOCAL] ~~~~~~~~~~~~~~~~~ @@ -657,11 +571,10 @@ internal_dlopen(const char *dll_name, const char **errmsg_ptr) static void * internal_dlsym(const char *symbol) { - OpenedSO* o_so; void *v; - // We acquire dl_mutex as concurrent dl* calls may alter dlerror - ACQUIRE_LOCK(&dl_mutex); + // concurrent dl* calls may alter dlerror + ASSERT_LOCK_HELD(&linker_mutex); // clears dlerror dlerror(); @@ -669,20 +582,19 @@ internal_dlsym(const char *symbol) { // look in program first v = dlsym(dl_prog_handle, symbol); if (dlerror() == NULL) { - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in program\n", symbol)); return v; } - for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) { - v = dlsym(o_so->handle, symbol); - if (dlerror() == NULL) { + for (ObjectCode *nc = loaded_objects; nc; nc = nc->next_loaded_object) { + if (nc->type == DYNAMIC_OBJECT) { + v = dlsym(nc->dlopen_handle, symbol); + if (dlerror() == NULL) { IF_DEBUG(linker, debugBelch("internal_dlsym: found symbol '%s' in shared object\n", symbol)); - RELEASE_LOCK(&dl_mutex); return v; + } } } - RELEASE_LOCK(&dl_mutex); IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol)); # define SPECIAL_SYMBOL(sym) \ @@ -722,98 +634,37 @@ internal_dlsym(const char *symbol) { // we failed to find the symbol return NULL; } +# endif -void *lookupSymbolInDLL(void *handle, const char *symbol_name) +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name) { + ACQUIRE_LOCK(&linker_mutex); + #if defined(OBJFORMAT_MACHO) CHECK(symbol_name[0] == '_'); symbol_name = symbol_name+1; #endif - - ACQUIRE_LOCK(&dl_mutex); // dlsym alters dlerror +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) void *result = dlsym(handle, symbol_name); - RELEASE_LOCK(&dl_mutex); +#elif defined(OBJFORMAT_PEi386) + void *result = lookupSymbolInDLL_PEi386(symbol_name, handle, NULL, NULL); +#else + barf("lookupSymbolInNativeObj: Unsupported platform"); +#endif + + RELEASE_LOCK(&linker_mutex); return result; } -# endif -void *addDLL(pathchar* dll_name, const char **errmsg_ptr) +const char *addDLL(pathchar* dll_name) { -# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - -#define NMATCH 5 - regmatch_t match[NMATCH]; - void *handle; - const char *errmsg; - FILE* fp; - size_t match_length; -#define MAXLINE 1000 - char line[MAXLINE]; - int result; - - IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); - handle = internal_dlopen(dll_name, &errmsg); - - if (handle != NULL) { - return handle; - } - - // GHC #2615 - // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) - // contain linker scripts rather than ELF-format object code. This - // code handles the situation by recognizing the real object code - // file name given in the linker script. - // - // If an "invalid ELF header" error occurs, it is assumed that the - // .so file contains a linker script instead of ELF object code. - // In this case, the code looks for the GROUP ( ... ) linker - // directive. If one is found, the first file name inside the - // parentheses is treated as the name of a dynamic library and the - // code attempts to dlopen that file. If this is also unsuccessful, - // an error message is returned. - - // see if the error message is due to an invalid ELF header - IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); - result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); - IF_DEBUG(linker, debugBelch("result = %i\n", result)); - if (result == 0) { - // success -- try to read the named file as a linker script - match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), - MAXLINE-1); - strncpy(line, (errmsg+(match[1].rm_so)),match_length); - line[match_length] = '\0'; // make sure string is null-terminated - IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); - if ((fp = __rts_fopen(line, "r")) == NULL) { - *errmsg_ptr = errmsg; // return original error if open fails - return NULL; - } - // try to find a GROUP or INPUT ( ... ) command - while (fgets(line, MAXLINE, fp) != NULL) { - IF_DEBUG(linker, debugBelch("input line = %s", line)); - if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { - // success -- try to dlopen the first named file - IF_DEBUG(linker, debugBelch("match%s\n","")); - line[match[2].rm_eo] = '\0'; - stgFree((void*)errmsg); // Free old message before creating new one - handle = internal_dlopen(line+match[2].rm_so, errmsg_ptr); - break; - } - // if control reaches here, no GROUP or INPUT ( ... ) directive - // was found and the original error message is returned to the - // caller - } - fclose(fp); + char *errmsg; + if (loadNativeObj(dll_name, &errmsg)) { + return NULL; + } else { + ASSERT(errmsg != NULL); + return errmsg; } - return handle; - -# elif defined(OBJFORMAT_PEi386) - // FIXME - return addDLL_PEi386(dll_name, NULL); - -# else - barf("addDLL: not implemented on this platform"); -# endif } /* ----------------------------------------------------------------------------- @@ -1240,10 +1091,10 @@ void freeObjectCode (ObjectCode *oc) } if (oc->type == DYNAMIC_OBJECT) { -#if defined(OBJFORMAT_ELF) - ACQUIRE_LOCK(&dl_mutex); - freeNativeCode_ELF(oc); - RELEASE_LOCK(&dl_mutex); +#if defined(OBJFORMAT_ELF) || defined(darwin_HOST_OS) + ACQUIRE_LOCK(&linker_mutex); + freeNativeCode_POSIX(oc); + RELEASE_LOCK(&linker_mutex); #else barf("freeObjectCode: This shouldn't happen"); #endif @@ -1908,12 +1759,20 @@ HsInt purgeObj (pathchar *path) return r; } +ObjectCode *lookupObjectByPath(pathchar *path) { + for (ObjectCode *o = objects; o; o = o->next) { + if (0 == pathcmp(o->fileName, path)) { + return o; + } + } + return NULL; +} + OStatus getObjectLoadStatus_ (pathchar *path) { - for (ObjectCode *o = objects; o; o = o->next) { - if (0 == pathcmp(o->fileName, path)) { - return o->status; - } + ObjectCode *oc = lookupObjectByPath(path); + if (oc) { + return oc->status; } return OBJECT_NOT_LOADED; } @@ -2000,25 +1859,33 @@ addSection (Section *s, SectionKind kind, SectionAlloc alloc, #define UNUSED(x) (void)(x) -#if defined(OBJFORMAT_ELF) void * loadNativeObj (pathchar *path, char **errmsg) { + IF_DEBUG(linker, debugBelch("loadNativeObj: path = '%" PATH_FMT "'\n", path)); ACQUIRE_LOCK(&linker_mutex); - void *r = loadNativeObj_ELF(path, errmsg); - RELEASE_LOCK(&linker_mutex); - return r; -} + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + void *r = loadNativeObj_POSIX(path, errmsg); +#elif defined(OBJFORMAT_PEi386) + void *r = NULL; + *errmsg = (char*)addDLL_PEi386(path, (HINSTANCE*)&r); #else -void * STG_NORETURN -loadNativeObj (pathchar *path, char **errmsg) -{ - UNUSED(path); - UNUSED(errmsg); barf("loadNativeObj: not implemented on this platform"); -} #endif -HsInt unloadNativeObj (void *handle) +#if defined(OBJFORMAT_ELF) + if (!r) { + // Check if native object may be a linker script and try loading a native + // object from it + r = loadNativeObjFromLinkerScript_ELF(errmsg); + } +#endif + + RELEASE_LOCK(&linker_mutex); + return r; +} + +static HsInt unloadNativeObj_(void *handle) { bool unloadedAnyObj = false; @@ -2051,11 +1918,18 @@ HsInt unloadNativeObj (void *handle) if (unloadedAnyObj) { return 1; } else { - errorBelch("unloadObjNativeObj_ELF: can't find `%p' to unload", handle); + errorBelch("unloadObjNativeObj_: can't find `%p' to unload", handle); return 0; } } +HsInt unloadNativeObj(void *handle) { + ACQUIRE_LOCK(&linker_mutex); + HsInt r = unloadNativeObj_(handle); + RELEASE_LOCK(&linker_mutex); + return r; +} + /* ----------------------------------------------------------------------------- * Segment management */ ===================================== rts/LinkerInternals.h ===================================== @@ -412,10 +412,6 @@ extern Elf_Word shndx_table_uninit_label; #if defined(THREADED_RTS) extern Mutex linker_mutex; - -#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) -extern Mutex dl_mutex; -#endif #endif /* THREADED_RTS */ /* Type of an initializer */ @@ -515,9 +511,9 @@ HsInt loadArchive_ (pathchar *path); #define USE_CONTIGUOUS_MMAP 0 #endif - HsInt isAlreadyLoaded( pathchar *path ); OStatus getObjectLoadStatus_ (pathchar *path); +ObjectCode *lookupObjectByPath(pathchar *path); HsInt loadOc( ObjectCode* oc ); ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, bool mapped, pathchar *archiveMemberName, ===================================== rts/RtsSymbols.c ===================================== @@ -509,6 +509,7 @@ extern char **environ; SymI_HasDataProto(stg_block_putmvar) \ MAIN_CAP_SYM \ SymI_HasProto(addDLL) \ + SymI_HasProto(loadNativeObj) \ SymI_HasProto(addLibrarySearchPath) \ SymI_HasProto(removeLibrarySearchPath) \ SymI_HasProto(findSystemLibrary) \ @@ -619,7 +620,7 @@ extern char **environ; SymI_HasProto(purgeObj) \ SymI_HasProto(insertSymbol) \ SymI_HasProto(lookupSymbol) \ - SymI_HasProto(lookupSymbolInDLL) \ + SymI_HasProto(lookupSymbolInNativeObj) \ SymI_HasDataProto(stg_makeStablePtrzh) \ SymI_HasDataProto(stg_mkApUpd0zh) \ SymI_HasDataProto(stg_labelThreadzh) \ ===================================== rts/include/rts/Linker.h ===================================== @@ -90,10 +90,10 @@ void *loadNativeObj( pathchar *path, char **errmsg ); Takes the handle returned from loadNativeObj() as an argument. */ HsInt unloadNativeObj( void *handle ); -/* load a dynamic library */ -void *addDLL(pathchar* dll_name, const char **errmsg); +void *lookupSymbolInNativeObj(void *handle, const char *symbol_name); -void *lookupSymbolInDLL(void *handle, const char *symbol_name); +/* load a dynamic library */ +const char *addDLL(pathchar* dll_name); /* add a path to the library search path */ HsPtr addLibrarySearchPath(pathchar* dll_path); ===================================== rts/linker/Elf.c ===================================== @@ -27,11 +27,15 @@ #include "sm/OSMem.h" #include "linker/util.h" #include "linker/elf_util.h" +#include "linker/LoadNativeObjPosix.h" +#include #include #include #include #include +#include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #if defined(HAVE_DLFCN_H) #include #endif @@ -2069,159 +2073,6 @@ int ocRunFini_ELF( ObjectCode *oc ) return true; } -/* - * Shared object loading - */ - -#if defined(HAVE_DLINFO) -struct piterate_cb_info { - ObjectCode *nc; - void *l_addr; /* base virtual address of the loaded code */ -}; - -static int loadNativeObjCb_(struct dl_phdr_info *info, - size_t _size STG_UNUSED, void *data) { - struct piterate_cb_info *s = (struct piterate_cb_info *) data; - - // This logic mimicks _dl_addr_inside_object from glibc - // For reference: - // int - // internal_function - // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - // { - // int n = l->l_phnum; - // const ElfW(Addr) reladdr = addr - l->l_addr; - // - // while (--n >= 0) - // if (l->l_phdr[n].p_type == PT_LOAD - // && reladdr - l->l_phdr[n].p_vaddr >= 0 - // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) - // return 1; - // return 0; - // } - - if ((void*) info->dlpi_addr == s->l_addr) { - int n = info->dlpi_phnum; - while (--n >= 0) { - if (info->dlpi_phdr[n].p_type == PT_LOAD) { - NativeCodeRange* ncr = - stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); - ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); - ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); - - ncr->next = s->nc->nc_ranges; - s->nc->nc_ranges = ncr; - } - } - } - return 0; -} -#endif /* defined(HAVE_DLINFO) */ - -static void copyErrmsg(char** errmsg_dest, char* errmsg) { - if (errmsg == NULL) errmsg = "loadNativeObj_ELF: unknown error"; - *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_ELF"); - strcpy(*errmsg_dest, errmsg); -} - -// need dl_mutex -void freeNativeCode_ELF (ObjectCode *nc) { - dlclose(nc->dlopen_handle); - - NativeCodeRange *ncr = nc->nc_ranges; - while (ncr) { - NativeCodeRange* last_ncr = ncr; - ncr = ncr->next; - stgFree(last_ncr); - } -} - -void * loadNativeObj_ELF (pathchar *path, char **errmsg) -{ - ObjectCode* nc; - void *hdl, *retval; - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF %" PATH_FMT "\n", path)); - - retval = NULL; - ACQUIRE_LOCK(&dl_mutex); - - /* Loading the same object multiple times will lead to chaos - * as we will have two ObjectCodes but one underlying dlopen - * handle. Fail if this happens. - */ - if (getObjectLoadStatus_(path) != OBJECT_NOT_LOADED) { - copyErrmsg(errmsg, "loadNativeObj_ELF: Already loaded"); - goto dlopen_fail; - } - - nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); - - foreignExportsLoadingObject(nc); - hdl = dlopen(path, RTLD_NOW|RTLD_LOCAL); - nc->dlopen_handle = hdl; - foreignExportsFinishedLoadingObject(); - if (hdl == NULL) { - /* dlopen failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlopen_fail; - } - -#if defined(HAVE_DLINFO) - struct link_map *map; - if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { - /* dlinfo failed; save the message in errmsg */ - copyErrmsg(errmsg, dlerror()); - goto dlinfo_fail; - } - - hdl = NULL; // pass handle ownership to nc - - struct piterate_cb_info piterate_info = { - .nc = nc, - .l_addr = (void *) map->l_addr - }; - dl_iterate_phdr(loadNativeObjCb_, &piterate_info); - if (!nc->nc_ranges) { - copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); - goto dl_iterate_phdr_fail; - } - nc->unloadable = true; -#else - nc->nc_ranges = NULL; - nc->unloadable = false; -#endif /* defined (HAVE_DLINFO) */ - - insertOCSectionIndices(nc); - - nc->next_loaded_object = loaded_objects; - loaded_objects = nc; - - retval = nc->dlopen_handle; - -#if defined(PROFILING) - // collect any new cost centres that were defined in the loaded object. - refreshProfilingCCSs(); -#endif - - goto success; - -dl_iterate_phdr_fail: - // already have dl_mutex - freeNativeCode_ELF(nc); -dlinfo_fail: - if (hdl) dlclose(hdl); -dlopen_fail: -success: - - RELEASE_LOCK(&dl_mutex); - - IF_DEBUG(linker, debugBelch("loadNativeObj_ELF result=%p\n", retval)); - - return retval; -} - - /* * PowerPC & X86_64 ELF specifics */ @@ -2271,4 +2122,71 @@ int ocAllocateExtras_ELF( ObjectCode *oc ) #endif /* NEED_SYMBOL_EXTRAS */ +extern regex_t re_invalid; +extern regex_t re_realso; + +void * loadNativeObjFromLinkerScript_ELF(char **errmsg) +{ + // GHC #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + +#define NMATCH 5 + regmatch_t match[NMATCH]; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + void* r = NULL; + + ASSERT_LOCK_HELD(&linker_mutex); + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", *errmsg)); + result = regexec(&re_invalid, *errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (*errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch("file name = '%s'\n", line)); + if ((fp = __rts_fopen(line, "r")) == NULL) { + // return original error if open fails + return NULL; + } + // try to find a GROUP or INPUT ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[2].rm_eo] = '\0'; + stgFree((void*)*errmsg); // Free old message before creating new one + r = loadNativeObj_POSIX(line+match[2].rm_so, errmsg); + break; + } + // if control reaches here, no GROUP or INPUT ( ... ) directive + // was found and the original error message is returned to the + // caller + } + fclose(fp); + } + + return r; +} + + #endif /* elf */ ===================================== rts/linker/Elf.h ===================================== @@ -14,7 +14,6 @@ int ocResolve_ELF ( ObjectCode* oc ); int ocRunInit_ELF ( ObjectCode* oc ); int ocRunFini_ELF ( ObjectCode* oc ); int ocAllocateExtras_ELF ( ObjectCode *oc ); -void freeNativeCode_ELF ( ObjectCode *nc ); -void *loadNativeObj_ELF ( pathchar *path, char **errmsg ); +void *loadNativeObjFromLinkerScript_ELF( char **errmsg ); #include "EndPrivate.h" ===================================== rts/linker/LoadNativeObjPosix.c ===================================== @@ -0,0 +1,214 @@ +#include "LinkerInternals.h" +#include "Rts.h" + +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + +#include "CheckUnload.h" +#include "ForeignExports.h" +#include "RtsUtils.h" +#include "Profiling.h" + +#include "linker/LoadNativeObjPosix.h" + +#if defined(HAVE_DLFCN_H) +#include +#endif + +#if defined(HAVE_DLINFO) +#include +#endif + +#include + +/* + * Shared object loading + */ + +#if defined(HAVE_DLINFO) +struct piterate_cb_info { + ObjectCode *nc; + void *l_addr; /* base virtual address of the loaded code */ +}; + +static int loadNativeObjCb_(struct dl_phdr_info *info, + size_t _size STG_UNUSED, void *data) { + struct piterate_cb_info *s = (struct piterate_cb_info *) data; + + // This logic mimicks _dl_addr_inside_object from glibc + // For reference: + // int + // internal_function + // _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + // { + // int n = l->l_phnum; + // const ElfW(Addr) reladdr = addr - l->l_addr; + // + // while (--n >= 0) + // if (l->l_phdr[n].p_type == PT_LOAD + // && reladdr - l->l_phdr[n].p_vaddr >= 0 + // && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) + // return 1; + // return 0; + // } + + if ((void*) info->dlpi_addr == s->l_addr) { + int n = info->dlpi_phnum; + while (--n >= 0) { + if (info->dlpi_phdr[n].p_type == PT_LOAD) { + NativeCodeRange* ncr = + stgMallocBytes(sizeof(NativeCodeRange), "loadNativeObjCb_"); + ncr->start = (void*) ((char*) s->l_addr + info->dlpi_phdr[n].p_vaddr); + ncr->end = (void*) ((char*) ncr->start + info->dlpi_phdr[n].p_memsz); + + ncr->next = s->nc->nc_ranges; + s->nc->nc_ranges = ncr; + } + } + } + return 0; +} +#endif /* defined(HAVE_DLINFO) */ + +static void copyErrmsg(char** errmsg_dest, char* errmsg) { + if (errmsg == NULL) errmsg = "loadNativeObj_POSIX: unknown error"; + *errmsg_dest = stgMallocBytes(strlen(errmsg)+1, "loadNativeObj_POSIX"); + strcpy(*errmsg_dest, errmsg); +} + +void freeNativeCode_POSIX (ObjectCode *nc) { + ASSERT_LOCK_HELD(&linker_mutex); + + dlclose(nc->dlopen_handle); + + NativeCodeRange *ncr = nc->nc_ranges; + while (ncr) { + NativeCodeRange* last_ncr = ncr; + ncr = ncr->next; + stgFree(last_ncr); + } +} + +void * loadNativeObj_POSIX (pathchar *path, char **errmsg) +{ + ObjectCode* nc; + void *hdl, *retval; + + ASSERT_LOCK_HELD(&linker_mutex); + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX %" PATH_FMT "\n", path)); + + retval = NULL; + + + /* If we load the same object multiple times, just return the + * already-loaded handle. Note that this is broken if unloadNativeObj + * is used, as we don’t do any reference counting; see #24345. + */ + ObjectCode *existing_oc = lookupObjectByPath(path); + if (existing_oc && existing_oc->status != OBJECT_UNLOADED) { + if (existing_oc->type == DYNAMIC_OBJECT) { + retval = existing_oc->dlopen_handle; + goto success; + } + copyErrmsg(errmsg, "loadNativeObj_POSIX: already loaded as non-dynamic object"); + goto dlopen_fail; + } + + nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0); + + foreignExportsLoadingObject(nc); + + // When dlopen() loads a profiled dynamic library, it calls the ctors which + // will call registerCcsList() to append the defined CostCentreStacks to + // CCS_LIST. However, another thread may be doing other things with the RTS + // linker that transitively calls refreshProfilingCCSs() which also accesses + // CCS_LIST. So there's a risk of data race that may lead to segfaults + // (#24423), and we need to ensure the ctors are also protected by + // ccs_mutex. +#if defined(PROFILING) + ACQUIRE_LOCK(&ccs_mutex); +#endif + + // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want + // to learn eagerly about all external functions. Otherwise, there is no + // additional advantage to being eager, so it is better to be lazy and only bind + // functions when needed for better performance. + int dlopen_mode; +#if defined(HAVE_DLINFO) + dlopen_mode = RTLD_NOW; +#else + dlopen_mode = RTLD_LAZY; +#endif + + hdl = dlopen(path, dlopen_mode|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */ + nc->dlopen_handle = hdl; + nc->status = OBJECT_READY; + +#if defined(PROFILING) + RELEASE_LOCK(&ccs_mutex); +#endif + + foreignExportsFinishedLoadingObject(); + + if (hdl == NULL) { + /* dlopen failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlopen_fail; + } + +#if defined(HAVE_DLINFO) + struct link_map *map; + if (dlinfo(hdl, RTLD_DI_LINKMAP, &map) == -1) { + /* dlinfo failed; save the message in errmsg */ + copyErrmsg(errmsg, dlerror()); + goto dlinfo_fail; + } + + hdl = NULL; // pass handle ownership to nc + + struct piterate_cb_info piterate_info = { + .nc = nc, + .l_addr = (void *) map->l_addr + }; + dl_iterate_phdr(loadNativeObjCb_, &piterate_info); + if (!nc->nc_ranges) { + copyErrmsg(errmsg, "dl_iterate_phdr failed to find obj"); + goto dl_iterate_phdr_fail; + } + nc->unloadable = true; +#else + nc->nc_ranges = NULL; + nc->unloadable = false; +#endif /* defined (HAVE_DLINFO) */ + + insertOCSectionIndices(nc); + + nc->next_loaded_object = loaded_objects; + loaded_objects = nc; + + retval = nc->dlopen_handle; + +#if defined(PROFILING) + // collect any new cost centres that were defined in the loaded object. + refreshProfilingCCSs(); +#endif + + goto success; + +#if defined(HAVE_DLINFO) +dl_iterate_phdr_fail: +#endif + freeNativeCode_POSIX(nc); +#if defined(HAVE_DLINFO) +dlinfo_fail: +#endif + if (hdl) dlclose(hdl); +dlopen_fail: +success: + + IF_DEBUG(linker, debugBelch("loadNativeObj_POSIX result=%p\n", retval)); + + return retval; +} + +#endif /* elf + macho */ ===================================== rts/linker/LoadNativeObjPosix.h ===================================== @@ -0,0 +1,11 @@ +#pragma once + +#include "Rts.h" +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void freeNativeCode_POSIX ( ObjectCode *nc ); +void *loadNativeObj_POSIX ( pathchar *path, char **errmsg ); + +#include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -1017,7 +1017,10 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f stgFree(dllName); IF_DEBUG(linker, debugBelch("loadArchive: read symbol %s from lib `%" PATH_FMT "'\n", symbol, dll)); - const char* result = addDLL(dll); + // We must call `addDLL_PEi386` directly rather than `addDLL` because `addDLL` + // is now a wrapper around `loadNativeObj` which acquires a lock which we + // already have here. + const char* result = addDLL_PEi386(dll, NULL); stgFree(image); @@ -1141,47 +1144,57 @@ SymbolAddr* lookupSymbolInDLLs ( const SymbolName* lbl, ObjectCode *dependent ) { OpenedDLL* o_dll; - SymbolAddr* sym; + SymbolAddr* res; - for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) { - /* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */ + for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) + if ((res = lookupSymbolInDLL_PEi386(lbl, o_dll->instance, o_dll->name, dependent))) + return res; + return NULL; +} - sym = GetProcAddress(o_dll->instance, lbl+STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ - return sym; - } +SymbolAddr* +lookupSymbolInDLL_PEi386 ( const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name STG_UNUSED, ObjectCode *dependent) +{ + SymbolAddr* sym; - // TODO: Drop this - /* Ticket #2283. - Long description: http://support.microsoft.com/kb/132044 - tl;dr: - If C/C++ compiler sees __declspec(dllimport) ... foo ... - it generates call *__imp_foo, and __imp_foo here has exactly - the same semantics as in __imp_foo = GetProcAddress(..., "foo") - */ - if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { - sym = GetProcAddress(o_dll->instance, - lbl + 6 + STRIP_LEADING_UNDERSCORE); - if (sym != NULL) { - SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); - if (indirect == NULL) { - barf("lookupSymbolInDLLs: Failed to allocation indirection"); - } - *indirect = sym; - IF_DEBUG(linker, - debugBelch("warning: %s from %S is linked instead of %s\n", - lbl+6+STRIP_LEADING_UNDERSCORE, o_dll->name, lbl)); - return (void*) indirect; - } - } + /* debugBelch("look in %ls for %s\n", dll_name, lbl); */ - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(instance, lbl+STRIP_LEADING_UNDERSCORE); + if (sym != NULL) { + /*debugBelch("found %s in %ls\n", lbl+STRIP_LEADING_UNDERSCORE,dll_name);*/ + return sym; + } + + // TODO: Drop this + /* Ticket #2283. + Long description: http://support.microsoft.com/kb/132044 + tl;dr: + If C/C++ compiler sees __declspec(dllimport) ... foo ... + it generates call *__imp_foo, and __imp_foo here has exactly + the same semantics as in __imp_foo = GetProcAddress(..., "foo") + */ + if (sym == NULL && strncmp (lbl, "__imp_", 6) == 0) { + sym = GetProcAddress(instance, + lbl + 6 + STRIP_LEADING_UNDERSCORE); if (sym != NULL) { - /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ - return sym; + SymbolAddr** indirect = m32_alloc(dependent->rw_m32, sizeof(SymbolAddr*), 8); + if (indirect == NULL) { + barf("lookupSymbolInDLLs: Failed to allocation indirection"); + } + *indirect = sym; + IF_DEBUG(linker, + debugBelch("warning: %s from %S is linked instead of %s\n", + lbl+6+STRIP_LEADING_UNDERSCORE, dll_name, lbl)); + return (void*) indirect; } } + + sym = GetProcAddress(instance, lbl); + if (sym != NULL) { + /*debugBelch("found %s in %s\n", lbl,dll_name);*/ + return sym; + } + return NULL; } ===================================== rts/linker/PEi386.h ===================================== @@ -60,6 +60,7 @@ bool ocRunFini_PEi386 ( ObjectCode *oc ); bool ocGetNames_PEi386 ( ObjectCode* oc ); bool ocVerifyImage_PEi386 ( ObjectCode* oc ); SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type); +SymbolAddr *lookupSymbolInDLL_PEi386 (const SymbolName* lbl, HINSTANCE instance, pathchar* dll_name, ObjectCode *dependent); /* See Note [mingw-w64 name decoration scheme] */ /* We use myindex to calculate array addresses, rather than ===================================== rts/rts.cabal ===================================== @@ -458,6 +458,7 @@ library linker/Elf.c linker/InitFini.c linker/LoadArchive.c + linker/LoadNativeObjPosix.c linker/M32Alloc.c linker/MMap.c linker/MachO.c ===================================== testsuite/tests/ghci/linking/dyn/T3372.hs ===================================== @@ -1,3 +1,6 @@ +-- Note: This test exercises running concurrent GHCi sessions, but +-- although this test is expected to pass, running concurrent GHCi +-- sessions is currently broken in other ways; see #24345. {-# LANGUAGE MagicHash #-} module Main where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39e5cb6c7092073f18a6442fac858d1a0fc70fdf...83e7e694278980c08874a66dd9d35330619c300d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39e5cb6c7092073f18a6442fac858d1a0fc70fdf...83e7e694278980c08874a66dd9d35330619c300d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 18:12:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 14:12:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660d9c281c43f_231e181a007347862f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b7265197 by Ben Gamari at 2024-04-03T14:12:46-04:00 testsuite: Introduce template-haskell-exports test - - - - - addae194 by Luite Stegeman at 2024-04-03T14:12:50-04:00 Update correct counter in bumpTickyAllocd - - - - - c0df4506 by Andrei Borzenkov at 2024-04-03T14:12:51-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5f45a7f00c7686d9f01075295370d205a6ad84c...c0df45068a1e8495280ab7ed09615c8f516902e3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5f45a7f00c7686d9f01075295370d205a6ad84c...c0df45068a1e8495280ab7ed09615c8f516902e3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 20:52:13 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 03 Apr 2024 16:52:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-cimport-epalocated Message-ID: <660dc17d53141_254dae107988c37038@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-cimport-epalocated at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-cimport-epalocated You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 21:33:23 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 17:33:23 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660dcb2368f0f_254dae17811ac47312@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ab79ec98 by Ben Gamari at 2024-04-03T17:33:12-04:00 testsuite: Introduce template-haskell-exports test - - - - - cf0612c6 by Luite Stegeman at 2024-04-03T17:33:15-04:00 Update correct counter in bumpTickyAllocd - - - - - 423b2705 by Andrei Borzenkov at 2024-04-03T17:33:16-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c0df45068a1e8495280ab7ed09615c8f516902e3...423b2705cf189dffa1c8073d0febe7fe86bc2f8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c0df45068a1e8495280ab7ed09615c8f516902e3...423b2705cf189dffa1c8073d0febe7fe86bc2f8f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 3 21:50:23 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 03 Apr 2024 17:50:23 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] testsuite: Add test for lookupSymbolInNativeObj Message-ID: <660dcf1fdd732_254dae1a21c40538cb@gitlab.mail> Ben Gamari pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 00f908b0 by Ben Gamari at 2024-04-03T17:41:37-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 5 changed files: - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c Changes: ===================================== testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +lookupSymbolInNativeObj1: + '$(TEST_HC)' -shared -dynamic obj.c -o libobj.so + '$(TEST_HC)' -no-hs-main -dynamic lookupSymbolInNativeObj1.c -o main + ./main + ===================================== testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T ===================================== @@ -0,0 +1,5 @@ +test('lookupSymbolInNativeObj1', + [unless(have_dynamic(), skip), + extra_files(['obj.c'])], + makefile_test, []) + ===================================== testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c ===================================== @@ -0,0 +1,39 @@ +#include "Rts.h" + +#if defined(mingw32_HOST_OS) +#define PATH_STR(str) L##str +#else +#define PATH_STR(str) str +#endif + +typedef void (*hello_t)(); + +int main(int argc, char *argv[]) +{ + RtsConfig conf = defaultRtsConfig; + conf.rts_opts_enabled = RtsOptsAll; + hs_init_ghc(&argc, &argv, conf); + + initLinker_(0); + + int ok; + char *errmsg; + void *obj = loadNativeObj("./libobj.so", &errmsg); + if (!obj) { + barf("loadNativeObj failed: %s", errmsg); + } + + hello_t sym; + sym = lookupSymbolInNativeObj(obj, "hello"); + if (sym == NULL) { + barf("lookupSymbolInNativeObj failed unexpectedly"); + } + sym(); + + sym = lookupSymbolInNativeObj(obj, "hello_world"); + if (sym != NULL) { + barf("lookupSymbolInNativeObj succeeded unexpectedly"); + } + + return 0; +} ===================================== testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout ===================================== @@ -0,0 +1 @@ +hello world ===================================== testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c ===================================== @@ -0,0 +1,5 @@ +#include + +void hello() { + printf("hello world\n"); +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00f908b07ae52b0ecfea90eb708a309da0257abe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00f908b07ae52b0ecfea90eb708a309da0257abe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 00:43:42 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 03 Apr 2024 20:43:42 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660df7be77b12_254dae2f40d886164a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e7f51b12 by Ben Gamari at 2024-04-03T20:43:34-04:00 testsuite: Introduce template-haskell-exports test - - - - - b65a7f78 by Luite Stegeman at 2024-04-03T20:43:37-04:00 Update correct counter in bumpTickyAllocd - - - - - 7f6ff03e by Andrei Borzenkov at 2024-04-03T20:43:38-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/423b2705cf189dffa1c8073d0febe7fe86bc2f8f...7f6ff03e1b53ec6d93e40d63f7f3e7bd9ae05434 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/423b2705cf189dffa1c8073d0febe7fe86bc2f8f...7f6ff03e1b53ec6d93e40d63f7f3e7bd9ae05434 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 05:04:40 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 01:04:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660e34e7f289d_312ac81b1cff040464@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 481af81a by Ben Gamari at 2024-04-04T01:04:26-04:00 testsuite: Introduce template-haskell-exports test - - - - - ff592218 by Luite Stegeman at 2024-04-04T01:04:30-04:00 Update correct counter in bumpTickyAllocd - - - - - 1b70a89e by Andrei Borzenkov at 2024-04-04T01:04:31-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7f6ff03e1b53ec6d93e40d63f7f3e7bd9ae05434...1b70a89eca6fcab897a5d270a0158847eda1f997 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7f6ff03e1b53ec6d93e40d63f7f3e7bd9ae05434...1b70a89eca6fcab897a5d270a0158847eda1f997 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 08:04:58 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 04:04:58 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660e5f2abc48e_235424109e3d011811a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 870bb024 by Ben Gamari at 2024-04-04T04:04:50-04:00 testsuite: Introduce template-haskell-exports test - - - - - 329380e7 by Luite Stegeman at 2024-04-04T04:04:53-04:00 Update correct counter in bumpTickyAllocd - - - - - 3 changed files: - compiler/GHC/StgToCmm/Ticky.hs - testsuite/tests/interface-stability/all.T - + testsuite/tests/interface-stability/template-haskell-exports.stdout Changes: ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -809,7 +809,7 @@ bumpTickyEntryCount lbl = do bumpTickyAllocd :: CLabel -> Int -> FCode () bumpTickyAllocd lbl bytes = do platform <- getPlatform - bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_entry_count (platformConstants platform))) bytes + bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_allocd (platformConstants platform))) bytes bumpTickyTagSkip :: CLabel -> FCode () bumpTickyTagSkip lbl = do ===================================== testsuite/tests/interface-stability/all.T ===================================== @@ -9,3 +9,4 @@ def check_package(pkg_name): check_package('base') check_package('ghc-experimental') +check_package('template-haskell') ===================================== testsuite/tests/interface-stability/template-haskell-exports.stdout ===================================== The diff for this file was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1b70a89eca6fcab897a5d270a0158847eda1f997...329380e731bc3d455cc64f0c5a1f2463c39c11cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1b70a89eca6fcab897a5d270a0158847eda1f997...329380e731bc3d455cc64f0c5a1f2463c39c11cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 08:07:30 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 04 Apr 2024 04:07:30 -0400 Subject: [Git][ghc/ghc][wip/T23109] Wibble imports Message-ID: <660e5fc2681f4_23542411e6cb012311c@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 53437d46 by Simon Peyton Jones at 2024-04-04T09:07:01+01:00 Wibble imports - - - - - 1 changed file: - compiler/GHC/Core/Unfold.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -41,6 +41,8 @@ import GHC.Core import GHC.Core.Utils import GHC.Core.DataCon import GHC.Core.Type +import GHC.Core.Class( Class, classTyCon ) +import GHC.Core.TyCon( isNewTyCon ) import GHC.Types.Id import GHC.Types.Literal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53437d46bb7fd3790bc06814e70d893f2c5a9454 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53437d46bb7fd3790bc06814e70d893f2c5a9454 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 09:38:54 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 04 Apr 2024 05:38:54 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660e752e18000_15494c8d423080176@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 7dcc34c9 by Teo Camarasu at 2024-04-04T10:36:52+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 10 changed files: - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +171,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +61,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +79,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,13 +34,12 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) import Control.Applicative (Applicative(..)) @@ -48,35 +47,42 @@ import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1024,7 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1391,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7dcc34c94995393a733af9e6294ded327d1a10a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7dcc34c94995393a733af9e6294ded327d1a10a7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 09:41:29 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 04 Apr 2024 05:41:29 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660e75c9401a2_15494ca366b4902a3@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: af633d6c by Teo Camarasu at 2024-04-04T10:41:14+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 10 changed files: - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +171,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +61,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +79,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,13 +34,12 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) import Control.Applicative (Applicative(..)) @@ -48,35 +47,42 @@ import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1024,7 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1391,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af633d6cb2b0829cd1d50156c70f8510874baf58 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af633d6cb2b0829cd1d50156c70f8510874baf58 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 10:08:23 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 04 Apr 2024 06:08:23 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 55 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660e7c17b3071_15494ce7cbc41002a5@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 6a38d7b6 by Rodrigo Mesquita at 2024-04-04T11:08:06+01:00 loader: Note down suggestion for needed_mods The associated ticket is #24600 - - - - - a7e985fb by Rodrigo Mesquita at 2024-04-04T11:08:07+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 8b985376 by Alexis King at 2024-04-04T11:08:07+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 38a83ce0 by Rodrigo Mesquita at 2024-04-04T11:08:07+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - d50ce08d by Rodrigo Mesquita at 2024-04-04T11:08:07+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 1a021a8a by Ben Gamari at 2024-04-04T11:08:07+01:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 17 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00f908b07ae52b0ecfea90eb708a309da0257abe...1a021a8a4cfe4ee06b840611d035d99191ad5ac8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00f908b07ae52b0ecfea90eb708a309da0257abe...1a021a8a4cfe4ee06b840611d035d99191ad5ac8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 10:22:59 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 04 Apr 2024 06:22:59 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660e7f83d93a_15494c10a0cfc1021a8@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 840fe186 by Teo Camarasu at 2024-04-04T11:22:50+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. Resolves #23536 - - - - - 10 changed files: - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +171,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,11 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: Enable if we are bootstrapping template-haskell, and hence want to depend on both the in-tree and boot `template-haskell` lib + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +61,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +79,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,54 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1023,7 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1390,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/840fe186f95e24b9a8e690af1fd78b6dfaaff475 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/840fe186f95e24b9a8e690af1fd78b6dfaaff475 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 10:31:23 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 06:31:23 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <660e817b105_15494c125258c10531@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 6c752256 by Fendor at 2024-04-04T10:11:42+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. - - - - - 5935848a by Fendor at 2024-04-04T12:00:36+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -54,6 +53,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import Data.Functor.Identity +import Data.Bifunctor (Bifunctor(second)) +import Data.Coerce -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -75,7 +77,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +123,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +139,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +150,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +158,33 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) - - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) - - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) - - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) - --- | Write an interface file + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + tables :: [SomeReaderTable IO] + tables = + [ SomeReaderTable initFastStringReaderTable + , SomeReaderTable (initReadNameCachedBinary name_cache) + , SomeReaderTable @IO @BindingName (coerce (initReadNameCachedBinary name_cache)) + ] + + tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables + + final_bh <- foldM (\bh (SomeReaderTable (tbl' :: Identity (ReaderTable a))) -> do + let tbl = runIdentity tbl' + res <- Binary.forwardGet bh (getTable tbl bh) + let newDecoder = mkReaderFromTable tbl res + pure $ addReaderToUserData (mkSomeBinaryReader newDecoder) bh + ) bh tables + + pure final_bh + +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +197,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +214,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +238,40 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + let + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + writerTables = + [ SomeWriterTable initFastStringWriterTable + , SomeWriterTable initWriteNameTable + , SomeWriterTable (fmap (second (\(BinaryWriter f) -> BinaryWriter (\bh name -> f bh (getBindingName name)))) initWriteNameTable) + ] + + tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + + let writerUserData = + mkWriterUserData $ + map + (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) + tables + + let bh = setWriterUserData bh' writerUserData + (fs_count : name_count : _, r) <- + putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +283,108 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be duplicated 'FastString's and 'Name's. +To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ │ +│ ModIface │ +│ Payload │ +│ │ +├──────────────┤ +│ Ptr FS ├───────────┐ +├──────────────┤ │ +│ Ptr Name ├────────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄───────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄──────────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) +initReadNameCachedBinary cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +393,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +414,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +438,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +463,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +482,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,19 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr -getIfaceTopBndr bh = get bh +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr +getIfaceTopBndr bh = + case findUserDataReader (Proxy @BindingName) bh of + tbl -> + --pprTrace "putIfaceTopBndr" (ppr name) $ + getBindingName <$> getEntry tbl bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2449,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,14 +140,14 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> putEntry tbl bh (BindingName ac) get bh = do aa <- get bh ab <- get bh - ac <- get bh - return (FieldLabel aa ab ac) + ac <- case findUserDataReader (Proxy @BindingName) bh of + tbl -> getEntry tbl bh + return (FieldLabel aa ab $ getBindingName ac) flIsOverloaded :: FieldLabel -> Bool flIsOverloaded fl = ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,30 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + SomeReaderTable(..), + ReaderTable(..), + SomeWriterTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -93,6 +111,7 @@ import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +123,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +140,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +174,83 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: !WriterUserData, + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: !ReaderUserData, + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +269,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,42 +293,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -279,20 +352,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -313,7 +389,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -329,7 +405,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -350,8 +426,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -372,39 +448,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -412,7 +486,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -425,7 +499,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -437,7 +511,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -458,10 +532,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -484,15 +558,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -509,15 +583,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -533,15 +607,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -561,15 +635,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -980,63 +1054,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1044,14 +1118,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1062,7 +1136,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1081,73 +1157,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader + } + +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +findUserDataReader :: forall a . Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +findUserDataWriter :: forall a . Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data SomeReaderTable f = forall a . Typeable a => + SomeReaderTable (f (ReaderTable a)) + +data SomeWriterTable f = forall a . Typeable a => + SomeWriterTable (f (WriterTable, BinaryWriter a)) + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1156,34 +1356,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1212,43 +1390,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1260,12 +1437,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e2705b08f39e87ccb4396739f0c67ef999e8d88...5935848a1121a97d202926eb41b202efcc3c7b5a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e2705b08f39e87ccb4396739f0c67ef999e8d88...5935848a1121a97d202926eb41b202efcc3c7b5a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 11:05:41 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 07:05:41 -0400 Subject: [Git][ghc/ghc][master] testsuite: Introduce template-haskell-exports test Message-ID: <660e898531409_15494c18bf2801163e2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 2 changed files: - testsuite/tests/interface-stability/all.T - + testsuite/tests/interface-stability/template-haskell-exports.stdout Changes: ===================================== testsuite/tests/interface-stability/all.T ===================================== @@ -9,3 +9,4 @@ def check_package(pkg_name): check_package('base') check_package('ghc-experimental') +check_package('template-haskell') ===================================== testsuite/tests/interface-stability/template-haskell-exports.stdout ===================================== The diff for this file was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fde229f1816a0f9a6f600df289b3d5d305eb0ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fde229f1816a0f9a6f600df289b3d5d305eb0ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 11:06:13 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 07:06:13 -0400 Subject: [Git][ghc/ghc][master] Update correct counter in bumpTickyAllocd Message-ID: <660e89a59e464_15494c1a71b1412009e@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 1 changed file: - compiler/GHC/StgToCmm/Ticky.hs Changes: ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -809,7 +809,7 @@ bumpTickyEntryCount lbl = do bumpTickyAllocd :: CLabel -> Int -> FCode () bumpTickyAllocd lbl bytes = do platform <- getPlatform - bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_entry_count (platformConstants platform))) bytes + bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_allocd (platformConstants platform))) bytes bumpTickyTagSkip :: CLabel -> FCode () bumpTickyTagSkip lbl = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c4a96862081f03e2946a2ed7e80c108f06205a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c4a96862081f03e2946a2ed7e80c108f06205a1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 11:36:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 07:36:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660e90d8a3d3c_15494c1f355c4137634@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 43914846 by Fendor at 2024-04-04T07:36:39-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - 4aa55923 by Matthew Pickering at 2024-04-04T07:36:43-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 10 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Utils/Binary.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - testsuite/tests/ghci/should_run/BinaryArray.hs - testsuite/tests/interface-stability/all.T - + testsuite/tests/interface-stability/template-haskell-exports.stdout Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = instrsFromUArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = bitmapFromUArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr final_lits final_ptrs -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -42,9 +42,11 @@ import GHC.Types.Name.Env import Language.Haskell.Syntax.Module.Name -- Standard libraries +import Data.Array.Base (UArray(..)) import Data.Array.Unboxed import Foreign.Ptr import GHC.Exts +import Data.Word (Word64) {- Linking interpretables into something we can run @@ -60,10 +62,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) + (lits :: [Word64]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeSS lits0)-1) lits) + let !(UArray _ _ _ lits') = listArray (0 :: Int, fromIntegral (sizeSS lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + (BCOByteArray (getBCOInstrs insns)) + (BCOByteArray (getBCOBitmap bitmap)) + (BCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,8 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOInstrs, getBCOInstrs, BCOBitmap, getBCOBitmap + , instrsFromUArray, bitmapFromUArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -36,7 +40,6 @@ import Control.DeepSeq import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -45,6 +48,9 @@ import GHC.Stack.CCS import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList ) import GHC.Iface.Syntax import Language.Haskell.Syntax.Module.Name (ModuleName) +import GHC.Base (ByteArray#) +import Data.Array.Unboxed (UArray) +import Data.Array.Base (UArray(..)) -- ----------------------------------------------------------------------------- -- Compiled Byte Code @@ -148,12 +154,26 @@ newtype ItblPtr = ItblPtr (RemotePtr Heap.StgInfoTable) newtype AddrPtr = AddrPtr (RemotePtr ()) deriving (NFData) +-- | 'BCOInstrs' is backed by an 'ByteArray#' and stores +-- 'Word16' elements. +newtype BCOInstrs = BCOInstrs { getBCOInstrs :: ByteArray# } + +-- | 'BCOBitmap' is backed by an 'ByteArray#' and stores +-- 'Word64' elements. +newtype BCOBitmap = BCOBitmap { getBCOBitmap :: ByteArray# } + +instrsFromUArray :: UArray Int Word16 -> BCOInstrs +instrsFromUArray !(UArray _ _ _ barr) = BCOInstrs barr + +bitmapFromUArray :: UArray Int Word64 -> BCOBitmap +bitmapFromUArray !(UArray _ _ _ barr) = BCOBitmap barr + data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !BCOInstrs, -- insns + unlinkedBCOBitmap :: !BCOBitmap, -- bitmap unlinkedBCOLits :: !(SizedSeq BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(SizedSeq BCOPtr) -- ptrs } ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -809,7 +809,7 @@ bumpTickyEntryCount lbl = do bumpTickyAllocd :: CLabel -> Int -> FCode () bumpTickyAllocd lbl bytes = do platform <- getPlatform - bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_entry_count (platformConstants platform))) bytes + bumpTickyLitBy (cmmLabelOffB lbl (pc_OFFSET_StgEntCounter_allocd (platformConstants platform))) bytes bumpTickyTagSkip :: CLabel -> FCode () bumpTickyTagSkip lbl = do ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -243,15 +243,18 @@ tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) seekBin :: BinHandle -> Bin a -> IO () seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | SeekBin but without calling expandBin +-- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- by 'Bin a'. +-- This operation may 'panic', if the pointer location is out of bounds of the +-- buffer of 'BinHandle'. seekBinNoExpand :: BinHandle -> Bin a -> IO () seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,11 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +13,18 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts + +import GHC.IO #include "MachDeps.h" @@ -32,19 +41,32 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word64, -- bitmap + resolvedBCOLits :: BCOByteArray Word64, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word64) where + showsPrec _ _ = showString "BCOByteArray Word64" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +76,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +101,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) ===================================== testsuite/tests/interface-stability/all.T ===================================== @@ -9,3 +9,4 @@ def check_package(pkg_name): check_package('base') check_package('ghc-experimental') +check_package('template-haskell') ===================================== testsuite/tests/interface-stability/template-haskell-exports.stdout ===================================== The diff for this file was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/329380e731bc3d455cc64f0c5a1f2463c39c11cb...4aa5592313aa35c977466c06c1ced79784419ff7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/329380e731bc3d455cc64f0c5a1f2463c39c11cb...4aa5592313aa35c977466c06c1ced79784419ff7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 12:39:23 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 08:39:23 -0400 Subject: [Git][ghc/ghc][wip/fendor/fix-thunks-name-and-ui] Eliminate name thunk in declaration fingerprinting Message-ID: <660e9f7b4de00_1e95a0131a7860428@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/fix-thunks-name-and-ui at Glasgow Haskell Compiler / GHC Commits: e2de39aa by Fendor at 2024-04-04T14:39:16+02:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. - - - - - 1 changed file: - compiler/GHC/IfaceToCore.hs Changes: ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,10 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl + -- Thunk analysis showed we retain a lot of thunks here. + -- Thus, force it, it reduces the numbers of thunks in GHCi + -- session noticeably. -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2de39aa82420a30ff04814adb65d28ddb787455 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2de39aa82420a30ff04814adb65d28ddb787455 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 12:47:27 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 08:47:27 -0400 Subject: [Git][ghc/ghc][wip/nounpack-z-encs-faststring] Never UNPACK `FastMutInt` for counting z-encoded `FastString`s Message-ID: <660ea15fbd8e1_1e95a02a0e54638b6@gitlab.mail> Hannes Siebenhandl pushed to branch wip/nounpack-z-encs-faststring at Glasgow Haskell Compiler / GHC Commits: ce050190 by Fendor at 2024-04-04T14:47:20+02:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - 1 changed file: - compiler/GHC/Data/FastString.hs Changes: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce0501906e8dc90d485b6576a09920b29810b132 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce0501906e8dc90d485b6576a09920b29810b132 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 13:03:36 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Thu, 04 Apr 2024 09:03:36 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/invis-pats-change-ast] 3 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660ea52894902_1e95a0537b4074650@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/invis-pats-change-ast at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - f3d4bfab by Andrei Borzenkov at 2024-04-04T17:03:21+04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8fbc07b8ac00a88fd704f6d91ed4a25f7689e448...f3d4bfab295dfce962965c568ec42f8f3eb3bbb6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8fbc07b8ac00a88fd704f6d91ed4a25f7689e448...f3d4bfab295dfce962965c568ec42f8f3eb3bbb6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 13:20:43 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 04 Apr 2024 09:20:43 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] MP fixes Message-ID: <660ea92b36154_1e95a093832084957@gitlab.mail> Matthew Pickering pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 6a86d08b by Matthew Pickering at 2024-04-04T14:20:23+01:00 MP fixes - - - - - 3 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Types/FieldLabel.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -168,7 +168,6 @@ getTables name_cache bh = do tables = [ SomeReaderTable initFastStringReaderTable , SomeReaderTable (initReadNameCachedBinary name_cache) - , SomeReaderTable @IO @BindingName (coerce (initReadNameCachedBinary name_cache)) ] tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables @@ -244,23 +243,16 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - writerTables = - [ SomeWriterTable initFastStringWriterTable - , SomeWriterTable initWriteNameTable - , SomeWriterTable (fmap (second (\(BinaryWriter f) -> BinaryWriter (\bh name -> f bh (getBindingName name)))) initWriteNameTable) - ] - tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + (fast_wt, BinaryWriter fast_w) <- initFastStringWriterTable + (name_wt, BinaryWriter name_w) <- initWriteNameTable + - let writerUserData = - mkWriterUserData $ - map - (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) - tables + let writerUserData = newWriteState name_w name_w fast_w let bh = setWriterUserData bh' writerUserData (fs_count : name_count : _, r) <- - putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + putAllTables bh [fast_wt, name_wt] $ do put_payload bh return (name_count, fs_count, r) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -120,11 +120,7 @@ type IfaceTopBndr = Name -- drop it when serialising and add it back in when deserialising. getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr -getIfaceTopBndr bh = - case findUserDataReader (Proxy @BindingName) bh of - tbl -> - --pprTrace "putIfaceTopBndr" (ppr name) $ - getBindingName <$> getEntry tbl bh +getIfaceTopBndr bh = get bh putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,14 +140,12 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case findUserDataWriter (Proxy @BindingName) bh of - tbl -> putEntry tbl bh (BindingName ac) + put_ bh ac get bh = do aa <- get bh ab <- get bh - ac <- case findUserDataReader (Proxy @BindingName) bh of - tbl -> getEntry tbl bh - return (FieldLabel aa ab $ getBindingName ac) + ac <- get bh + return (FieldLabel aa ab ac) flIsOverloaded :: FieldLabel -> Bool flIsOverloaded fl = View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a86d08b4c20c3f05c0b5a959461815dd8604e15 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a86d08b4c20c3f05c0b5a959461815dd8604e15 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 13:28:07 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 04 Apr 2024 09:28:07 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] MP fixes Message-ID: <660eaae79e81a_1e95a0aba68087054@gitlab.mail> Matthew Pickering pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 61563853 by Matthew Pickering at 2024-04-04T14:27:54+01:00 MP fixes - - - - - 3 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Types/FieldLabel.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -54,8 +54,6 @@ import Data.Word import Data.IORef import Control.Monad import Data.Functor.Identity -import Data.Bifunctor (Bifunctor(second)) -import Data.Coerce -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -168,7 +166,6 @@ getTables name_cache bh = do tables = [ SomeReaderTable initFastStringReaderTable , SomeReaderTable (initReadNameCachedBinary name_cache) - , SomeReaderTable @IO @BindingName (coerce (initReadNameCachedBinary name_cache)) ] tables <- traverse (\(SomeReaderTable tblM) -> tblM >>= pure . SomeReaderTable . pure) tables @@ -244,23 +241,16 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - writerTables = - [ SomeWriterTable initFastStringWriterTable - , SomeWriterTable initWriteNameTable - , SomeWriterTable (fmap (second (\(BinaryWriter f) -> BinaryWriter (\bh name -> f bh (getBindingName name)))) initWriteNameTable) - ] - tables <- traverse (\(SomeWriterTable worker) -> worker >>= pure . SomeWriterTable . pure) writerTables + (fast_wt, BinaryWriter fast_w) <- initFastStringWriterTable + (name_wt, BinaryWriter name_w) <- initWriteNameTable + - let writerUserData = - mkWriterUserData $ - map - (\(SomeWriterTable tbl') -> mkSomeBinaryWriter (snd $ runIdentity tbl')) - tables + let writerUserData = newWriteState name_w name_w fast_w let bh = setWriterUserData bh' writerUserData (fs_count : name_count : _, r) <- - putAllTables bh (fmap (\(SomeWriterTable tbl) -> fst $ runIdentity tbl) tables) $ do + putAllTables bh [fast_wt, name_wt] $ do put_payload bh return (name_count, fs_count, r) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -120,11 +120,7 @@ type IfaceTopBndr = Name -- drop it when serialising and add it back in when deserialising. getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr -getIfaceTopBndr bh = - case findUserDataReader (Proxy @BindingName) bh of - tbl -> - --pprTrace "putIfaceTopBndr" (ppr name) $ - getBindingName <$> getEntry tbl bh +getIfaceTopBndr bh = get bh putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,14 +140,12 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case findUserDataWriter (Proxy @BindingName) bh of - tbl -> putEntry tbl bh (BindingName ac) + put_ bh ac get bh = do aa <- get bh ab <- get bh - ac <- case findUserDataReader (Proxy @BindingName) bh of - tbl -> getEntry tbl bh - return (FieldLabel aa ab $ getBindingName ac) + ac <- get bh + return (FieldLabel aa ab ac) flIsOverloaded :: FieldLabel -> Bool flIsOverloaded fl = View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61563853ed31172db8efa2890b6929b467e1f826 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61563853ed31172db8efa2890b6929b467e1f826 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 15:54:28 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 04 Apr 2024 11:54:28 -0400 Subject: [Git][ghc/ghc][wip/T23109] Wibbles Message-ID: <660ecd344dea6_1e95a01afcde0122560@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: b27f6c8c by Simon Peyton Jones at 2024-04-04T16:53:23+01:00 Wibbles Notably: define and use mkNewTypeDictApp - - - - - 5 changed files: - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -40,7 +40,6 @@ import GHC.Types.Var.Env ( VarEnv ) import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var -import GHC.Types.Basic( dfunInlinePragma ) import GHC.Core.Predicate import GHC.Core.Coercion @@ -50,8 +49,7 @@ import GHC.Core.Make ( mkCharExpr, mkNaturalExpr, mkStringExprFS, mkCoreLams ) import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Core.Class -import GHC.Core.Unfold.Make( mkDFunUnfolding ) -import GHC.Core ( Expr(..), Bind(..), mkConApp ) +import GHC.Core ( Expr(..), mkConApp ) import GHC.StgToCmm.Closure ( isSmallFamily ) @@ -68,7 +66,6 @@ import Language.Haskell.Syntax.Basic (FieldLabelString(..)) import GHC.Tc.Errors.Types import Control.Monad -import Data.Functor import Data.Maybe {- ******************************************************************* @@ -224,7 +221,6 @@ match_one so canonical dfun_id mb_inst_tys warn , iw_safe_over = so , iw_warn = warn } } } - {- Note [Shortcut solving: overlap] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have @@ -255,13 +251,10 @@ was a puzzling example. matchCTuple :: Class -> [Type] -> TcM ClsInstResult matchCTuple clas tys -- (isCTupleClass clas) holds = return (OneInst { cir_new_theta = tys - , cir_mk_ev = tuple_ev + , cir_mk_ev = evDictApp clas tys , cir_canonical = True , cir_what = BuiltinInstance }) -- The dfun *is* the data constructor! - where - data_con = tyConSingleDataCon (classTyCon clas) - tuple_ev = evDFunApp (dataConWrapId data_con) tys {- ******************************************************************** * * @@ -413,36 +406,21 @@ makeLitDict clas lit_ty lit_expr , Just rep_tc <- tyConAppTyCon_maybe (classMethodTy meth) -- If the method type is forall n. KnownNat n => SNat n -- then rep_tc :: TyCon is SNat - , [dict_con] <- tyConDataCons (classTyCon clas) , [rep_con] <- tyConDataCons rep_tc - , let pred_ty = mkClassPred clas [lit_ty] - dict_args = [ Type lit_ty, mkConApp rep_con [Type lit_ty, lit_expr] ] - dfun_rhs = mkConApp dict_con dict_args - dfun_info = vanillaIdInfo `setUnfoldingInfo` mkDFunUnfolding [] dict_con dict_args - `setInlinePragInfo` dfunInlinePragma - dfun_occ_str :: String - = "$f" ++ occNameString (getOccName clas) ++ - occNameString (getDFunTyKey lit_ty) - - = do { df_name <- newName (mkVarOcc dfun_occ_str) - ; let dfun_id = mkLocalVar (DFunId True) df_name ManyTy pred_ty dfun_info - ev_tm = EvExpr (Let (NonRec dfun_id dfun_rhs) (Var dfun_id)) + = do { df_name <- newNTDFName clas + ; let mk_ev _ = mkNewTypeDictApp df_name clas [lit_ty] $ + mkConApp rep_con [Type lit_ty, lit_expr] ; return $ OneInst { cir_new_theta = [] - , cir_mk_ev = \_ -> ev_tm + , cir_mk_ev = mk_ev , cir_canonical = True , cir_what = BuiltinInstance } } - | otherwise - = pprPanic "makeLitDict" $ - text "Unexpected evidence for" <+> ppr (className clas) - $$ vcat (map (ppr . idType) (classMethods clas)) + | otherwise + = pprPanic "makeLitDict" $ + text "Unexpected evidence for" <+> ppr (className clas) + $$ vcat (map (ppr . idType) (classMethods clas)) + -{- Here is what we are making - let $dfKnownNat17 :: KnownNat 17 - [Unfolding = DFun :DKnownNat @17 (UnsafeSNat @17 17)] - $dfKnownNat17 = :DKnownNat @17 (UnsafeSNat @17 17) - in $dfKnownNat17 --} {- ******************************************************************** * * @@ -475,12 +453,10 @@ matchWithDict [cls, mty] `App` (Var sv `Cast` mkTransCo (mkSubCo co2) (mkSymCo co)) - ; tc <- tcLookupTyCon withDictClassName - ; let Just withdict_data_con - = tyConSingleDataCon_maybe tc -- "Data constructor" - -- for WithDict - mk_ev [c] = evDataConApp withdict_data_con - [cls, mty] [evWithDict (evTermCoercion (EvExpr c))] + ; wd_cls <- tcLookupClass withDictClassName + ; dfun_name <- newNTDFName wd_cls + ; let mk_ev [c] = mkNewTypeDictApp dfun_name wd_cls [cls, mty] $ + evWithDict (evTermCoercion (EvExpr c)) mk_ev e = pprPanic "matchWithDict" (ppr e) ; return $ OneInst { cir_new_theta = [mkPrimEqPred mty inst_meth_ty] @@ -949,21 +925,24 @@ matchDataToTag dataToTagClass [levity, dty] = do (mkNomReflCo ManyTy) (mkSymCo repCo) (mkReflCo Representational intPrimTy) - dataToTagDataCon = tyConSingleDataCon (classTyCon dataToTagClass) - mk_ev _ = evDataConApp dataToTagDataCon - [levity, dty] - [methodRep `Cast` methodCo] - -> addUsedDataCons rdr_env repTyCon -- See wrinkles DTW2 and DTW3 - $> OneInst { cir_new_theta = [] -- (Ignore stupid theta.) - , cir_mk_ev = mk_ev - , cir_canonical = True - , cir_what = BuiltinInstance - } + -> do { addUsedDataCons rdr_env repTyCon -- See wrinkles DTW2 and DTW3 + ; df_name <- newNTDFName dataToTagClass + ; let mk_ev _ = mkNewTypeDictApp df_name dataToTagClass [levity, dty] $ + methodRep `Cast` methodCo + ; pure (OneInst { cir_new_theta = [] -- (Ignore stupid theta.) + , cir_mk_ev = mk_ev + , cir_canonical = True + , cir_what = BuiltinInstance })} | otherwise -> pure NoInstance matchDataToTag _ _ = pure NoInstance +newNTDFName :: Class -> TcM Name +newNTDFName cls = newName (mkVarOcc dfun_occ_str) + where + dfun_occ_str :: String + dfun_occ_str = "$f" ++ occNameString (getOccName cls) {- ******************************************************************** * * @@ -1011,8 +990,8 @@ doFunTy clas ty mult arg_ty ret_ty , cir_what = BuiltinInstance } where preds = map (mk_typeable_pred clas) [mult, arg_ty, ret_ty] - mk_ev [mult_ev, arg_ev, ret_ev] = evTypeable ty $ - EvTypeableTrFun (EvExpr mult_ev) (EvExpr arg_ev) (EvExpr ret_ev) + mk_ev [mult_ev, arg_ev, ret_ev] + = evTypeable ty $ EvTypeableTrFun (EvExpr mult_ev) (EvExpr arg_ev) (EvExpr ret_ev) mk_ev _ = panic "GHC.Tc.Instance.Class.doFunTy" @@ -1164,21 +1143,21 @@ if you'd written ***********************************************************************-} -- See also Note [The equality types story] in GHC.Builtin.Types.Prim -matchEqualityInst :: Class -> [Type] -> (DataCon, Role, Type, Type) +matchEqualityInst :: Class -> [Type] -> (Role, Type, Type) -- Precondition: `cls` satisfies GHC.Core.Predicate.isEqualityClass -- See Note [Solving equality classes] in GHC.Tc.Solver.Dict matchEqualityInst cls args | cls `hasKey` eqTyConKey -- Solves (t1 ~ t2) , [_,t1,t2] <- args - = (eqDataCon, Nominal, t1, t2) + = (Nominal, t1, t2) | cls `hasKey` heqTyConKey -- Solves (t1 ~~ t2) , [_,_,t1,t2] <- args - = (heqDataCon, Nominal, t1, t2) + = (Nominal, t1, t2) | cls `hasKey` coercibleTyConKey -- Solves (Coercible t1 t2) , [_, t1, t2] <- args - = (coercibleDataCon, Representational, t1, t2) + = (Representational, t1, t2) | otherwise -- Does not satisfy the precondition = pprPanic "matchEqualityInst" (ppr (mkClassPred cls args)) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -405,14 +405,14 @@ solveEqualityDict :: CtEvidence -> Class -> [Type] -> SolverStage Void solveEqualityDict ev cls tys | CtWanted { ctev_dest = dest } <- ev = Stage $ - do { let (data_con, role, t1, t2) = matchEqualityInst cls tys + do { let (role, t1, t2) = matchEqualityInst cls tys -- Unify t1~t2, putting anything that can't be solved -- immediately into the work list ; (co, _, _) <- wrapUnifierTcS ev role $ \uenv -> uType uenv t1 t2 -- Set d :: (t1~t2) = Eq# co ; setWantedEvTerm dest True $ - evDataConApp data_con tys [Coercion co] + evDictApp cls tys [Coercion co] ; stopWith ev "Solved wanted lifted equality" } | CtGiven { ctev_evar = ev_id, ctev_loc = loc } <- ev @@ -823,7 +823,7 @@ shortCutSolver dflags ev_w ev_i -- Emit work for subgoals but use our local cache -- so we can solve recursive dictionaries. - ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ; let ev_tm = mk_ev (map getEvExpr evc_vs) ev_binds' = extendEvBinds ev_binds $ mkWantedEvBind (ctEvEvId ev) canonical ev_tm ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -202,15 +202,15 @@ mkProvEvidence ev_id hetero_tys = [k1, k2, ty1, ty2] = case r of ReprEq | is_homo - -> Just ( mkClassPred coercibleClass homo_tys - , evDataConApp coercibleDataCon homo_tys eq_con_args ) + -> Just ( mkClassPred coercibleClass homo_tys + , evDictApp coercibleClass homo_tys eq_con_args ) | otherwise -> Nothing NomEq | is_homo - -> Just ( mkClassPred eqClass homo_tys - , evDataConApp eqDataCon homo_tys eq_con_args ) + -> Just ( mkClassPred eqClass homo_tys + , evDictApp eqClass homo_tys eq_con_args ) | otherwise - -> Just ( mkClassPred heqClass hetero_tys - , evDataConApp heqDataCon hetero_tys eq_con_args ) + -> Just ( mkClassPred heqClass hetero_tys + , evDictApp heqClass hetero_tys eq_con_args ) | otherwise = Just (pred, EvExpr (evId ev_id)) ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -27,7 +27,7 @@ module GHC.Tc.Types.Evidence ( -- * EvTerm (already a CoreExpr) EvTerm(..), EvExpr, - evId, evCoercion, evCast, evDFunApp, evDataConApp, evSelector, + evId, evCoercion, evCast, evDFunApp, evDictApp, mkNewTypeDictApp, evSelector, mkEvCast, evVarsOfTerm, mkEvScSelectors, evTypeable, findNeededEvVars, evTermCoercion, evTermCoercion_maybe, @@ -50,27 +50,34 @@ module GHC.Tc.Types.Evidence ( import GHC.Prelude -import GHC.Types.Unique.DFM -import GHC.Types.Unique.FM -import GHC.Types.Var -import GHC.Types.Id( idScaledType ) +import GHC.Tc.Utils.TcType + +import GHC.Core import GHC.Core.Coercion.Axiom import GHC.Core.Coercion import GHC.Core.Ppr () -- Instance OutputableBndr TyVar -import GHC.Tc.Utils.TcType +import GHC.Core.Unfold.Make( mkDFunUnfolding ) import GHC.Core.Type import GHC.Core.TyCon -import GHC.Core.DataCon ( DataCon, dataConWrapId ) -import GHC.Builtin.Names +import GHC.Core.Class( classTyCon ) +import GHC.Core.DataCon ( isNewDataCon, dataConWrapId ) +import GHC.Core.Class (Class, classSCSelId ) +import GHC.Core.FVs ( exprSomeFreeVars ) +import GHC.Core.InstEnv ( Canonical ) + + +import GHC.Types.Unique.DFM +import GHC.Types.Unique.FM +import GHC.Types.Var +import GHC.Types.Id( idScaledType ) +import GHC.Types.Id.Info import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Core.Predicate import GHC.Types.Basic +import GHC.Types.Name( Name ) -import GHC.Core -import GHC.Core.Class (Class, classSCSelId ) -import GHC.Core.FVs ( exprSomeFreeVars ) -import GHC.Core.InstEnv ( Canonical ) +import GHC.Builtin.Names import GHC.Utils.Misc import GHC.Utils.Panic @@ -529,8 +536,51 @@ evCast et tc | isReflCo tc = EvExpr et evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvTerm evDFunApp df tys ets = EvExpr $ Var df `mkTyApps` tys `mkApps` ets -evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvTerm -evDataConApp dc tys ets = evDFunApp (dataConWrapId dc) tys ets +evDictApp :: Class -> [Type] -> [EvExpr] -> EvTerm +-- Only for classes that are not represented by a newtype +evDictApp cls tys args + = case tyConSingleDataCon_maybe (classTyCon cls) of + Just dc -> assertPpr (not (isNewDataCon dc)) (ppr cls) $ + evDFunApp (dataConWrapId dc) tys args + Nothing -> pprPanic "evDictApp" (ppr cls) + +mkNewTypeDictApp :: Name -> Class -> [Type] -> EvExpr -> EvTerm +mkNewTypeDictApp df_name cls tys arg + | not (isNewTyCon tycon) + = evDictApp cls tys [arg] + | otherwise + = EvExpr $ Let (NonRec dfun dict_app) (Var dfun) + where + tycon = classTyCon cls + dict_con = tyConSingleDataCon tycon + pred_ty = mkClassPred cls tys + dict_args = map Type tys ++ [arg] + dict_app = mkConApp dict_con dict_args + dfun = mkLocalVar (DFunId True) df_name ManyTy pred_ty dfun_info + unf = mkDFunUnfolding [] dict_con dict_args + dfun_info = vanillaIdInfo `setUnfoldingInfo` unf + `setInlinePragInfo` dfunInlinePragma + +{- Here is what we are making: + let $fKnownNat :: KnownNat 17 + {-# Unfolding = DFun :DKnownNat @17 (UnsafeSNat @17 17) #-} + $fKnownNat = :DKnownNat @17 (UnsafeSNat @17 17) + in $fKnownNat + +Here we have introduced a funny extra binding: + +* KnownNat is a newtype class + +* $fKnownNat is a full DFun, with a DFun unfolding. So + - it does not inline; + - it interacts nicely with the class selector + +* :DKnowNat, the data construtor, will inline to a cast right away + But we don't want that to be visible to clients of this constraint + +All this is important for any newtype class; so evDictApp checks +that it is not used for newtype classes. +-} -- Selector id plus the types at which it -- should be instantiated, used for HasField ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -76,8 +76,8 @@ import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic -import GHC.Core.Multiplicity import GHC.Core +import GHC.Core.Multiplicity import GHC.Core.Predicate import GHC.Types.Name @@ -597,7 +597,23 @@ zonkIdBndrX v zonkIdBndr :: TcId -> ZonkTcM Id zonkIdBndr v = do { Scaled w' ty' <- zonkScaledTcTypeToTypeX (idScaledType v) - ; return $ setIdMult (setIdType v ty') w' } + ; v' <- if isLocalId v && hasCoreUnfolding unf -- Local DFuns are like this + then do { unf' <- zonkUnfolding unf + ; return (setIdUnfolding v unf') } + else return v + ; return $ setIdMult (setIdType v' ty') w' } + where + unf = realIdUnfolding v + +zonkUnfolding :: Unfolding -> ZonkTcM Unfolding +zonkUnfolding unf@(CoreUnfolding { uf_tmpl = tmpl }) + = do { tmpl' <- zonkCoreExpr tmpl + ; return (unf { uf_tmpl = tmpl'}) } +zonkUnfolding unf@(DFunUnfolding { df_bndrs = bndrs, df_args = args }) + = runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + do { args' <- mapM zonkCoreExpr args + ; return (unf { df_bndrs = bndrs', df_args = args'}) } +zonkUnfolding unf = return unf zonkIdBndrs :: [TcId] -> ZonkTcM [Id] zonkIdBndrs ids = mapM zonkIdBndr ids View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b27f6c8cc59bf576089c3c66ab0bed174aa65e6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b27f6c8cc59bf576089c3c66ab0bed174aa65e6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:14:13 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 12:14:13 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <660ed1d5660f3_1e95a01e540ec130115@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: a150e51a by Fendor at 2024-04-04T18:10:58+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. - - - - - ea37b798 by Fendor at 2024-04-04T18:13:49+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- (initReadNameCachedBinary name_cache) + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +233,35 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +-- See Note [Iface Binary Serialiser Order] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initWriteNameTable + + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +273,108 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be duplicated 'FastString's and 'Name's. +To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) +initReadNameCachedBinary cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +383,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +404,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +428,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +453,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +472,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,12 +103,14 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +122,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +139,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,42 +300,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p >= sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p >= sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -279,20 +359,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -313,7 +396,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -329,7 +412,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -350,8 +433,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -372,39 +455,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -412,7 +493,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -425,7 +506,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -437,7 +518,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -458,10 +539,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -484,15 +565,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -509,15 +590,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -533,15 +614,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -561,15 +642,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -980,63 +1061,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1044,14 +1125,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1062,7 +1143,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1081,73 +1164,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader + } + +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count + + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1156,34 +1363,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1212,43 +1397,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1260,12 +1444,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61563853ed31172db8efa2890b6929b467e1f826...ea37b7989c13615069f728739afd871de7f9becb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61563853ed31172db8efa2890b6929b467e1f826...ea37b7989c13615069f728739afd871de7f9becb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:17:28 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 12:17:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Replace `SizedSeq` with `FlatBag` for flattened structure Message-ID: <660ed29899c5e_1e95a01fd49a81317d1@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 27268b77 by Fendor at 2024-04-04T12:17:22-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - ddc8afe9 by Fendor at 2024-04-04T12:17:22-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 9d127769 by Andrei Borzenkov at 2024-04-04T12:17:23-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - fc649558 by Matthew Pickering at 2024-04-04T12:17:24-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4aa5592313aa35c977466c06c1ced79784419ff7...fc6495586eeac7f975db9219a861119561c235ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4aa5592313aa35c977466c06c1ced79784419ff7...fc6495586eeac7f975db9219a861119561c235ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:22:48 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 12:22:48 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660ed3d875e8a_1e95a0216987c139914@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: d07b4102 by Fendor at 2024-04-04T18:21:10+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinNoExpandReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do fsReaderTable <- initFastStringReaderTable nameReaderTable <- (initReadNameCachedBinary name_cache) @@ -192,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -209,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -234,7 +234,7 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Iface Binary Serialiser Order] -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable @@ -374,7 +374,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -383,7 +383,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -404,7 +404,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -428,7 +428,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -454,7 +454,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -112,9 +112,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -122,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -182,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -191,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -214,7 +214,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -233,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinNoExpandReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinNoExpandReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinNoExpandReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinNoExpandReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -261,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -277,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -335,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -346,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinNoExpandReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -39,7 +39,7 @@ computeFingerprint put_nonbinding_name a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter (Proxy @BindingName) bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Control.Monad +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinNoExpandReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinNoExpandReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -85,7 +87,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding @@ -172,70 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -254,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinNoExpandReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -278,42 +300,57 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinNoExpandReader :: ReadBinHandle -> Bin a -> IO () +seekBinNoExpandReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinNoExpand: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -322,20 +359,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -356,7 +396,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -372,7 +412,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -393,8 +433,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -415,39 +455,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -455,7 +493,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -468,7 +506,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -480,7 +518,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -501,10 +539,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -527,15 +565,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -552,15 +590,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -576,15 +614,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -604,15 +642,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1023,63 +1061,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinNoExpandReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinNoExpandReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinNoExpandReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1087,14 +1125,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1189,19 +1227,19 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } deriving (Functor) data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } @@ -1209,7 +1247,7 @@ mkReader f = BinaryReader -- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. -- -- If no 'BinaryReader' has been configured before, this function will panic. -findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) @@ -1219,7 +1257,7 @@ findUserDataReader query bh = -- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. -- -- If no 'BinaryWriter' has been configured before, this function will panic. -findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) @@ -1236,8 +1274,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1246,11 +1284,11 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_non_binding_name put_binding_name put_fs = mkWriterUserData @@ -1264,12 +1302,12 @@ newWriteState put_non_binding_name put_binding_name put_fs = -- ---------------------------------------------------------------------------- data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int } --------------------------------------------------------- @@ -1309,14 +1347,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1325,12 +1363,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1367,34 +1405,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit c641b7349239c497cbd64a64cd21fd388f431b9f +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d07b410229f3844118c4c211e9998478e0cdbc66 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d07b410229f3844118c4c211e9998478e0cdbc66 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:26:24 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 04 Apr 2024 12:26:24 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660ed4b0767f_1e95a0227f43c14035c@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: a5f0e63e by Teo Camarasu at 2024-04-04T17:25:59+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. See Note [Bootstrapping Template Haskell] Resolves #23536 - - - - - 11 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,106 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- Template Haskell requires special attention when compiling GHC. +-- The implementation of the Template Haskell set of features requires tight +-- coupling between the compiler and the `template-haskell` library. +-- This complicates the bootstrapping story as compatibility constraints are +-- placed on the version of `template-haskell` used to compile GHC during a +-- particular stage and the version bundled with it. +-- +-- These constraints can be divided by the features they are used to implement, +-- namely running splices either directly or via the external interpreter, and +-- desugaring bracket syntax. +-- +-- (C1) Executing splices within the compiler: In order to execute a splice +-- within the compiler, we must be able to compile and load code built against +-- the same version of the `template-haskell` library as the compiler. This +-- is an ABI compatibility constraint between the `template-haskell` version of +-- the compiler and the splice. +-- (C2) Executing splices through the external interpreter: In order to execute +-- a splice via the external interpreter, we serialise bytecode, run it with the +-- external interpreter, and communicate back the result through a binary +-- serialised interface. This is a binary serialisation compatibilty constraint +-- between the `template-haskell` version of the compiler and the splice. +-- (C3) Desugaring bracket syntax: Bracket syntax is desugared by referring to a +-- special wired-in package whose package id is `template-haskell`. So for +-- instance an expression `'Just` gets desugared to something of type +-- `template-haskell:Language.Haskell.TH.Syntax.Name`. Importantly, while this +-- identifier is wired-in, the identity of the `template-haskell` package is +-- not. So for instance we can successfully use an expression like +-- `'Just :: Name` while compiling the `template-haskell` package as long as its +-- package id is set to `template-haskell` as `Name` will resolve the the local +-- identifier in the package (and the LHS and RHS will align). On the other +-- hand, if we don't set the special package id, the type of the expression will +-- be `template-haskell:...Name` while the `Name` on the RHS will resolve to the +-- local identifier and we will get a type error. So, bracket syntax assumes the +-- presence of a particular API in the `template-haskell` package, but it allows +-- +-- These constraints are ranked from strongest to weakest. They only apply if we +-- want to support the particular feature associated with them. +-- +-- The tricky case is what do to when building the bootstrapping (stage1) GHC. +-- The stage2 GHC is simpler as it can use the in-tree `template-haskell` +-- package built by the stage1 GHC. +-- +-- We should note that we cannot feasibly use the internal interpreter with a +-- stage1 GHC. This is because the stage1 GHC was compiled with the stage0 GHC, +-- which we assume is a different version. In order to run a splice that too +-- would need to be compiled with the stage0 GHC, and so would all its +-- dependencies. +-- This allows us to disregard (C1) for the stage1 case. +-- +-- In the past, we used to build the stage1 GHC and all its dependencies against +-- the in-tree `template-haskell` library. This meant that we sacrificed (C2) +-- because they are likely not serialisation compatible. We could not sacrifice +-- (C3) because dependencies of GHC (such as `containers` and +-- `template-haskell`) used bracket syntax to define `Lift` instances. This +-- meant that the interface assumed by the boot compiler to implement bracket +-- desugaring could not be modified (not even through CPP as (C1) would +-- constrain us in future stages where we do support the internal interpreter). +-- Yet, bracket syntax did work and gave us splices that desugared to code that +-- referenced the in-tree version of `template-haskell` not the one the boot +-- compiler required. So they could never be run. +-- +-- Our current strategy is to not build `template-haskell` as a stage0 package. +-- All of GHCs dependencies depend on the boot compilers version, and produce +-- runnable splices. How do we deal with the stage1 compiler's dependency on +-- `template-haskell`? There are two options. (D1) depend on the boot +-- compiler's version for stage1 and then depend on the in-tree one in stage2. +-- This violates (C1) and (C2), so we wouldn't be able to run splices at all +-- with the stage1 compiler. Additionally this would introduce quite a bit of +-- CPP into the compiler and mean we would have to stub out much of the +-- template-haskell machinery or have an unrunable compatibilty shim. Or (D2) +-- depend on the in-tree version. +-- +-- (D2) is what we implement, but it is complicated by the fact that it means we +-- practically have two versions of `template-haskell` in the dependency graph +-- of the stage1 compiler. To avoid this, we recall that we only need +-- serliasation compatibility (as per (C2)), so we can avoid a direct dependency +-- on the in-tree version by vendoring it. We choose to vendor it into the +-- `ghc-boot` package as both `lib:ghc` and `ghci` require a dependency on the +-- `template-haskell` interface as they define the two ends of the protocol. +-- This allows us to still run splices through the external interpreter. +-- +-- We should note a futher edge-case with this approach. When compiling our +-- vendored `template-haskell` library, we run afoul of (C3). The library +-- defines several `Name`s using bracket syntax. As this package doesn't claim +-- to be the wired-in package but it defines its own `Name` type, we get a type +-- discrepancy with the `Name` type from the boot compiler's `template-haskell` +-- library. Most of these are only used to define `Lift` instances, so in the +-- vendored case we simply hide them behind CPP. Yet, there is one distinct use +-- of a `Name`. We have a `Name` for the constructors of the `Multiplicity` +-- type, which are also used in the pretty-printing module. We construct these +-- manulally instead. This allows us to completely avoid using bracket syntax +-- for compiling the vendored `template-haskell` package. +-- +-- To summarise, our current approach allows us to use the external interpreter +-- to run splices and allows bracket syntax to be desugared correctly. In order +-- to implement this we vendor the `template-haskell` library into `ghc-boot` +-- and take special care to not use bracket syntax in those modules as that +-- would incorrectly produce code that uses identifiers from the boot compiler's +-- `template-haskell` library. ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +171,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,54 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1023,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1391,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5f0e63ee2bec8bf895c24434d513a2684e95192 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5f0e63ee2bec8bf895c24434d513a2684e95192 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:29:19 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 04 Apr 2024 12:29:19 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <660ed55feabbf_1e95a023ce798144512@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 7c85b3d8 by Teo Camarasu at 2024-04-04T17:29:07+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. See Note [Bootstrapping Template Haskell] Resolves #23536 - - - - - 11 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,108 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- Template Haskell requires special attention when compiling GHC. +-- The implementation of the Template Haskell set of features requires tight +-- coupling between the compiler and the `template-haskell` library. +-- This complicates the bootstrapping story as compatibility constraints are +-- placed on the version of `template-haskell` used to compile GHC during a +-- particular stage and the version bundled with it. +-- +-- These constraints can be divided by the features they are used to implement, +-- namely running splices either directly or via the external interpreter, and +-- desugaring bracket syntax. +-- +-- (C1) Executing splices within the compiler: In order to execute a splice +-- within the compiler, we must be able to compile and load code built against +-- the same version of the `template-haskell` library as the compiler. This +-- is an ABI compatibility constraint between the `template-haskell` version of +-- the compiler and the splice. +-- (C2) Executing splices through the external interpreter: In order to execute +-- a splice via the external interpreter, we serialise bytecode, run it with the +-- external interpreter, and communicate back the result through a binary +-- serialised interface. This is a binary serialisation compatibilty constraint +-- between the `template-haskell` version of the compiler and the splice. +-- (C3) Desugaring bracket syntax: Bracket syntax is desugared by referring to a +-- special wired-in package whose package id is `template-haskell`. So for +-- instance an expression `'Just` gets desugared to something of type +-- `template-haskell:Language.Haskell.TH.Syntax.Name`. Importantly, while this +-- identifier is wired-in, the identity of the `template-haskell` package is +-- not. So for instance we can successfully use an expression like +-- `'Just :: Name` while compiling the `template-haskell` package as long as its +-- package id is set to `template-haskell` as `Name` will resolve the the local +-- identifier in the package (and the LHS and RHS will align). On the other +-- hand, if we don't set the special package id, the type of the expression will +-- be `template-haskell:...Name` while the `Name` on the RHS will resolve to the +-- local identifier and we will get a type error. So, bracket syntax assumes the +-- presence of a particular API in the `template-haskell` package, but it allows +-- +-- These constraints are ranked from strongest to weakest. They only apply if we +-- want to support the particular feature associated with them. +-- +-- The tricky case is what do to when building the bootstrapping (stage1) GHC. +-- The stage2 GHC is simpler as it can use the in-tree `template-haskell` +-- package built by the stage1 GHC. +-- +-- We should note that we cannot feasibly use the internal interpreter with a +-- stage1 GHC. This is because the stage1 GHC was compiled with the stage0 GHC, +-- which we assume is a different version. In order to run a splice that too +-- would need to be compiled with the stage0 GHC, and so would all its +-- dependencies. +-- This allows us to disregard (C1) for the stage1 case. +-- +-- In the past, we used to build the stage1 GHC and all its dependencies against +-- the in-tree `template-haskell` library. This meant that we sacrificed (C2) +-- because they are likely not serialisation compatible. We could not sacrifice +-- (C3) because dependencies of GHC (such as `containers` and +-- `template-haskell`) used bracket syntax to define `Lift` instances. This +-- meant that the interface assumed by the boot compiler to implement bracket +-- desugaring could not be modified (not even through CPP as (C1) would +-- constrain us in future stages where we do support the internal interpreter). +-- Yet, bracket syntax did work and gave us splices that desugared to code that +-- referenced the in-tree version of `template-haskell` not the one the boot +-- compiler required. So they could never be run. +-- +-- Our current strategy is to not build `template-haskell` as a stage0 package. +-- All of GHCs dependencies depend on the boot compilers version, and produce +-- runnable splices. How do we deal with the stage1 compiler's dependency on +-- `template-haskell`? There are two options. (D1) depend on the boot +-- compiler's version for stage1 and then depend on the in-tree one in stage2. +-- This violates (C1) and (C2), so we wouldn't be able to run splices at all +-- with the stage1 compiler. Additionally this would introduce quite a bit of +-- CPP into the compiler and mean we would have to stub out much of the +-- template-haskell machinery or have an unrunable compatibilty shim. Or (D2) +-- depend on the in-tree version. +-- +-- (D2) is what we implement, but it is complicated by the fact that it means we +-- practically have two versions of `template-haskell` in the dependency graph +-- of the stage1 compiler. To avoid this, we recall that we only need +-- serliasation compatibility (as per (C2)), so we can avoid a direct dependency +-- on the in-tree version by vendoring it. We choose to vendor it into the +-- `ghc-boot` package as both `lib:ghc` and `ghci` require a dependency on the +-- `template-haskell` interface as they define the two ends of the protocol. +-- This allows us to still run splices through the external interpreter. +-- +-- We should note a futher edge-case with this approach. When compiling our +-- vendored `template-haskell` library, we run afoul of (C3). The library +-- defines several `Name`s using bracket syntax. As this package doesn't claim +-- to be the wired-in package but it defines its own `Name` type, we get a type +-- discrepancy with the `Name` type from the boot compiler's `template-haskell` +-- library. Most of these are only used to define `Lift` instances, so in the +-- vendored case we simply hide them behind CPP. Yet, there is one distinct use +-- of a `Name`. We have a `Name` for the constructors of the `Multiplicity` +-- type, which are also used in the pretty-printing module. We construct these +-- manulally instead. This allows us to completely avoid using bracket syntax +-- for compiling the vendored `template-haskell` package. +-- +-- To summarise, our current approach allows us to use the external interpreter +-- to run splices and allows bracket syntax to be desugared correctly. In order +-- to implement this we vendor the `template-haskell` library into `ghc-boot` +-- and take special care to not use bracket syntax in those modules as that +-- would incorrectly produce code that uses identifiers from the boot compiler's +-- `template-haskell` library. +-- +-- See #23536. ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -158,7 +158,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +171,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,54 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +#ifdef BOOTSTRAP_TH +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#else +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), + TYPE, RuntimeRep(..), Levity(..) ) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1023,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1391,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c85b3d8be68c000c93698954a7930096f0a499d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c85b3d8be68c000c93698954a7930096f0a499d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 16:50:03 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 04 Apr 2024 12:50:03 -0400 Subject: [Git][ghc/ghc][wip/fendor/os-string-modlocation] Migrate `Finder` component to `OsPath` Message-ID: <660eda3b2e927_210eac2624b01956f@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/os-string-modlocation at Glasgow Haskell Compiler / GHC Commits: dcd026a7 by Fendor at 2024-04-04T18:49:47+02:00 Migrate `Finder` component to `OsPath` For each module in a GHCi session, we keep alive one `ModLocation`. A `ModLocation` is fairly inefficiently packed, as `String`s are expensive in memory usage. While benchmarking the agda codebase, we concluded that we keep alive around 11MB of `FilePath`'s, solely retained by `ModLocation`. We provide a more densely packed encoding of `ModLocation`, by moving from `FilePath` to `OsPath`. Further, we migrate the full `Finder` component to `OsPath` to avoid unnecessary transformations. As the `Finder` component is well-encapsuled, this requires only a minimal amount of changes in other modules. Bump to haddock submodule for `ModLocation` changes. - - - - - 18 changed files: - compiler/GHC.hs - + compiler/GHC/Data/OsPath.hs - compiler/GHC/Data/Strict.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Finder/Types.hs - compiler/GHC/Unit/Module/Location.hs - compiler/ghc.cabal.in - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -76,6 +76,12 @@ module GHC ( ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), + ml_hs_file, + ml_hi_file, + ml_dyn_hi_file, + ml_obj_file, + ml_dyn_obj_file, + ml_hie_file, getModSummary, getModuleGraph, isLoaded, ===================================== compiler/GHC/Data/OsPath.hs ===================================== @@ -0,0 +1,22 @@ +module GHC.Data.OsPath + ( + -- * OsPath initialisation and transformation + OsPath + , OsString + , unsafeDecodeUtf + , unsafeEncodeUtf + , os + -- * Common utility functions + , () + , (<.>) + ) + where + +import GHC.Prelude + +import Data.Either +import System.OsPath +import System.Directory.Internal (os) + +unsafeDecodeUtf :: OsPath -> FilePath +unsafeDecodeUtf = fromRight (error "unsafeEncodeUtf: Internal error") . decodeUtf ===================================== compiler/GHC/Data/Strict.hs ===================================== @@ -9,8 +9,11 @@ module GHC.Data.Strict ( Maybe(Nothing, Just), fromMaybe, + GHC.Data.Strict.maybe, Pair(And), - + expectJust, + fromLazy, + toLazy, -- Not used at the moment: -- -- Either(Left, Right), @@ -18,9 +21,12 @@ module GHC.Data.Strict ( ) where import GHC.Prelude hiding (Maybe(..), Either(..)) +import GHC.Stack.Types + import Control.Applicative import Data.Semigroup import Data.Data +import qualified Data.Maybe as Lazy data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Functor, Foldable, Traversable, Data) @@ -29,6 +35,10 @@ fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe _ (Just x) = x +maybe :: b -> (a -> b) -> Maybe a -> b +maybe d _ Nothing = d +maybe _ f (Just x) = f x + apMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b apMaybe (Just f) (Just x) = Just (f x) apMaybe _ _ = Nothing @@ -37,6 +47,19 @@ altMaybe :: Maybe a -> Maybe a -> Maybe a altMaybe Nothing r = r altMaybe l _ = l +fromLazy :: Lazy.Maybe a -> Maybe a +fromLazy (Lazy.Just a) = Just a +fromLazy Lazy.Nothing = Nothing + +toLazy :: Maybe a -> Lazy.Maybe a +toLazy (Just a) = Lazy.Just a +toLazy Nothing = Lazy.Nothing + +expectJust :: HasCallStack => String -> Maybe a -> a +{-# INLINE expectJust #-} +expectJust _ (Just x) = x +expectJust err Nothing = error ("expectJust " ++ err) + instance Semigroup a => Semigroup (Maybe a) where Nothing <> b = b a <> Nothing = a ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Maybe +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Data.StringBuffer import GHC.Data.FastString import qualified GHC.Data.EnumSet as EnumSet @@ -772,7 +773,7 @@ summariseRequirement pn mod_name = do let PackageName pn_fs = pn let location = mkHomeModLocation2 fopts mod_name - (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" + (unsafeEncodeUtf $ unpackFS pn_fs moduleNameSlashes mod_name) (unsafeEncodeUtf "hsig") env <- getBkpEnv src_hash <- liftIO $ getFileHash (bkp_filename env) @@ -855,12 +856,12 @@ hsModuleToModSummary home_keys pn hsc_src modname -- these filenames to figure out where the hi files go. -- A travesty! let location0 = mkHomeModLocation2 fopts modname - (unpackFS unit_fs + (unsafeEncodeUtf $ unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of - HsigFile -> "hsig" - HsBootFile -> "hs-boot" - HsSrcFile -> "hs") + HsigFile -> unsafeEncodeUtf "hsig" + HsBootFile -> unsafeEncodeUtf "hs-boot" + HsSrcFile -> unsafeEncodeUtf "hs") -- DANGEROUS: bootifying can POISON the module finder cache let location = case hsc_src of HsBootFile -> addBootSuffixLocnOut location0 ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Driver.LlvmConfigCache (LlvmConfigCache) import GHC.Driver.Ppr import GHC.Driver.Backend +import GHC.Data.OsPath import qualified GHC.Data.ShortText as ST import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream @@ -259,7 +260,7 @@ outputForeignStubs Maybe FilePath) -- C file created outputForeignStubs logger tmpfs dflags unit_state mod location stubs = do - let stub_h = mkStubPaths (initFinderOpts dflags) (moduleName mod) location + let stub_h = unsafeDecodeUtf $ mkStubPaths (initFinderOpts dflags) (moduleName mod) location stub_c <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c" case stubs of ===================================== compiler/GHC/Driver/Config/Finder.hs ===================================== @@ -5,30 +5,31 @@ module GHC.Driver.Config.Finder ( import GHC.Prelude +import qualified GHC.Data.Strict as Strict import GHC.Driver.DynFlags import GHC.Unit.Finder.Types import GHC.Data.FastString - +import GHC.Data.OsPath -- | Create a new 'FinderOpts' from DynFlags. initFinderOpts :: DynFlags -> FinderOpts initFinderOpts flags = FinderOpts - { finder_importPaths = importPaths flags + { finder_importPaths = fmap unsafeEncodeUtf $ importPaths flags , finder_lookupHomeInterfaces = isOneShot (ghcMode flags) , finder_bypassHiFileCheck = MkDepend == (ghcMode flags) , finder_ways = ways flags , finder_enableSuggestions = gopt Opt_HelpfulErrors flags - , finder_workingDirectory = workingDirectory flags + , finder_workingDirectory = fmap unsafeEncodeUtf $ Strict.fromLazy $ workingDirectory flags , finder_thisPackageName = mkFastString <$> thisPackageName flags , finder_hiddenModules = hiddenModules flags , finder_reexportedModules = reexportedModules flags - , finder_hieDir = hieDir flags - , finder_hieSuf = hieSuf flags - , finder_hiDir = hiDir flags - , finder_hiSuf = hiSuf_ flags - , finder_dynHiSuf = dynHiSuf_ flags - , finder_objectDir = objectDir flags - , finder_objectSuf = objectSuf_ flags - , finder_dynObjectSuf = dynObjectSuf_ flags - , finder_stubDir = stubDir flags + , finder_hieDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hieDir flags + , finder_hieSuf = unsafeEncodeUtf $ hieSuf flags + , finder_hiDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ hiDir flags + , finder_hiSuf = unsafeEncodeUtf $ hiSuf_ flags + , finder_dynHiSuf = unsafeEncodeUtf $ dynHiSuf_ flags + , finder_objectDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ objectDir flags + , finder_objectSuf = unsafeEncodeUtf $ objectSuf_ flags + , finder_dynObjectSuf = unsafeEncodeUtf $ dynObjectSuf_ flags + , finder_stubDir = fmap unsafeEncodeUtf $ Strict.fromLazy $ stubDir flags } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -264,6 +264,8 @@ import qualified GHC.LanguageExtensions as LangExt import GHC.Data.FastString import GHC.Data.Bag +import GHC.Data.OsPath (unsafeEncodeUtf) +import qualified GHC.Data.Strict as Strict import GHC.Data.StringBuffer import qualified GHC.Data.Stream as Stream import GHC.Data.Stream (Stream) @@ -2106,12 +2108,12 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs rawCmms return stub_c_exists where - no_loc = ModLocation{ ml_hs_file = Just original_filename, - ml_hi_file = panic "hscCompileCmmFile: no hi file", - ml_obj_file = panic "hscCompileCmmFile: no obj file", - ml_dyn_obj_file = panic "hscCompileCmmFile: no dyn obj file", - ml_dyn_hi_file = panic "hscCompileCmmFile: no dyn obj file", - ml_hie_file = panic "hscCompileCmmFile: no hie file"} + no_loc = ModLocation{ ml_hs_file_ = Strict.Just $ unsafeEncodeUtf original_filename, + ml_hi_file_ = panic "hscCompileCmmFile: no hi file", + ml_obj_file_ = panic "hscCompileCmmFile: no obj file", + ml_dyn_obj_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_dyn_hi_file_ = panic "hscCompileCmmFile: no dyn obj file", + ml_hie_file_ = panic "hscCompileCmmFile: no hie file"} -------------------- Stuff for new code gen --------------------- @@ -2346,12 +2348,12 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do {- Desugar it -} -- We use a basically null location for iNTERACTIVE - let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file", - ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file", - ml_dyn_obj_file = panic "hsDeclsWithLocation:ml_dyn_obj_file", - ml_dyn_hi_file = panic "hsDeclsWithLocation:ml_dyn_hi_file", - ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" } + let iNTERACTIVELoc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hsDeclsWithLocation:ml_hi_file", + ml_obj_file_ = panic "hsDeclsWithLocation:ml_obj_file", + ml_dyn_obj_file_ = panic "hsDeclsWithLocation:ml_dyn_obj_file", + ml_dyn_hi_file_ = panic "hsDeclsWithLocation:ml_dyn_hi_file", + ml_hie_file_ = panic "hsDeclsWithLocation:ml_hie_file" } ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv {- Simplify -} @@ -2630,12 +2632,12 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do {- Lint if necessary -} lintInteractiveExpr (text "hscCompileCoreExpr") hsc_env prepd_expr - let this_loc = ModLocation{ ml_hs_file = Nothing, - ml_hi_file = panic "hscCompileCoreExpr':ml_hi_file", - ml_obj_file = panic "hscCompileCoreExpr':ml_obj_file", - ml_dyn_obj_file = panic "hscCompileCoreExpr': ml_obj_file", - ml_dyn_hi_file = panic "hscCompileCoreExpr': ml_dyn_hi_file", - ml_hie_file = panic "hscCompileCoreExpr':ml_hie_file" } + let this_loc = ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = panic "hscCompileCoreExpr':ml_hi_file", + ml_obj_file_ = panic "hscCompileCoreExpr':ml_obj_file", + ml_dyn_obj_file_ = panic "hscCompileCoreExpr': ml_obj_file", + ml_dyn_hi_file_ = panic "hscCompileCoreExpr': ml_dyn_hi_file", + ml_hie_file_ = panic "hscCompileCoreExpr':ml_hie_file" } -- Ensure module uniqueness by giving it a name like "GhciNNNN". -- This uniqueness is needed by the JS linker. Without it we break the 1-1 ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -72,10 +72,12 @@ import GHC.Iface.Load ( cannotFindModule ) import GHC.IfaceToCore ( typecheckIface ) import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) ) +import qualified GHC.Data.Strict as Strict import GHC.Data.Bag ( listToBag ) import GHC.Data.Graph.Directed import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) +import GHC.Data.OsPath ( unsafeEncodeUtf, unsafeDecodeUtf ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt @@ -336,12 +338,15 @@ warnMissingHomeModules dflags targets mod_graph = -> moduleName (ms_mod mod) == name && tuid == ms_unitid mod TargetFile target_file _ - | Just mod_file <- ml_hs_file (ms_location mod) + | Strict.Just mod_file <- ml_hs_file_ (ms_location mod) -> - augmentByWorkingDirectory dflags target_file == mod_file || + let + target_os_file = unsafeEncodeUtf target_file + in + augmentByWorkingDirectory dflags target_file == unsafeDecodeUtf mod_file || -- Don't warn on B.hs-boot if B.hs is specified (#16551) - addBootSuffix target_file == mod_file || + addBootSuffix target_os_file == mod_file || -- We can get a file target even if a module name was -- originally specified in a command line because it can @@ -1830,7 +1835,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + return (unsafeEncodeUtf tn, unsafeEncodeUtf dyn_tn) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -1839,8 +1844,8 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = -- If ``-fwrite-interface` is specified, then the .o and .hi files -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags - then return ((ml_hi_file ms_location, ml_dyn_hi_file ms_location) - , (ml_obj_file ms_location, ml_dyn_obj_file ms_location)) + then return ((ml_hi_file_ ms_location, ml_dyn_hi_file_ ms_location) + , (ml_obj_file_ ms_location, ml_dyn_obj_file_ ms_location)) else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags)) <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) let new_dflags = case enable_spec of @@ -1849,10 +1854,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = EnableByteCodeAndObject -> (gopt_set dflags Opt_ByteCodeAndObjectCode) { backend = defaultBackendOf ms} let ms' = ms { ms_location = - ms_location { ml_hi_file = hi_file - , ml_obj_file = o_file - , ml_dyn_hi_file = dyn_hi_file - , ml_dyn_obj_file = dyn_o_file } + ms_location { ml_hi_file_ = hi_file + , ml_obj_file_ = o_file + , ml_dyn_hi_file_ = dyn_hi_file + , ml_dyn_obj_file_ = dyn_o_file } , ms_hspp_opts = updOptLevel 0 $ new_dflags } -- Recursive call to catch the other cases @@ -2037,7 +2042,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + let location = mkHomeModLocation fopts pi_mod_name (unsafeEncodeUtf src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -24,6 +24,7 @@ import GHC.Driver.Env import GHC.Driver.Errors.Types import qualified GHC.SysTools as SysTools import GHC.Data.Graph.Directed ( SCC(..) ) +import GHC.Data.OsPath (unsafeDecodeUtf) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Types.SourceError @@ -297,7 +298,7 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> return (Just (unsafeDecodeUtf $ addBootSuffix_maybe is_boot (ml_hi_file_ loc))) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Iface.Make import GHC.Driver.Config.Parser import GHC.Parser.Header import GHC.Data.StringBuffer +import GHC.Data.OsPath (unsafeEncodeUtf) import GHC.Types.SourceError import GHC.Unit.Finder import Data.IORef @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + let location1 = mkHomeModLocation2 fopts mod_name (unsafeEncodeUtf basename) (unsafeEncodeUtf suff) -- Boot-ify it if necessary let location2 @@ -771,11 +772,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + location3 | Just fn <- ohi = location2{ ml_hi_file_ = unsafeEncodeUtf fn } | otherwise = location2 let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file_ = unsafeEncodeUtf fn } | otherwise = location3 -- Take -o into account if present @@ -789,10 +790,10 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do location5 | Just ofile <- expl_o_file , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file , isNoLink (ghcLink dflags) - = location4 { ml_obj_file = ofile - , ml_dyn_obj_file = dyn_ofile } + = location4 { ml_obj_file_ = unsafeEncodeUtf ofile + , ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | Just dyn_ofile <- expl_dyn_o_file - = location4 { ml_dyn_obj_file = dyn_ofile } + = location4 { ml_dyn_obj_file_ = unsafeEncodeUtf dyn_ofile } | otherwise = location4 return location5 where ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Panic.Plain import GHC.Driver.DynFlags import GHC.Driver.Env import GHC.Data.Maybe +import GHC.Data.OsPath import GHC.Prelude import GHC.Unit import GHC.Unit.Env @@ -55,13 +56,13 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result InstalledNotFound files mb_pkg | Just pkg <- mb_pkg , notHomeUnitId mhome_unit pkg - -> not_found_in_package pkg files + -> not_found_in_package pkg $ fmap unsafeDecodeUtf files | null files -> NotAModule | otherwise - -> CouldntFindInFiles files + -> CouldntFindInFiles $ fmap unsafeDecodeUtf files _ -> panic "cantFindInstalledErr" ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -42,6 +42,9 @@ import GHC.Platform.Ways import GHC.Builtin.Names ( gHC_PRIM ) +import qualified GHC.Data.Strict as Strict +import GHC.Data.OsPath + import GHC.Unit.Env import GHC.Unit.Types import GHC.Unit.Module @@ -49,7 +52,6 @@ import GHC.Unit.Home import GHC.Unit.State import GHC.Unit.Finder.Types -import GHC.Data.Maybe ( expectJust ) import qualified GHC.Data.ShortText as ST import GHC.Utils.Misc @@ -61,8 +63,7 @@ import GHC.Types.PkgQual import GHC.Fingerprint import Data.IORef -import System.Directory -import System.FilePath +import System.Directory.OsPath import Control.Monad import Data.Time import qualified Data.Map as M @@ -70,9 +71,10 @@ import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder import qualified Data.Set as Set +import qualified System.OsPath as OsPath -type FileExt = String -- Filename extension -type BaseName = String -- Basename of file +type FileExt = OsString -- Filename extension +type BaseName = OsPath -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -286,7 +288,7 @@ findLookupResult fc fopts r = case r of -- implicit locations from the instances InstalledFound loc _ -> return (Found loc m) InstalledNoPackage _ -> return (NoPackage (moduleUnit m)) - InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnit m) + InstalledNotFound fp _ -> return (NotFound{ fr_paths = fmap unsafeDecodeUtf fp, fr_pkg = Just (moduleUnit m) , fr_pkgs_hidden = [] , fr_mods_hidden = [] , fr_unusables = [] @@ -357,7 +359,7 @@ findHomeModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkHomeModule home_unit mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -382,7 +384,7 @@ findHomePackageModule fc fopts home_unit mod_name = do InstalledFound loc _ -> Found loc (mkModule uid mod_name) InstalledNoPackage _ -> NoPackage uid -- impossible InstalledNotFound fps _ -> NotFound { - fr_paths = fps, + fr_paths = fmap unsafeDecodeUtf fps, fr_pkg = Just uid, fr_mods_hidden = [], fr_pkgs_hidden = [], @@ -413,22 +415,22 @@ findInstalledHomeModule fc fopts home_unit mod_name = do let maybe_working_dir = finder_workingDirectory fopts home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) + Strict.Nothing -> finder_importPaths fopts + Strict.Just fp -> augmentImports fp (finder_importPaths fopts) hi_dir_path = case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] - Nothing -> home_path + Strict.Just hiDir -> case maybe_working_dir of + Strict.Nothing -> [hiDir] + Strict.Just fp -> [fp hiDir] + Strict.Nothing -> home_path hisuf = finder_hiSuf fopts mod = mkModule home_unit mod_name source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") + [ (unsafeEncodeUtf "hs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hs") + , (unsafeEncodeUtf "lhs", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhs") + , (unsafeEncodeUtf "hsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "hsig") + , (unsafeEncodeUtf "lhsig", mkHomeModLocationSearched fopts mod_name $ unsafeEncodeUtf "lhsig") ] -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that @@ -453,10 +455,11 @@ findInstalledHomeModule fc fopts home_unit mod_name = do else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps - | otherwise = (work_dir fp) : augmentImports work_dir fps +augmentImports work_dir (fp:fps) + | OsPath.isAbsolute fp = fp : augmentImports work_dir fps + | otherwise = (work_dir fp) : augmentImports work_dir fps -- | Search for a module in external packages only. findPackageModule :: FinderCache -> UnitState -> FinderOpts -> InstalledModule -> IO InstalledFindResult @@ -488,14 +491,14 @@ findPackageModule_ fc fopts mod pkg_conf = do tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" + package_hisuf | null tag = unsafeEncodeUtf $ "hi" + | otherwise = unsafeEncodeUtf $ tag ++ "_hi" - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_dynhisuf = unsafeEncodeUtf $ waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - import_dirs = map ST.unpack $ unitImportDirs pkg_conf + import_dirs = map (unsafeEncodeUtf . ST.unpack) $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. in @@ -503,7 +506,7 @@ findPackageModule_ fc fopts mod pkg_conf = do [one] | finder_bypassHiFileCheck fopts -> -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) + let basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) loc = mk_hi_loc one basename in return $ InstalledFound loc mod _otherwise -> @@ -512,24 +515,24 @@ findPackageModule_ fc fopts mod pkg_conf = do -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath -> BaseName -> ModLocation -- action ) ] -> IO InstalledFindResult searchPathExts paths mod exts = search to_search where - basename = moduleNameSlashes (moduleName mod) + basename = unsafeEncodeUtf $ moduleNameSlashes (moduleName mod) - to_search :: [(FilePath, ModLocation)] + to_search :: [(OsPath, ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename + let base | path == unsafeEncodeUtf "." = basename | otherwise = path basename file = base <.> ext ] @@ -543,7 +546,7 @@ searchPathExts paths mod exts = search to_search else search rest mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation + -> OsPath -> BaseName -> ModLocation mkHomeModLocationSearched fopts mod suff path basename = mkHomeModLocation2 fopts mod (path basename) suff @@ -581,18 +584,18 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> OsPath -> ModLocation mkHomeModLocation dflags mod src_filename = - let (basename,extension) = splitExtension src_filename + let (basename,extension) = OsPath.splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension mkHomeModLocation2 :: FinderOpts -> ModuleName - -> FilePath -- Of source module, without suffix - -> String -- Suffix + -> OsPath -- Of source module, without suffix + -> FileExt -- Suffix -> ModLocation mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod + let mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod obj_fn = mkObjPath fopts src_basename mod_basename dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename @@ -600,72 +603,72 @@ mkHomeModLocation2 fopts mod src_basename ext = dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename hie_fn = mkHiePath fopts src_basename mod_basename - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + in (ModLocation{ ml_hs_file_ = Strict.Just (src_basename <.> ext), + ml_hi_file_ = hi_fn, + ml_dyn_hi_file_ = dyn_hi_fn, + ml_obj_file_ = obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, + ml_hie_file_ = hie_fn }) mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath + -> OsPath -> BaseName -> ModLocation mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + let loc = mkHomeModLocation2 fopts mod (path basename) mempty + in loc { ml_hs_file_ = Strict.Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String +mkHiOnlyModLocation :: FinderOpts -> FileExt -> FileExt -> OsPath -> OsPath -> ModLocation mkHiOnlyModLocation fopts hisuf dynhisuf path basename = let full_basename = path basename obj_fn = mkObjPath fopts full_basename basename dyn_obj_fn = mkDynObjPath fopts full_basename basename hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, + in ModLocation{ ml_hs_file_ = Strict.Nothing, + ml_hi_file_ = full_basename <.> hisuf, -- Remove the .hi-boot suffix from -- hi_file, if it had one. We always -- want the name of the real .hi file -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, + ml_dyn_obj_file_ = dyn_obj_fn, -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn + ml_dyn_hi_file_ = full_basename <.> dynhisuf, + ml_obj_file_ = obj_fn, + ml_hie_file_ = hie_fn } -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists mkObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath +mkObjPath fopts basename mod_basename = obj_basename OsPath.<.> osuf where odir = finder_objectDir fopts osuf = finder_objectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir OsPath. mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists mkDynObjPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf where odir = finder_objectDir fopts dynosuf = finder_dynObjectSuf fopts - obj_basename | Just dir <- odir = dir mod_basename + obj_basename | Strict.Just dir <- odir = dir mod_basename | otherwise = basename @@ -673,45 +676,45 @@ mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf -- Does /not/ check whether the .hi file exists mkHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiPath fopts basename mod_basename = hi_basename <.> hisuf where hidir = finder_hiDir fopts hisuf = finder_hiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists mkDynHiPath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf where hidir = finder_hiDir fopts dynhisuf = finder_dynHiSuf fopts - hi_basename | Just dir <- hidir = dir mod_basename + hi_basename | Strict.Just dir <- hidir = dir mod_basename | otherwise = basename -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists mkHiePath :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> OsPath mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf where hiedir = finder_hieDir fopts hiesuf = finder_hieSuf fopts - hie_basename | Just dir <- hiedir = dir mod_basename + hie_basename | Strict.Just dir <- hiedir = dir mod_basename | otherwise = basename @@ -726,23 +729,23 @@ mkStubPaths :: FinderOpts -> ModuleName -> ModLocation - -> FilePath + -> OsPath mkStubPaths fopts mod location = let stubdir = finder_stubDir fopts - mod_basename = moduleNameSlashes mod - src_basename = dropExtension $ expectJust "mkStubPaths" - (ml_hs_file location) + mod_basename = unsafeEncodeUtf $ moduleNameSlashes mod + src_basename = OsPath.dropExtension $ Strict.expectJust "mkStubPaths" + (ml_hs_file_ location) stub_basename0 - | Just dir <- stubdir = dir mod_basename + | Strict.Just dir <- stubdir = dir mod_basename | otherwise = src_basename - stub_basename = stub_basename0 ++ "_stub" + stub_basename = stub_basename0 `mappend` unsafeEncodeUtf "_stub" in - stub_basename <.> "h" + stub_basename <.> unsafeEncodeUtf "h" -- ----------------------------------------------------------------------------- -- findLinkable isn't related to the other stuff in here, ===================================== compiler/GHC/Unit/Finder/Types.hs ===================================== @@ -9,6 +9,8 @@ where import GHC.Prelude import GHC.Unit +import GHC.Data.OsPath +import qualified GHC.Data.Strict as Strict import qualified Data.Map as M import GHC.Fingerprint import GHC.Platform.Ways @@ -31,7 +33,7 @@ data FinderCache = FinderCache { fcModuleCache :: (IORef FinderCacheState) data InstalledFindResult = InstalledFound ModLocation InstalledModule | InstalledNoPackage UnitId - | InstalledNotFound [FilePath] (Maybe UnitId) + | InstalledNotFound [OsPath] (Maybe UnitId) -- | The result of searching for an imported module. -- @@ -70,7 +72,7 @@ data FindResult -- -- Should be taken from 'DynFlags' via 'initFinderOpts'. data FinderOpts = FinderOpts - { finder_importPaths :: [FilePath] + { finder_importPaths :: [OsPath] -- ^ Where are we allowed to look for Modules and Source files , finder_lookupHomeInterfaces :: Bool -- ^ When looking up a home module: @@ -88,17 +90,17 @@ data FinderOpts = FinderOpts , finder_enableSuggestions :: Bool -- ^ If we encounter unknown modules, should we suggest modules -- that have a similar name. - , finder_workingDirectory :: Maybe FilePath + , finder_workingDirectory :: Strict.Maybe OsPath , finder_thisPackageName :: Maybe FastString , finder_hiddenModules :: Set.Set ModuleName , finder_reexportedModules :: Set.Set ModuleName - , finder_hieDir :: Maybe FilePath - , finder_hieSuf :: String - , finder_hiDir :: Maybe FilePath - , finder_hiSuf :: String - , finder_dynHiSuf :: String - , finder_objectDir :: Maybe FilePath - , finder_objectSuf :: String - , finder_dynObjectSuf :: String - , finder_stubDir :: Maybe FilePath + , finder_hieDir :: Strict.Maybe OsPath + , finder_hieSuf :: OsString + , finder_hiDir :: Strict.Maybe OsPath + , finder_hiSuf :: OsString + , finder_dynHiSuf :: OsString + , finder_objectDir :: Strict.Maybe OsPath + , finder_objectSuf :: OsString + , finder_dynObjectSuf :: OsString + , finder_stubDir :: Strict.Maybe OsPath } deriving Show ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -7,10 +7,19 @@ module GHC.Unit.Module.Location , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , ml_hs_file + , ml_hi_file + , ml_dyn_hi_file + , ml_obj_file + , ml_dyn_obj_file + , ml_hie_file ) where import GHC.Prelude + +import GHC.Data.OsPath +import qualified GHC.Data.Strict as Strict import GHC.Unit.Types import GHC.Utils.Outputable @@ -39,30 +48,30 @@ import GHC.Utils.Outputable data ModLocation = ModLocation { - ml_hs_file :: Maybe FilePath, + ml_hs_file_ :: Strict.Maybe OsPath, -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file_ :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file_ :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file_ :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file_ :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file_ :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -71,8 +80,8 @@ instance Outputable ModLocation where ppr = text . show -- | Add the @-boot@ suffix to .hs, .hi and .o files -addBootSuffix :: FilePath -> FilePath -addBootSuffix path = path ++ "-boot" +addBootSuffix :: OsPath -> OsPath +addBootSuffix path = path `mappend` unsafeEncodeUtf "-boot" -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath @@ -82,7 +91,7 @@ removeBootSuffix [] = error "removeBootSuffix: no -boot suffix" -- | Add the @-boot@ suffix if the @Bool@ argument is @True@ -addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath +addBootSuffix_maybe :: IsBootInterface -> OsPath -> OsPath addBootSuffix_maybe is_boot path = case is_boot of IsBoot -> addBootSuffix path NotBoot -> path @@ -95,22 +104,42 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of -- | Add the @-boot@ suffix to all file paths associated with the module addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn - = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + = locn { ml_hs_file_ = fmap addBootSuffix (ml_hs_file_ locn) + , ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file_ = addBootSuffix (ml_hi_file_ locn) + , ml_dyn_hi_file_ = addBootSuffix (ml_dyn_hi_file_ locn) + , ml_obj_file_ = addBootSuffix (ml_obj_file_ locn) + , ml_dyn_obj_file_ = addBootSuffix (ml_dyn_obj_file_ locn) + , ml_hie_file_ = addBootSuffix (ml_hie_file_ locn) } +-- ---------------------------------------------------------------------------- +-- Helpers for backwards compatibility +-- ---------------------------------------------------------------------------- + +ml_hs_file :: ModLocation -> Maybe FilePath +ml_hs_file = fmap unsafeDecodeUtf . Strict.toLazy . ml_hs_file_ + +ml_hi_file :: ModLocation -> FilePath +ml_hi_file = unsafeDecodeUtf . ml_hi_file_ + +ml_dyn_hi_file :: ModLocation -> FilePath +ml_dyn_hi_file = unsafeDecodeUtf . ml_dyn_hi_file_ + +ml_obj_file :: ModLocation -> FilePath +ml_obj_file = unsafeDecodeUtf . ml_obj_file_ + +ml_dyn_obj_file :: ModLocation -> FilePath +ml_dyn_obj_file = unsafeDecodeUtf . ml_dyn_obj_file_ +ml_hie_file :: ModLocation -> FilePath +ml_hie_file = unsafeDecodeUtf . ml_hie_file_ ===================================== compiler/ghc.cabal.in ===================================== @@ -428,6 +428,7 @@ Library GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList + GHC.Data.OsPath GHC.Data.Pair GHC.Data.SmallArray GHC.Data.Stream ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -69,6 +69,7 @@ GHC.Data.List.Infinite GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList +GHC.Data.OsPath GHC.Data.Pair GHC.Data.Strict GHC.Data.StringBuffer ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -70,6 +70,7 @@ GHC.Data.List.Infinite GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList +GHC.Data.OsPath GHC.Data.Pair GHC.Data.Strict GHC.Data.StringBuffer ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 1ef6c187b31f85dfd7133b150b211ec9140cc84a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcd026a7f2979797ef2fffae41aa352b0034b6f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcd026a7f2979797ef2fffae41aa352b0034b6f1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 18:48:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 14:48:00 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Replace `SizedSeq` with `FlatBag` for flattened structure Message-ID: <660ef5e07b503_3f7027440c00864c9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 8 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/ghc.cabal.in - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -71,9 +71,9 @@ bcoFreeNames bco where bco_refs (UnlinkedBCO _ _ _ _ nonptrs ptrs) = unionManyUniqDSets ( - mkUniqDSet [ n | BCOPtrName n <- ssElts ptrs ] : - mkUniqDSet [ n | BCONPtrItbl n <- ssElts nonptrs ] : - map bco_refs [ bco | BCOPtrBCO bco <- ssElts ptrs ] + mkUniqDSet [ n | BCOPtrName n <- elemsFlatBag ptrs ] : + mkUniqDSet [ n | BCONPtrItbl n <- elemsFlatBag nonptrs ] : + map bco_refs [ bco | BCOPtrBCO bco <- elemsFlatBag ptrs ] ) -- ----------------------------------------------------------------------------- @@ -215,7 +215,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm let asm_insns = ssElts final_insns insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns bitmap_arr = mkBitmapArray bsize bitmap - ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr final_lits final_ptrs + ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive -- objects, since they might get run too early. Disable this until ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,10 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0) - ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0) + lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeSS lits0)-1) lits) + (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -18,12 +18,13 @@ module GHC.ByteCode.Types , CgBreakInfo(..) , ModBreaks (..), BreakIndex, emptyModBreaks , CCostCentre + , FlatBag, sizeFlatBag, fromSizedSeq, elemsFlatBag ) where import GHC.Prelude import GHC.Data.FastString -import GHC.Data.SizedSeq +import GHC.Data.FlatBag import GHC.Types.Name import GHC.Types.Name.Env import GHC.Utils.Outputable @@ -154,8 +155,8 @@ data UnlinkedBCO unlinkedBCOArity :: {-# UNPACK #-} !Int, unlinkedBCOInstrs :: !(UArray Int Word16), -- insns unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap - unlinkedBCOLits :: !(SizedSeq BCONPtr), -- non-ptrs - unlinkedBCOPtrs :: !(SizedSeq BCOPtr) -- ptrs + unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs + unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } instance NFData UnlinkedBCO where @@ -210,8 +211,8 @@ seqCgBreakInfo CgBreakInfo{..} = instance Outputable UnlinkedBCO where ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs) = sep [text "BCO", ppr nm, text "with", - ppr (sizeSS lits), text "lits", - ppr (sizeSS ptrs), text "ptrs" ] + ppr (sizeFlatBag lits), text "lits", + ppr (sizeFlatBag ptrs), text "ptrs" ] instance Outputable CgBreakInfo where ppr info = text "CgBreakInfo" <+> ===================================== compiler/GHC/Data/FlatBag.hs ===================================== @@ -0,0 +1,129 @@ +{-# LANGUAGE UnboxedTuples #-} +module GHC.Data.FlatBag + ( FlatBag + , emptyFlatBag + , unitFlatBag + , sizeFlatBag + , elemsFlatBag + , mappendFlatBag + -- * Construction + , fromList + , fromSizedSeq + ) where + +import GHC.Prelude + +import GHC.Data.SizedSeq (SizedSeq, ssElts, sizeSS) + +import Control.DeepSeq + +import GHC.Data.SmallArray + +-- | Store elements in a flattened representation. +-- +-- A 'FlatBag' is a data structure that stores an ordered list of elements +-- in a flat structure, avoiding the overhead of a linked list. +-- Use this data structure, if the code requires the following properties: +-- +-- * Elements are stored in a long-lived object, and benefit from a flattened +-- representation. +-- * The 'FlatBag' will be traversed but not extended or filtered. +-- * The number of elements should be known. +-- * Sharing of the empty case improves memory behaviour. +-- +-- A 'FlagBag' aims to have as little overhead as possible to store its elements. +-- To achieve that, it distinguishes between the empty case, singleton, tuple +-- and general case. +-- Thus, we only pay for the additional three words of an 'Array' if we have at least +-- three elements. +data FlatBag a + = EmptyFlatBag + | UnitFlatBag !a + | TupleFlatBag !a !a + | FlatBag {-# UNPACK #-} !(SmallArray a) + +instance Functor FlatBag where + fmap _ EmptyFlatBag = EmptyFlatBag + fmap f (UnitFlatBag a) = UnitFlatBag $ f a + fmap f (TupleFlatBag a b) = TupleFlatBag (f a) (f b) + fmap f (FlatBag e) = FlatBag $ mapSmallArray f e + +instance Foldable FlatBag where + foldMap _ EmptyFlatBag = mempty + foldMap f (UnitFlatBag a) = f a + foldMap f (TupleFlatBag a b) = f a `mappend` f b + foldMap f (FlatBag arr) = foldMapSmallArray f arr + + length = fromIntegral . sizeFlatBag + +instance Traversable FlatBag where + traverse _ EmptyFlatBag = pure EmptyFlatBag + traverse f (UnitFlatBag a) = UnitFlatBag <$> f a + traverse f (TupleFlatBag a b) = TupleFlatBag <$> f a <*> f b + traverse f fl@(FlatBag arr) = fromList (fromIntegral $ sizeofSmallArray arr) <$> traverse f (elemsFlatBag fl) + +instance NFData a => NFData (FlatBag a) where + rnf EmptyFlatBag = () + rnf (UnitFlatBag a) = rnf a + rnf (TupleFlatBag a b) = rnf a `seq` rnf b + rnf (FlatBag arr) = rnfSmallArray arr + +-- | Create an empty 'FlatBag'. +-- +-- The empty 'FlatBag' is shared over all instances. +emptyFlatBag :: FlatBag a +emptyFlatBag = EmptyFlatBag + +-- | Create a singleton 'FlatBag'. +unitFlatBag :: a -> FlatBag a +unitFlatBag = UnitFlatBag + +-- | Calculate the size of +sizeFlatBag :: FlatBag a -> Word +sizeFlatBag EmptyFlatBag = 0 +sizeFlatBag UnitFlatBag{} = 1 +sizeFlatBag TupleFlatBag{} = 2 +sizeFlatBag (FlatBag arr) = fromIntegral $ sizeofSmallArray arr + +-- | Get all elements that are stored in the 'FlatBag'. +elemsFlatBag :: FlatBag a -> [a] +elemsFlatBag EmptyFlatBag = [] +elemsFlatBag (UnitFlatBag a) = [a] +elemsFlatBag (TupleFlatBag a b) = [a, b] +elemsFlatBag (FlatBag arr) = + [indexSmallArray arr i | i <- [0 .. sizeofSmallArray arr - 1]] + +-- | Combine two 'FlatBag's. +-- +-- The new 'FlatBag' contains all elements from both 'FlatBag's. +-- +-- If one of the 'FlatBag's is empty, the old 'FlatBag' is reused. +mappendFlatBag :: FlatBag a -> FlatBag a -> FlatBag a +mappendFlatBag EmptyFlatBag b = b +mappendFlatBag a EmptyFlatBag = a +mappendFlatBag (UnitFlatBag a) (UnitFlatBag b) = TupleFlatBag a b +mappendFlatBag a b = + fromList (sizeFlatBag a + sizeFlatBag b) + (elemsFlatBag a ++ elemsFlatBag b) + +-- | Store the list in a flattened memory representation, avoiding the memory overhead +-- of a linked list. +-- +-- The size 'n' needs to be smaller or equal to the length of the list. +-- If it is smaller than the length of the list, overflowing elements are +-- discarded. It is undefined behaviour to set 'n' to be bigger than the +-- length of the list. +fromList :: Word -> [a] -> FlatBag a +fromList n elts = + case elts of + [] -> EmptyFlatBag + [a] -> UnitFlatBag a + [a, b] -> TupleFlatBag a b + xs -> + FlatBag (listToArray (fromIntegral n) fst snd (zip [0..] xs)) + +-- | Convert a 'SizedSeq' into its flattened representation. +-- A 'FlatBag a' is more memory efficient than '[a]', if no further modification +-- is necessary. +fromSizedSeq :: SizedSeq a -> FlatBag a +fromSizedSeq s = fromList (sizeSS s) (ssElts s) ===================================== compiler/GHC/Data/SmallArray.hs ===================================== @@ -11,13 +11,18 @@ module GHC.Data.SmallArray , freezeSmallArray , unsafeFreezeSmallArray , indexSmallArray + , sizeofSmallArray , listToArray + , mapSmallArray + , foldMapSmallArray + , rnfSmallArray ) where import GHC.Exts import GHC.Prelude import GHC.ST +import Control.DeepSeq data SmallArray a = SmallArray (SmallArray# a) @@ -64,6 +69,14 @@ unsafeFreezeSmallArray (SmallMutableArray ma) s = case unsafeFreezeSmallArray# ma s of (# s', a #) -> (# s', SmallArray a #) +-- | Get the size of a 'SmallArray' +sizeofSmallArray + :: SmallArray a + -> Int +{-# INLINE sizeofSmallArray #-} +sizeofSmallArray (SmallArray sa#) = + case sizeofSmallArray# sa# of + s -> I# s -- | Index a small-array (no bounds checking!) indexSmallArray @@ -71,9 +84,51 @@ indexSmallArray -> Int -- ^ index -> a {-# INLINE indexSmallArray #-} -indexSmallArray (SmallArray sa#) (I# i) = case indexSmallArray# sa# i of - (# v #) -> v +indexSmallArray (SmallArray sa#) (I# i) = + case indexSmallArray# sa# i of + (# v #) -> v +-- | Map a function over the elements of a 'SmallArray' +-- +mapSmallArray :: (a -> b) -> SmallArray a -> SmallArray b +{-# INLINE mapSmallArray #-} +mapSmallArray f sa = runST $ ST $ \s -> + let + n = sizeofSmallArray sa + go !i saMut# state# + | i < n = + let + a = indexSmallArray sa i + newState# = writeSmallArray saMut# i (f a) state# + in + go (i + 1) saMut# newState# + | otherwise = state# + in + case newSmallArray n (error "SmallArray: internal error, uninitialised elements") s of + (# s', mutArr #) -> + case go 0 mutArr s' of + s'' -> unsafeFreezeSmallArray mutArr s'' + +-- | Fold the values of a 'SmallArray' into a 'Monoid m' of choice +foldMapSmallArray :: Monoid m => (a -> m) -> SmallArray a -> m +{-# INLINE foldMapSmallArray #-} +foldMapSmallArray f sa = go 0 + where + n = sizeofSmallArray sa + go i + | i < n = f (indexSmallArray sa i) `mappend` go (i + 1) + | otherwise = mempty + +-- | Force the elements of the given 'SmallArray' +-- +rnfSmallArray :: NFData a => SmallArray a -> () +{-# INLINE rnfSmallArray #-} +rnfSmallArray sa = go 0 + where + n = sizeofSmallArray sa + go !i + | i < n = rnf (indexSmallArray sa i) `seq` go (i + 1) + | otherwise = () -- | Convert a list into an array. listToArray :: Int -> (e -> Int) -> (e -> a) -> [e] -> SmallArray a ===================================== compiler/ghc.cabal.in ===================================== @@ -414,6 +414,7 @@ Library GHC.Data.FastString GHC.Data.FastString.Env GHC.Data.FiniteMap + GHC.Data.FlatBag GHC.Data.Graph.Base GHC.Data.Graph.Color GHC.Data.Graph.Collapse ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -63,6 +63,7 @@ GHC.Data.FastMutInt GHC.Data.FastString GHC.Data.FastString.Env GHC.Data.FiniteMap +GHC.Data.FlatBag GHC.Data.Graph.Directed GHC.Data.Graph.UnVar GHC.Data.List.Infinite @@ -70,6 +71,7 @@ GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList GHC.Data.Pair +GHC.Data.SmallArray GHC.Data.Strict GHC.Data.StringBuffer GHC.Data.TrieMap ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -64,6 +64,7 @@ GHC.Data.FastMutInt GHC.Data.FastString GHC.Data.FastString.Env GHC.Data.FiniteMap +GHC.Data.FlatBag GHC.Data.Graph.Directed GHC.Data.Graph.UnVar GHC.Data.List.Infinite @@ -71,6 +72,7 @@ GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList GHC.Data.Pair +GHC.Data.SmallArray GHC.Data.Strict GHC.Data.StringBuffer GHC.Data.TrieMap View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c4a96862081f03e2946a2ed7e80c108f06205a1...82cfe10c8c3ec68e1b054e2d6b88e1a8830c60bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c4a96862081f03e2946a2ed7e80c108f06205a1...82cfe10c8c3ec68e1b054e2d6b88e1a8830c60bf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 18:48:34 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 14:48:34 -0400 Subject: [Git][ghc/ghc][master] Change how invisible patterns represented in haskell syntax and TH AST (#24557) Message-ID: <660ef602bdf1e_3f70275a8e30897f5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36a75b80ebe592f582f3f349e8c73b8293d49ed1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36a75b80ebe592f582f3f349e8c73b8293d49ed1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 18:49:19 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 14:49:19 -0400 Subject: [Git][ghc/ghc][master] Fix off by one error in seekBinNoExpand and seekBin Message-ID: <660ef62f2b31_3f70277b3d3893635@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 1 changed file: - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -243,15 +243,18 @@ tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) seekBin :: BinHandle -> Bin a -> IO () seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | SeekBin but without calling expandBin +-- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- by 'Bin a'. +-- This operation may 'panic', if the pointer location is out of bounds of the +-- buffer of 'BinHandle'. seekBinNoExpand :: BinHandle -> Bin a -> IO () seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r - if (p >= sz) + if (p > sz) then panic "seekBinNoExpand: seek out of range" else writeFastMutInt ix_r p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/28009fbc26e4aca7a3b05cedb60c5c9baa31223d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/28009fbc26e4aca7a3b05cedb60c5c9baa31223d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 19:19:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 15:19:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Replace `SizedSeq` with `FlatBag` for flattened structure Message-ID: <660efd5189c5e_3f7027bfdd301003a3@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 367b9b71 by Ben Gamari at 2024-04-04T15:19:35-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 94543adb by Alan Zimmerman at 2024-04-04T15:19:36-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Deriv/Functor.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fc6495586eeac7f975db9219a861119561c235ad...94543adb99830343aa651973697a36342450cee5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fc6495586eeac7f975db9219a861119561c235ad...94543adb99830343aa651973697a36342450cee5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 20:36:16 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Thu, 04 Apr 2024 16:36:16 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-rec-dotdot Message-ID: <660f0f4079b57_3f702715071241108bb@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-rec-dotdot at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-rec-dotdot You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 4 22:20:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 18:20:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: compiler: Allow more types in GHCForeignImportPrim Message-ID: <660f27a75edc2_3f702721b0ce011934e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f4a1d762 by Ben Gamari at 2024-04-04T18:20:01-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - c52eb51a by Alan Zimmerman at 2024-04-04T18:20:02-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/ThToHs.hs - testsuite/tests/ffi/should_fail/ccfail001.stderr - + testsuite/tests/ffi/should_run/T24598.hs - + testsuite/tests/ffi/should_run/T24598.stdout - + testsuite/tests/ffi/should_run/T24598_cmm.cmm - + testsuite/tests/ffi/should_run/T24598b.hs - + testsuite/tests/ffi/should_run/T24598b.stdout - + testsuite/tests/ffi/should_run/T24598b_cmm.cmm - + testsuite/tests/ffi/should_run/T24598c.hs - + testsuite/tests/ffi/should_run/T24598c.stdout - + testsuite/tests/ffi/should_run/T24598c_cmm.cmm - testsuite/tests/ffi/should_run/all.T - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1131,10 +1131,10 @@ type instance XForeignExport GhcTc = Coercion type instance XXForeignDecl (GhcPass _) = DataConCantHappen -type instance XCImport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCImport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignImport (GhcPass _) = DataConCantHappen -type instance XCExport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCExport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignExport (GhcPass _) = DataConCantHappen -- pretty printing of foreign declarations @@ -1399,6 +1399,6 @@ type instance Anno (WarnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (AnnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (RoleAnnotDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (Maybe Role) = EpAnnCO -type instance Anno CCallConv = SrcSpan -type instance Anno Safety = SrcSpan -type instance Anno CExportSpec = SrcSpan +type instance Anno CCallConv = EpaLocation +type instance Anno Safety = EpaLocation +type instance Anno CExportSpec = EpaLocation ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2095,15 +2095,15 @@ instance ToHie (LocatedA (ForeignDecl GhcRn)) where instance ToHie (ForeignImport GhcRn) where toHie (CImport (L c _) (L a _) (L b _) _ _) = concatM $ - [ locOnly a - , locOnly b - , locOnly c + [ locOnlyE a + , locOnlyE b + , locOnlyE c ] instance ToHie (ForeignExport GhcRn) where toHie (CExport (L b _) (L a _)) = concatM $ - [ locOnly a - , locOnly b + [ locOnlyE a + , locOnlyE b ] instance ToHie (LocatedA (WarnDecls GhcRn)) where ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -533,6 +533,10 @@ locOnly (RealSrcSpan span _) = do pure [Node e span []] locOnly _ = pure [] +locOnlyE :: Monad m => EpaLocation -> ReaderT NodeOrigin m [HieAST a] +locOnlyE (EpaSpan s) = locOnly s +locOnlyE _ = pure [] + mkScope :: (HasLoc a) => a -> Scope mkScope a = case getHasLoc a of (RealSrcSpan sp _) -> LocalScope sp ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -39,6 +39,7 @@ module GHC.Parser.Annotation ( -- ** Annotations in 'GenLocated' LocatedA, LocatedL, LocatedC, LocatedN, LocatedAn, LocatedP, SrcSpanAnnA, SrcSpanAnnL, SrcSpanAnnP, SrcSpanAnnC, SrcSpanAnnN, + LocatedE, -- ** Annotation data types used in 'GenLocated' @@ -644,6 +645,8 @@ type SrcSpanAnnL = EpAnn AnnList type SrcSpanAnnP = EpAnn AnnPragma type SrcSpanAnnC = EpAnn AnnContext +type LocatedE = GenLocated EpaLocation + -- | General representation of a 'GenLocated' type carrying a -- parameterised annotation type. type LocatedAn an = GenLocated (EpAnn an) @@ -1049,9 +1052,12 @@ reLoc (L la a) = L (noAnnSrcSpan $ locA (L la a) ) a class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e -instance HasAnnotation (SrcSpan) where +instance HasAnnotation SrcSpan where noAnnSrcSpan l = l +instance HasAnnotation EpaLocation where + noAnnSrcSpan l = EpaSpan l + instance (NoAnn ann) => HasAnnotation (EpAnn ann) where noAnnSrcSpan l = EpAnn (spanAsAnchor l) noAnn emptyComments @@ -1452,6 +1458,10 @@ instance (Outputable a, OutputableBndr e) pprInfixOcc = pprInfixOcc . unLoc pprPrefixOcc = pprPrefixOcc . unLoc +instance (Outputable e) + => Outputable (GenLocated EpaLocation e) where + ppr = pprLocated + instance Outputable ParenType where ppr t = text (show t) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2766,7 +2766,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- name (cf section 8.5.1 in Haskell 2010 report). mkCImport = do let e = unpackFS entity - case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc esrc) of + case parseCImport (reLoc cconv) (reLoc safety) (mkExtName (unLoc v)) e (L loc esrc) of Nothing -> addFatalError $ mkPlainErrorMsgEnvelope loc $ PsErrMalformedEntityString Just importSpec -> return importSpec @@ -2782,7 +2782,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = then mkExtName (unLoc v) else entity funcTarget = CFunction (StaticTarget esrc entity' Nothing True) - importSpec = CImport (L loc esrc) cconv safety Nothing funcTarget + importSpec = CImport (L (l2l loc) esrc) (reLoc cconv) (reLoc safety) Nothing funcTarget returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport { fd_i_ext = ann @@ -2796,7 +2796,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- the string "foo" is ambiguous: either a header or a C identifier. The -- C identifier case comes first in the alternatives below, so we pick -- that one. -parseCImport :: Located CCallConv -> Located Safety -> FastString -> String +parseCImport :: LocatedE CCallConv -> LocatedE Safety -> FastString -> String -> Located SourceText -> Maybe (ForeignImport (GhcPass p)) parseCImport cconv safety nm str sourceText = @@ -2826,7 +2826,7 @@ parseCImport cconv safety nm str sourceText = | id_char c -> pfail _ -> return () - mk h n = CImport sourceText cconv safety h n + mk h n = CImport (reLoc sourceText) (reLoc cconv) (reLoc safety) h n hdr_char c = not (isSpace c) -- header files are filenames, which can contain @@ -2861,7 +2861,7 @@ mkExport :: Located CCallConv mkExport (L lc cconv) (L le (StringLiteral esrc entity _), v, ty) = return $ \ann -> ForD noExtField $ ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty - , fd_fe = CExport (L le esrc) (L lc (CExportStatic esrc entity' cconv)) } + , fd_fe = CExport (L (l2l le) esrc) (L (l2l lc) (CExportStatic esrc entity' cconv)) } where entity' | nullFS entity = mkExtName (unLoc v) | otherwise = entity ===================================== compiler/GHC/Tc/Gen/Foreign.hs ===================================== @@ -84,7 +84,6 @@ import Control.Monad.Trans.Writer.CPS import Control.Monad.Trans.Class ( lift ) import Data.Maybe (isJust) -import GHC.Types.RepType (tyConPrimRep) import GHC.Builtin.Types (unitTyCon) -- Defines a binding @@ -737,7 +736,6 @@ marshalablePrimTyCon tc = isPrimTyCon tc && not (isLiftedTypeKind (tyConResKind marshalableTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledReason marshalableTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | otherwise = boxedMarshalableTyCon tc @@ -772,7 +770,6 @@ legalFIPrimResultTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledRe -- types and also unboxed tuple and sum result types. legalFIPrimResultTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | isUnboxedTupleTyCon tc || isUnboxedSumTyCon tc @@ -786,13 +783,3 @@ validIfUnliftedFFITypes dflags | xopt LangExt.UnliftedFFITypes dflags = IsValid | otherwise = NotValid UnliftedFFITypesNeeded -{- -Note [Marshalling void] -~~~~~~~~~~~~~~~~~~~~~~~ -We don't treat State# (whose PrimRep is VoidRep) as marshalable. -In turn that means you can't write - foreign import foo :: Int -> State# RealWorld - -Reason: the back end falls over with panic "primRepHint:VoidRep"; - and there is no compelling reason to permit it --} ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -799,7 +799,8 @@ cvt_fundep (TH.FunDep xs ys) = do { xs' <- mapM tNameN xs cvtForD :: Foreign -> CvtM (ForeignDecl GhcPs) cvtForD (ImportF callconv safety from nm ty) = - do { l <- getL + do { ls <- getL + ; let l = l2l ls ; if -- the prim and javascript calling conventions do not support headers -- and are inserted verbatim, analogous to mkImport in GHC.Parser.PostProcess | callconv == TH.Prim || callconv == TH.JavaScript @@ -809,7 +810,7 @@ cvtForD (ImportF callconv safety from nm ty) = True))) | Just impspec <- parseCImport (L l (cvt_conv callconv)) (L l safety') (mkFastString (TH.nameBase nm)) - from (L l $ quotedSourceText from) + from (L ls $ quotedSourceText from) -> mk_imp impspec | otherwise -> failWith $ InvalidCCallImpent from } @@ -831,7 +832,8 @@ cvtForD (ImportF callconv safety from nm ty) = cvtForD (ExportF callconv as nm ty) = do { nm' <- vNameN nm ; ty' <- cvtSigType ty - ; l <- getL + ; ls <- getL + ; let l = l2l ls ; let astxt = mkFastString as ; let e = CExport (L l (SourceText astxt)) (L l (CExportStatic (SourceText astxt) astxt ===================================== testsuite/tests/ffi/should_fail/ccfail001.stderr ===================================== @@ -1,6 +1,8 @@ -ccfail001.hs:10:1: error: [GHC-89401] +ccfail001.hs:10:1: error: [GHC-10964] • Unacceptable result type in foreign declaration: ‘State# RealWorld’ cannot be marshalled in a foreign call + UnliftedFFITypes is required to marshal unlifted types • When checking declaration: foreign import ccall safe foo :: Int -> State# RealWorld + Suggested fix: Perhaps you intended to use UnliftedFFITypes ===================================== testsuite/tests/ffi/should_run/T24598.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in results correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello >>= print + +hello :: IO Int +hello = IO $ \s -> case hello# s of (# s', n# #) -> (# s', I# n# #) ===================================== testsuite/tests/ffi/should_run/T24598.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello() { + return (42); +} ===================================== testsuite/tests/ffi/should_run/T24598b.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello 21 >>= print + +hello :: Int -> IO Int +hello (I# n#) = IO $ \s -> + case hello# n# s of (# s', n# #) -> (# s', I# n# #) + ===================================== testsuite/tests/ffi/should_run/T24598b.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598b_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello(W_ n) { + return (2*n); +} ===================================== testsuite/tests/ffi/should_run/T24598c.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> State# RealWorld + +main :: IO () +main = hello + +hello :: IO () +hello = IO $ \s -> + case hello# s of s' -> (# s', () #) + ===================================== testsuite/tests/ffi/should_run/T24598c.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/ffi/should_run/T24598c_cmm.cmm ===================================== @@ -0,0 +1,15 @@ +#include "Cmm.h" + +#if !defined(UnregisterisedCompiler) +import CLOSURE test_str; +#endif + +section "data" { + test_str: bits8[] "hello"; +} + +hello() { + CInt r; + (r) = ccall puts(test_str "ptr"); + return (); +} ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -268,3 +268,7 @@ test('T24314', # libffi-wasm doesn't support more than 4 args yet when(arch('wasm32'), skip)], compile_and_run, ['T24314_c.c']) + +test('T24598', req_cmm, compile_and_run, ['T24598_cmm.cmm']) +test('T24598b', req_cmm, compile_and_run, ['T24598b_cmm.cmm']) +test('T24598c', req_cmm, compile_and_run, ['T24598c_cmm.cmm']) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -738,9 +738,9 @@ printStringAtAAC capture (EpaDelta d cs) s = do -- --------------------------------------------------------------------- -markExternalSourceText :: (Monad m, Monoid w) => SrcSpan -> SourceText -> String -> EP w m () -markExternalSourceText l NoSourceText txt = printStringAtRs (realSrcSpan l) txt >> return () -markExternalSourceText l (SourceText txt) _ = printStringAtRs (realSrcSpan l) (unpackFS txt) >> return () +markExternalSourceTextE :: (Monad m, Monoid w) => EpaLocation -> SourceText -> String -> EP w m EpaLocation +markExternalSourceTextE l NoSourceText txt = printStringAtAA l txt +markExternalSourceTextE l (SourceText txt) _ = printStringAtAA l (unpackFS txt) -- --------------------------------------------------------------------- @@ -1587,6 +1587,15 @@ instance (ExactPrint a) => ExactPrint (Located a) where exact (L l a) = L l <$> markAnnotated a +instance (ExactPrint a) => ExactPrint (LocatedE a) where + getAnnotationEntry (L l _) = Entry l [] emptyComments NoFlushComments CanUpdateAnchorOnly + setAnnotationAnchor (L _ a) anc _ts _cs = L anc a + + exact (L la a) = do + debugM $ "LocatedE a:la loc=" ++ show (ss2range $ locA la) + a' <- markAnnotated a + return (L la a') + instance (ExactPrint a) => ExactPrint (LocatedA a) where getAnnotationEntry = entryFromLocatedA setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs @@ -2009,11 +2018,15 @@ instance ExactPrint (ForeignDecl GhcPs) where instance ExactPrint (ForeignImport GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CImport (L ls src) cconv safety@(L ll _) mh imp) = do + exact (CImport (L ls src) cconv safety@(L l _) mh imp) = do cconv' <- markAnnotated cconv - unless (ll == noSrcSpan) $ markAnnotated safety >> return () - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" >> return () - return (CImport (L ls src) cconv' safety mh imp) + safety' <- if notDodgyE l + then markAnnotated safety + else return safety + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CImport (L ls' src) cconv' safety' mh imp) -- --------------------------------------------------------------------- @@ -2023,8 +2036,10 @@ instance ExactPrint (ForeignExport GhcPs) where exact (CExport (L ls src) spec) = do debugM $ "CExport starting" spec' <- markAnnotated spec - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" - return (CExport (L ls src) spec') + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CExport (L ls' src) spec') -- --------------------------------------------------------------------- @@ -3240,6 +3255,12 @@ markMaybeDodgyStmts an stmts = return (an, r) else return (an, stmts) +notDodgyE :: EpaLocation -> Bool +notDodgyE anc = + case anc of + EpaSpan s -> isGoodSrcSpan s + EpaDelta{} -> True + -- --------------------------------------------------------------------- instance ExactPrint (HsPragE GhcPs) where getAnnotationEntry HsPragSCC{} = NoEntryVal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94543adb99830343aa651973697a36342450cee5...c52eb51a530ef4e6e6cf108056e87a74aecdeae1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94543adb99830343aa651973697a36342450cee5...c52eb51a530ef4e6e6cf108056e87a74aecdeae1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 01:30:46 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 21:30:46 -0400 Subject: [Git][ghc/ghc][master] compiler: Allow more types in GHCForeignImportPrim Message-ID: <660f5446d560f_1bd2a1ebe8f8351e5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 12 changed files: - compiler/GHC/Tc/Gen/Foreign.hs - testsuite/tests/ffi/should_fail/ccfail001.stderr - + testsuite/tests/ffi/should_run/T24598.hs - + testsuite/tests/ffi/should_run/T24598.stdout - + testsuite/tests/ffi/should_run/T24598_cmm.cmm - + testsuite/tests/ffi/should_run/T24598b.hs - + testsuite/tests/ffi/should_run/T24598b.stdout - + testsuite/tests/ffi/should_run/T24598b_cmm.cmm - + testsuite/tests/ffi/should_run/T24598c.hs - + testsuite/tests/ffi/should_run/T24598c.stdout - + testsuite/tests/ffi/should_run/T24598c_cmm.cmm - testsuite/tests/ffi/should_run/all.T Changes: ===================================== compiler/GHC/Tc/Gen/Foreign.hs ===================================== @@ -84,7 +84,6 @@ import Control.Monad.Trans.Writer.CPS import Control.Monad.Trans.Class ( lift ) import Data.Maybe (isJust) -import GHC.Types.RepType (tyConPrimRep) import GHC.Builtin.Types (unitTyCon) -- Defines a binding @@ -737,7 +736,6 @@ marshalablePrimTyCon tc = isPrimTyCon tc && not (isLiftedTypeKind (tyConResKind marshalableTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledReason marshalableTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | otherwise = boxedMarshalableTyCon tc @@ -772,7 +770,6 @@ legalFIPrimResultTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledRe -- types and also unboxed tuple and sum result types. legalFIPrimResultTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | isUnboxedTupleTyCon tc || isUnboxedSumTyCon tc @@ -786,13 +783,3 @@ validIfUnliftedFFITypes dflags | xopt LangExt.UnliftedFFITypes dflags = IsValid | otherwise = NotValid UnliftedFFITypesNeeded -{- -Note [Marshalling void] -~~~~~~~~~~~~~~~~~~~~~~~ -We don't treat State# (whose PrimRep is VoidRep) as marshalable. -In turn that means you can't write - foreign import foo :: Int -> State# RealWorld - -Reason: the back end falls over with panic "primRepHint:VoidRep"; - and there is no compelling reason to permit it --} ===================================== testsuite/tests/ffi/should_fail/ccfail001.stderr ===================================== @@ -1,6 +1,8 @@ -ccfail001.hs:10:1: error: [GHC-89401] +ccfail001.hs:10:1: error: [GHC-10964] • Unacceptable result type in foreign declaration: ‘State# RealWorld’ cannot be marshalled in a foreign call + UnliftedFFITypes is required to marshal unlifted types • When checking declaration: foreign import ccall safe foo :: Int -> State# RealWorld + Suggested fix: Perhaps you intended to use UnliftedFFITypes ===================================== testsuite/tests/ffi/should_run/T24598.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in results correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello >>= print + +hello :: IO Int +hello = IO $ \s -> case hello# s of (# s', n# #) -> (# s', I# n# #) ===================================== testsuite/tests/ffi/should_run/T24598.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello() { + return (42); +} ===================================== testsuite/tests/ffi/should_run/T24598b.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello 21 >>= print + +hello :: Int -> IO Int +hello (I# n#) = IO $ \s -> + case hello# n# s of (# s', n# #) -> (# s', I# n# #) + ===================================== testsuite/tests/ffi/should_run/T24598b.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598b_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello(W_ n) { + return (2*n); +} ===================================== testsuite/tests/ffi/should_run/T24598c.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> State# RealWorld + +main :: IO () +main = hello + +hello :: IO () +hello = IO $ \s -> + case hello# s of s' -> (# s', () #) + ===================================== testsuite/tests/ffi/should_run/T24598c.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/ffi/should_run/T24598c_cmm.cmm ===================================== @@ -0,0 +1,15 @@ +#include "Cmm.h" + +#if !defined(UnregisterisedCompiler) +import CLOSURE test_str; +#endif + +section "data" { + test_str: bits8[] "hello"; +} + +hello() { + CInt r; + (r) = ccall puts(test_str "ptr"); + return (); +} ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -268,3 +268,7 @@ test('T24314', # libffi-wasm doesn't support more than 4 args yet when(arch('wasm32'), skip)], compile_and_run, ['T24314_c.c']) + +test('T24598', req_cmm, compile_and_run, ['T24598_cmm.cmm']) +test('T24598b', req_cmm, compile_and_run, ['T24598b_cmm.cmm']) +test('T24598c', req_cmm, compile_and_run, ['T24598c_cmm.cmm']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b9e031b67dbc812c156a4773c0c9d293451fefa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b9e031b67dbc812c156a4773c0c9d293451fefa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 01:31:28 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 04 Apr 2024 21:31:28 -0400 Subject: [Git][ghc/ghc][master] EPA: Use EpaLocation not SrcSpan in ForeignDecls Message-ID: <660f5470948f6_1bd2a1104a1e038485@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 7 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1131,10 +1131,10 @@ type instance XForeignExport GhcTc = Coercion type instance XXForeignDecl (GhcPass _) = DataConCantHappen -type instance XCImport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCImport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignImport (GhcPass _) = DataConCantHappen -type instance XCExport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCExport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignExport (GhcPass _) = DataConCantHappen -- pretty printing of foreign declarations @@ -1399,6 +1399,6 @@ type instance Anno (WarnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (AnnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (RoleAnnotDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (Maybe Role) = EpAnnCO -type instance Anno CCallConv = SrcSpan -type instance Anno Safety = SrcSpan -type instance Anno CExportSpec = SrcSpan +type instance Anno CCallConv = EpaLocation +type instance Anno Safety = EpaLocation +type instance Anno CExportSpec = EpaLocation ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2095,15 +2095,15 @@ instance ToHie (LocatedA (ForeignDecl GhcRn)) where instance ToHie (ForeignImport GhcRn) where toHie (CImport (L c _) (L a _) (L b _) _ _) = concatM $ - [ locOnly a - , locOnly b - , locOnly c + [ locOnlyE a + , locOnlyE b + , locOnlyE c ] instance ToHie (ForeignExport GhcRn) where toHie (CExport (L b _) (L a _)) = concatM $ - [ locOnly a - , locOnly b + [ locOnlyE a + , locOnlyE b ] instance ToHie (LocatedA (WarnDecls GhcRn)) where ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -533,6 +533,10 @@ locOnly (RealSrcSpan span _) = do pure [Node e span []] locOnly _ = pure [] +locOnlyE :: Monad m => EpaLocation -> ReaderT NodeOrigin m [HieAST a] +locOnlyE (EpaSpan s) = locOnly s +locOnlyE _ = pure [] + mkScope :: (HasLoc a) => a -> Scope mkScope a = case getHasLoc a of (RealSrcSpan sp _) -> LocalScope sp ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -39,6 +39,7 @@ module GHC.Parser.Annotation ( -- ** Annotations in 'GenLocated' LocatedA, LocatedL, LocatedC, LocatedN, LocatedAn, LocatedP, SrcSpanAnnA, SrcSpanAnnL, SrcSpanAnnP, SrcSpanAnnC, SrcSpanAnnN, + LocatedE, -- ** Annotation data types used in 'GenLocated' @@ -644,6 +645,8 @@ type SrcSpanAnnL = EpAnn AnnList type SrcSpanAnnP = EpAnn AnnPragma type SrcSpanAnnC = EpAnn AnnContext +type LocatedE = GenLocated EpaLocation + -- | General representation of a 'GenLocated' type carrying a -- parameterised annotation type. type LocatedAn an = GenLocated (EpAnn an) @@ -1049,9 +1052,12 @@ reLoc (L la a) = L (noAnnSrcSpan $ locA (L la a) ) a class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e -instance HasAnnotation (SrcSpan) where +instance HasAnnotation SrcSpan where noAnnSrcSpan l = l +instance HasAnnotation EpaLocation where + noAnnSrcSpan l = EpaSpan l + instance (NoAnn ann) => HasAnnotation (EpAnn ann) where noAnnSrcSpan l = EpAnn (spanAsAnchor l) noAnn emptyComments @@ -1452,6 +1458,10 @@ instance (Outputable a, OutputableBndr e) pprInfixOcc = pprInfixOcc . unLoc pprPrefixOcc = pprPrefixOcc . unLoc +instance (Outputable e) + => Outputable (GenLocated EpaLocation e) where + ppr = pprLocated + instance Outputable ParenType where ppr t = text (show t) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2766,7 +2766,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- name (cf section 8.5.1 in Haskell 2010 report). mkCImport = do let e = unpackFS entity - case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc esrc) of + case parseCImport (reLoc cconv) (reLoc safety) (mkExtName (unLoc v)) e (L loc esrc) of Nothing -> addFatalError $ mkPlainErrorMsgEnvelope loc $ PsErrMalformedEntityString Just importSpec -> return importSpec @@ -2782,7 +2782,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = then mkExtName (unLoc v) else entity funcTarget = CFunction (StaticTarget esrc entity' Nothing True) - importSpec = CImport (L loc esrc) cconv safety Nothing funcTarget + importSpec = CImport (L (l2l loc) esrc) (reLoc cconv) (reLoc safety) Nothing funcTarget returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport { fd_i_ext = ann @@ -2796,7 +2796,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- the string "foo" is ambiguous: either a header or a C identifier. The -- C identifier case comes first in the alternatives below, so we pick -- that one. -parseCImport :: Located CCallConv -> Located Safety -> FastString -> String +parseCImport :: LocatedE CCallConv -> LocatedE Safety -> FastString -> String -> Located SourceText -> Maybe (ForeignImport (GhcPass p)) parseCImport cconv safety nm str sourceText = @@ -2826,7 +2826,7 @@ parseCImport cconv safety nm str sourceText = | id_char c -> pfail _ -> return () - mk h n = CImport sourceText cconv safety h n + mk h n = CImport (reLoc sourceText) (reLoc cconv) (reLoc safety) h n hdr_char c = not (isSpace c) -- header files are filenames, which can contain @@ -2861,7 +2861,7 @@ mkExport :: Located CCallConv mkExport (L lc cconv) (L le (StringLiteral esrc entity _), v, ty) = return $ \ann -> ForD noExtField $ ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty - , fd_fe = CExport (L le esrc) (L lc (CExportStatic esrc entity' cconv)) } + , fd_fe = CExport (L (l2l le) esrc) (L (l2l lc) (CExportStatic esrc entity' cconv)) } where entity' | nullFS entity = mkExtName (unLoc v) | otherwise = entity ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -799,7 +799,8 @@ cvt_fundep (TH.FunDep xs ys) = do { xs' <- mapM tNameN xs cvtForD :: Foreign -> CvtM (ForeignDecl GhcPs) cvtForD (ImportF callconv safety from nm ty) = - do { l <- getL + do { ls <- getL + ; let l = l2l ls ; if -- the prim and javascript calling conventions do not support headers -- and are inserted verbatim, analogous to mkImport in GHC.Parser.PostProcess | callconv == TH.Prim || callconv == TH.JavaScript @@ -809,7 +810,7 @@ cvtForD (ImportF callconv safety from nm ty) = True))) | Just impspec <- parseCImport (L l (cvt_conv callconv)) (L l safety') (mkFastString (TH.nameBase nm)) - from (L l $ quotedSourceText from) + from (L ls $ quotedSourceText from) -> mk_imp impspec | otherwise -> failWith $ InvalidCCallImpent from } @@ -831,7 +832,8 @@ cvtForD (ImportF callconv safety from nm ty) = cvtForD (ExportF callconv as nm ty) = do { nm' <- vNameN nm ; ty' <- cvtSigType ty - ; l <- getL + ; ls <- getL + ; let l = l2l ls ; let astxt = mkFastString as ; let e = CExport (L l (SourceText astxt)) (L l (CExportStatic (SourceText astxt) astxt ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -738,9 +738,9 @@ printStringAtAAC capture (EpaDelta d cs) s = do -- --------------------------------------------------------------------- -markExternalSourceText :: (Monad m, Monoid w) => SrcSpan -> SourceText -> String -> EP w m () -markExternalSourceText l NoSourceText txt = printStringAtRs (realSrcSpan l) txt >> return () -markExternalSourceText l (SourceText txt) _ = printStringAtRs (realSrcSpan l) (unpackFS txt) >> return () +markExternalSourceTextE :: (Monad m, Monoid w) => EpaLocation -> SourceText -> String -> EP w m EpaLocation +markExternalSourceTextE l NoSourceText txt = printStringAtAA l txt +markExternalSourceTextE l (SourceText txt) _ = printStringAtAA l (unpackFS txt) -- --------------------------------------------------------------------- @@ -1587,6 +1587,15 @@ instance (ExactPrint a) => ExactPrint (Located a) where exact (L l a) = L l <$> markAnnotated a +instance (ExactPrint a) => ExactPrint (LocatedE a) where + getAnnotationEntry (L l _) = Entry l [] emptyComments NoFlushComments CanUpdateAnchorOnly + setAnnotationAnchor (L _ a) anc _ts _cs = L anc a + + exact (L la a) = do + debugM $ "LocatedE a:la loc=" ++ show (ss2range $ locA la) + a' <- markAnnotated a + return (L la a') + instance (ExactPrint a) => ExactPrint (LocatedA a) where getAnnotationEntry = entryFromLocatedA setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs @@ -2009,11 +2018,15 @@ instance ExactPrint (ForeignDecl GhcPs) where instance ExactPrint (ForeignImport GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CImport (L ls src) cconv safety@(L ll _) mh imp) = do + exact (CImport (L ls src) cconv safety@(L l _) mh imp) = do cconv' <- markAnnotated cconv - unless (ll == noSrcSpan) $ markAnnotated safety >> return () - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" >> return () - return (CImport (L ls src) cconv' safety mh imp) + safety' <- if notDodgyE l + then markAnnotated safety + else return safety + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CImport (L ls' src) cconv' safety' mh imp) -- --------------------------------------------------------------------- @@ -2023,8 +2036,10 @@ instance ExactPrint (ForeignExport GhcPs) where exact (CExport (L ls src) spec) = do debugM $ "CExport starting" spec' <- markAnnotated spec - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" - return (CExport (L ls src) spec') + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CExport (L ls' src) spec') -- --------------------------------------------------------------------- @@ -3240,6 +3255,12 @@ markMaybeDodgyStmts an stmts = return (an, r) else return (an, stmts) +notDodgyE :: EpaLocation -> Bool +notDodgyE anc = + case anc of + EpaSpan s -> isGoodSrcSpan s + EpaDelta{} -> True + -- --------------------------------------------------------------------- instance ExactPrint (HsPragE GhcPs) where getAnnotationEntry HsPragSCC{} = NoEntryVal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 09:31:59 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 05 Apr 2024 05:31:59 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Remove th_hack Message-ID: <660fc50fc35af_1d9be1107393c750ac@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: d835af29 by Teo Camarasu at 2024-04-05T10:31:53+01:00 Remove th_hack This is no longer necessary now that template-haskell is no longer a stage0 package - - - - - 1 changed file: - hadrian/src/Rules/ToolArgs.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d835af29aaf96bbb0682718b9bc24e04bab14081 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d835af29aaf96bbb0682718b9bc24e04bab14081 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 09:48:28 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 05 Apr 2024 05:48:28 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] 2 commits: Make template-haskell a stage1 package Message-ID: <660fc8ec7d5cf_1d9be113ab1187919f@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 98729f73 by Teo Camarasu at 2024-04-05T10:48:17+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. In order to accomplish this we now compile stage0 packages using the boot compiler's version of template-haskell. This means that there are now two versions of template-haskell in play: the boot compiler's version, and the in-tree version. When compiling the stage1 compiler, we have to pick a version of template-haskell to use. During bootstrapping we want to use the same version as the final compiler. This forces the in-tree version. We are only able to use the internal interpreter with stage2 onwards. Yet, we could still use the external interpreter. The external interpreter runs splices in another process. Queries and results are seralised. This reduces our compatibility requirements from ABI compatibility with the internal interpreter to mere serialisation compatibility. We may compile GHC against another library to what the external interpreter is compiled against so long as it has exactly the same serialisation of template-haskell types. This opens up the strategy pursued in this patch. When compiling the stage1 compiler we vendor the template-haskell and ghc-boot-th libraries through ghc-boot and use these to define the Template Haskell interface for the external interpreter. Note that at this point we also have the template-haskell and ghc-boot-th packages in our transitive dependency closure from the boot compiler, and some packages like containers have dependencies on these to define Lift instances. Then the external interpreter should be compiled against the regular template-haskell library from the source tree. As this will have the same serialised interface as what we vendor in ghc-boot, we can then run splices. GHC stage2 is compiled as normal as well against the template-haskell library from the source tree. See Note [Bootstrapping Template Haskell] Resolves #23536 - - - - - 36b83a79 by Teo Camarasu at 2024-04-05T10:48:17+01:00 Remove th_hack This is no longer necessary now that template-haskell is no longer a stage0 package - - - - - 11 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,108 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- Template Haskell requires special attention when compiling GHC. +-- The implementation of the Template Haskell set of features requires tight +-- coupling between the compiler and the `template-haskell` library. +-- This complicates the bootstrapping story as compatibility constraints are +-- placed on the version of `template-haskell` used to compile GHC during a +-- particular stage and the version bundled with it. +-- +-- These constraints can be divided by the features they are used to implement, +-- namely running splices either directly or via the external interpreter, and +-- desugaring bracket syntax. +-- +-- (C1) Executing splices within the compiler: In order to execute a splice +-- within the compiler, we must be able to compile and load code built against +-- the same version of the `template-haskell` library as the compiler. This +-- is an ABI compatibility constraint between the `template-haskell` version of +-- the compiler and the splice. +-- (C2) Executing splices through the external interpreter: In order to execute +-- a splice via the external interpreter, we serialise bytecode, run it with the +-- external interpreter, and communicate back the result through a binary +-- serialised interface. This is a binary serialisation compatibilty constraint +-- between the `template-haskell` version of the compiler and the splice. +-- (C3) Desugaring bracket syntax: Bracket syntax is desugared by referring to a +-- special wired-in package whose package id is `template-haskell`. So for +-- instance an expression `'Just` gets desugared to something of type +-- `template-haskell:Language.Haskell.TH.Syntax.Name`. Importantly, while this +-- identifier is wired-in, the identity of the `template-haskell` package is +-- not. So for instance we can successfully use an expression like +-- `'Just :: Name` while compiling the `template-haskell` package as long as its +-- package id is set to `template-haskell` as `Name` will resolve the the local +-- identifier in the package (and the LHS and RHS will align). On the other +-- hand, if we don't set the special package id, the type of the expression will +-- be `template-haskell:...Name` while the `Name` on the RHS will resolve to the +-- local identifier and we will get a type error. So, bracket syntax assumes the +-- presence of a particular API in the `template-haskell` package, but it allows +-- +-- These constraints are ranked from strongest to weakest. They only apply if we +-- want to support the particular feature associated with them. +-- +-- The tricky case is what do to when building the bootstrapping (stage1) GHC. +-- The stage2 GHC is simpler as it can use the in-tree `template-haskell` +-- package built by the stage1 GHC. +-- +-- We should note that we cannot feasibly use the internal interpreter with a +-- stage1 GHC. This is because the stage1 GHC was compiled with the stage0 GHC, +-- which we assume is a different version. In order to run a splice that too +-- would need to be compiled with the stage0 GHC, and so would all its +-- dependencies. +-- This allows us to disregard (C1) for the stage1 case. +-- +-- In the past, we used to build the stage1 GHC and all its dependencies against +-- the in-tree `template-haskell` library. This meant that we sacrificed (C2) +-- because they are likely not serialisation compatible. We could not sacrifice +-- (C3) because dependencies of GHC (such as `containers` and +-- `template-haskell`) used bracket syntax to define `Lift` instances. This +-- meant that the interface assumed by the boot compiler to implement bracket +-- desugaring could not be modified (not even through CPP as (C1) would +-- constrain us in future stages where we do support the internal interpreter). +-- Yet, bracket syntax did work and gave us splices that desugared to code that +-- referenced the in-tree version of `template-haskell` not the one the boot +-- compiler required. So they could never be run. +-- +-- Our current strategy is to not build `template-haskell` as a stage0 package. +-- All of GHCs dependencies depend on the boot compilers version, and produce +-- runnable splices. How do we deal with the stage1 compiler's dependency on +-- `template-haskell`? There are two options. (D1) depend on the boot +-- compiler's version for stage1 and then depend on the in-tree one in stage2. +-- This violates (C1) and (C2), so we wouldn't be able to run splices at all +-- with the stage1 compiler. Additionally this would introduce quite a bit of +-- CPP into the compiler and mean we would have to stub out much of the +-- template-haskell machinery or have an unrunable compatibilty shim. Or (D2) +-- depend on the in-tree version. +-- +-- (D2) is what we implement, but it is complicated by the fact that it means we +-- practically have two versions of `template-haskell` in the dependency graph +-- of the stage1 compiler. To avoid this, we recall that we only need +-- serliasation compatibility (as per (C2)), so we can avoid a direct dependency +-- on the in-tree version by vendoring it. We choose to vendor it into the +-- `ghc-boot` package as both `lib:ghc` and `ghci` require a dependency on the +-- `template-haskell` interface as they define the two ends of the protocol. +-- This allows us to still run splices through the external interpreter. +-- +-- We should note a futher edge-case with this approach. When compiling our +-- vendored `template-haskell` library, we run afoul of (C3). The library +-- defines several `Name`s using bracket syntax. As this package doesn't claim +-- to be the wired-in package but it defines its own `Name` type, we get a type +-- discrepancy with the `Name` type from the boot compiler's `template-haskell` +-- library. Most of these are only used to define `Lift` instances, so in the +-- vendored case we simply hide them behind CPP. Yet, there is one distinct use +-- of a `Name`. We have a `Name` for the constructors of the `Multiplicity` +-- type, which are also used in the pretty-printing module. We construct these +-- manulally instead. This allows us to completely avoid using bracket syntax +-- for compiling the vendored `template-haskell` package. +-- +-- To summarise, our current approach allows us to use the external interpreter +-- to run splices and allows bracket syntax to be desugared correctly. In order +-- to implement this we vendor the `template-haskell` library into `ghc-boot` +-- and take special care to not use bracket syntax in those modules as that +-- would incorrectly produce code that uses identifiers from the boot compiler's +-- `template-haskell` library. +-- +-- See #23536. ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d835af29aaf96bbb0682718b9bc24e04bab14081...36b83a79a4ee7654a2a5cdb03d26d13f5d219328 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d835af29aaf96bbb0682718b9bc24e04bab14081...36b83a79a4ee7654a2a5cdb03d26d13f5d219328 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 09:53:59 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 05 Apr 2024 05:53:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mp-i386-fix Message-ID: <660fca372e49c_1d9be1159af8c811ab@gitlab.mail> Matthew Pickering pushed new branch wip/mp-i386-fix at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mp-i386-fix You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 10:15:25 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 05 Apr 2024 06:15:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/remove-test-file Message-ID: <660fcf3d13c25_1d9be118f4bec87624@gitlab.mail> Matthew Pickering pushed new branch wip/remove-test-file at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/remove-test-file You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 10:25:23 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 05 Apr 2024 06:25:23 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 13 commits: testsuite: Introduce template-haskell-exports test Message-ID: <660fd193c40c3_1d9be11adc5189098@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 6e0ffd02 by Rodrigo Mesquita at 2024-04-05T11:24:06+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 648e94ea by Alexis King at 2024-04-05T11:25:03+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 86f3dd38 by Rodrigo Mesquita at 2024-04-05T11:25:04+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - a409754a by Rodrigo Mesquita at 2024-04-05T11:25:04+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 785937b4 by Ben Gamari at 2024-04-05T11:25:04+01:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1a021a8a4cfe4ee06b840611d035d99191ad5ac8...785937b46351fa021eac5b7bb683b2fa38739302 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1a021a8a4cfe4ee06b840611d035d99191ad5ac8...785937b46351fa021eac5b7bb683b2fa38739302 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 10:51:54 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 05 Apr 2024 06:51:54 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Apply 5 suggestion(s) to 1 file(s) Message-ID: <660fd7ca2dfa0_1d9be11e268a4940a3@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 6fb08605 by Sebastian Graf at 2024-04-05T10:51:50+00:00 Apply 5 suggestion(s) to 1 file(s) - - - - - 1 changed file: - compiler/GHC/Tc/Gen/Splice.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2919,17 +2919,20 @@ tcGetInterp = do -- Note [Bootstrapping Template Haskell] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- -- Template Haskell requires special attention when compiling GHC. -- The implementation of the Template Haskell set of features requires tight --- coupling between the compiler and the `template-haskell` library. +-- coupling between the compiler and the `template-haskell` library: +-- on one hand, there are many known-key definitions in GHC.Builtin.Names.TH +-- pointing to the in-tree library; +-- on the other hand, the compiler needs to be compiled against parts of the in-tree TH AST +-- to enable serialisation. -- This complicates the bootstrapping story as compatibility constraints are -- placed on the version of `template-haskell` used to compile GHC during a -- particular stage and the version bundled with it. -- -- These constraints can be divided by the features they are used to implement, -- namely running splices either directly or via the external interpreter, and --- desugaring bracket syntax. +-- desugaring quotes. -- -- (C1) Executing splices within the compiler: In order to execute a splice -- within the compiler, we must be able to compile and load code built against @@ -2981,8 +2984,8 @@ tcGetInterp = do -- referenced the in-tree version of `template-haskell` not the one the boot -- compiler required. So they could never be run. -- --- Our current strategy is to not build `template-haskell` as a stage0 package. --- All of GHCs dependencies depend on the boot compilers version, and produce +-- Our current strategy is to avoid building the in-tree `template-haskell` as a stage0 package entirely. +-- All of stage1 GHCs source dependencies depend on the boot compilers version, and produce -- runnable splices. How do we deal with the stage1 compiler's dependency on -- `template-haskell`? There are two options. (D1) depend on the boot -- compiler's version for stage1 and then depend on the in-tree one in stage2. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6fb086057e726b389864a1516bf5e2e1176d47b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6fb086057e726b389864a1516bf5e2e1176d47b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 11:51:43 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 05 Apr 2024 07:51:43 -0400 Subject: [Git][ghc/ghc][wip/bump-alpine-aarch64] 178 commits: rel_eng: Update hackage docs upload scripts Message-ID: <660fe5cf8a237_180afb7a35b4268e@gitlab.mail> Matthew Pickering pushed to branch wip/bump-alpine-aarch64 at Glasgow Haskell Compiler / GHC Commits: 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/05dea0d5e29bc2b293ae770bd43be01c0d3cf830...1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/05dea0d5e29bc2b293ae770bd43be01c0d3cf830...1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 12:11:11 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 08:11:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/array-bcos Message-ID: <660fea5f18390_180afb9d55d028442@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/array-bcos at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/array-bcos You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 12:15:38 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 05 Apr 2024 08:15:38 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 59 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <660feb6a483e5_180afbbd8580300ce@gitlab.mail> Matthew Pickering pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - ed3fb50d by Fendor at 2024-04-05T13:14:59+01:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: T21839c ------------------------- - - - - - 99aa935a by Fendor at 2024-04-05T13:15:13+01:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 19 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d07b410229f3844118c4c211e9998478e0cdbc66...99aa935a7863b8b20d855b09113af1133f47179d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d07b410229f3844118c4c211e9998478e0cdbc66...99aa935a7863b8b20d855b09113af1133f47179d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 12:25:56 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 08:25:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ifacetype-deduplication Message-ID: <660fedd4d72f3_180afbda816c31940@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ifacetype-deduplication You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 12:56:50 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Fri, 05 Apr 2024 08:56:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/fix_fallthrough Message-ID: <660ff5122a381_180afb1205624374f7@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/fix_fallthrough at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/fix_fallthrough You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 13:13:35 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 09:13:35 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <660ff8ff1e2f1_180afb149c4f0462b2@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: adf68fba by Fendor at 2024-04-05T15:13:12+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do fsReaderTable <- initFastStringReaderTable nameReaderTable <- (initReadNameCachedBinary name_cache) @@ -192,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -209,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -234,7 +234,7 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Iface Binary Serialiser Order] -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable @@ -374,7 +374,7 @@ initWriteNameTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -383,7 +383,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -404,7 +404,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -428,7 +428,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -454,7 +454,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -112,9 +112,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -122,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -182,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -191,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -214,7 +214,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -233,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -261,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -277,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -335,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -346,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -39,7 +39,7 @@ computeFingerprint put_nonbinding_name a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter (Proxy @BindingName) bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Control.Monad +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -85,7 +87,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding @@ -172,70 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert typRep cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert typRep cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -254,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -278,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" + else writeFastMutInt ix_r p + +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -325,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -359,7 +399,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -375,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -396,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -418,39 +458,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -458,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -471,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -483,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -504,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -530,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -555,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -579,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -607,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1026,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1090,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1192,19 +1230,19 @@ mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReade mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb data BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } deriving (Functor) data BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } @@ -1212,7 +1250,7 @@ mkReader f = BinaryReader -- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. -- -- If no 'BinaryReader' has been configured before, this function will panic. -findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> BinHandle -> BinaryReader a +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) @@ -1222,7 +1260,7 @@ findUserDataReader query bh = -- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. -- -- If no 'BinaryWriter' has been configured before, this function will panic. -findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> BinHandle -> BinaryWriter a +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) @@ -1239,8 +1277,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1249,11 +1287,11 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_non_binding_name put_binding_name put_fs = mkWriterUserData @@ -1267,12 +1305,12 @@ newWriteState put_non_binding_name put_binding_name put_fs = -- ---------------------------------------------------------------------------- data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) , mkReaderFromTable :: SymbolTable a -> BinaryReader a } data WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int } --------------------------------------------------------- @@ -1312,14 +1350,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1328,12 +1366,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1370,34 +1408,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit c641b7349239c497cbd64a64cd21fd388f431b9f +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/adf68fbabc8b0654e324959421496a59d85deb14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/adf68fbabc8b0654e324959421496a59d85deb14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 13:39:09 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 09:39:09 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] Add deduplication table for `IfaceType` Message-ID: <660ffefde858e_180afb182a95048778@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 748bf100 by Matthew Pickering at 2024-04-05T15:38:40+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it effeiciently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 20 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - utils/haddock Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -952,13 +952,13 @@ data CoSel -- See Note [SelCo] | SelForAll -- Decomposes (forall a. co) - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) data FunSel -- See Note [SelCo] = SelMult -- Multiplicity | SelArg -- Argument of function | SelRes -- Result of function - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -121,7 +121,7 @@ toIfaceTvBndr :: TyVar -> IfaceTvBndr toIfaceTvBndr = toIfaceTvBndrX emptyVarSet toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr -toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar) +toIfaceTvBndrX fr tyvar = ( mkIfLclName (occNameFS (getOccName tyvar)) , toIfaceTypeX fr (tyVarKind tyvar) ) @@ -133,7 +133,7 @@ toIfaceIdBndr = toIfaceIdBndrX emptyVarSet toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr toIfaceIdBndrX fr covar = ( toIfaceType (idMult covar) - , occNameFS (getOccName covar) + , mkIfLclName (occNameFS (getOccName covar)) , toIfaceTypeX fr (varType covar) ) @@ -218,11 +218,11 @@ toIfaceTypeX fr (TyConApp tc tys) arity = tyConArity tc n_tys = length tys -toIfaceTyVar :: TyVar -> FastString -toIfaceTyVar = occNameFS . getOccName +toIfaceTyVar :: TyVar -> IfLclName +toIfaceTyVar = mkIfLclName . occNameFS . getOccName -toIfaceCoVar :: CoVar -> FastString -toIfaceCoVar = occNameFS . getOccName +toIfaceCoVar :: CoVar -> IfLclName +toIfaceCoVar = mkIfLclName . occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon @@ -264,7 +264,7 @@ toIfaceTyCon_name n = IfaceTyCon n info toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x -toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x +toIfaceTyLit (StrTyLit x) = IfaceStrTyLit (LexicalFastString x) toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x ---------------- @@ -296,7 +296,7 @@ toIfaceCoercionX fr co go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c) go (SubCo co) = IfaceSubCo (go co) - go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs) + go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (mkIfLclName (coaxrName co)) (map go cs) go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs) go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) @@ -433,7 +433,7 @@ toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang toIfaceLetBndr :: Id -> IfaceLetBndr -toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) +toIfaceLetBndr id = IfLetBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (idJoinPointHood id) @@ -444,7 +444,7 @@ toIfaceTopBndr :: Id -> IfaceTopBndrInfo toIfaceTopBndr id = if isExternalName name then IfGblTopBndr name - else IfLclTopBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) + else IfLclTopBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (toIfaceIdDetails (idDetails id)) where name = getName id @@ -555,7 +555,7 @@ toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfac toIfaceExpr (App f a) = toIfaceApp f [a] toIfaceExpr (Case s x ty as) | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty) - | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as) + | otherwise = IfaceCase (toIfaceExpr s) (mkIfLclName (getOccFS x)) (map toIfaceAlt as) toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e) toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co) toIfaceExpr (Tick t e) = IfaceTick (toIfaceTickish t) (toIfaceExpr e) @@ -610,7 +610,7 @@ toIfaceTopBind b = --------------------- toIfaceAlt :: CoreAlt -> IfaceAlt -toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map getOccFS bs) (toIfaceExpr r) +toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map (mkIfLclName . getOccFS) bs) (toIfaceExpr r) --------------------- toIfaceCon :: AltCon -> IfaceConAlt @@ -655,7 +655,7 @@ toIfaceVar v -- Foreign calls have special syntax | isExternalName name = IfaceExt name - | otherwise = IfaceLcl (occNameFS $ nameOccName name) + | otherwise = IfaceLcl (mkIfLclName (occNameFS $ nameOccName name)) where name = idName v ty = idType v ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -283,13 +283,16 @@ instance Ord NonDetFastString where -- `lexicalCompareFS` (i.e. which compares FastStrings on their String -- representation). Hence it is deterministic from one run to the other. newtype LexicalFastString - = LexicalFastString FastString + = LexicalFastString { getLexicalFastString :: FastString } deriving newtype (Eq, Show) deriving stock Data instance Ord LexicalFastString where compare (LexicalFastString fs1) (LexicalFastString fs2) = lexicalCompareFS fs1 fs2 +instance NFData LexicalFastString where + rnf (LexicalFastString f) = rnf f + -- ----------------------------------------------------------------------------- -- Construction ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -54,6 +54,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -158,9 +161,13 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - fsReaderTable <- initFastStringReaderTable - nameReaderTable <- (initReadNameCachedBinary name_cache) + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameCachedBinary name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud -- The order of these deserialisation matters! -- @@ -168,14 +175,21 @@ getTables name_cache bh = do fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) let fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh + bhFs = addReaderToUserData fsReader bh + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) let nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs + bhName = addReaderToUserData nameReader bhFs - pure bhName + ifaceTypeTable <- Binary.forwardGet bh (getTable ifaceTypeReaderTable bhName) + let + ifaceTypeReader = mkReaderFromTable ifaceTypeReaderTable ifaceTypeTable + bhIfaceType = addReaderToUserData ifaceTypeReader bhName + + writeIORef bhRef (getReaderUserData bhIfaceType) + pure bhIfaceType -- | Write an interface file. -- @@ -238,11 +252,13 @@ putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter , mkSomeBinaryWriter @Name nameWriter , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -250,7 +266,7 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) @@ -335,6 +351,24 @@ Here, a visualisation of the table structure we currently have: -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType = do + sym_tab <- initGenericSymbolTable + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ putGenericSymTab sym_tab + ) + initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) initReadNameCachedBinary cache = do ===================================== compiler/GHC/Iface/Decl.hs ===================================== @@ -45,7 +45,6 @@ import GHC.Types.SrcLoc import GHC.Utils.Panic.Plain import GHC.Utils.Misc -import GHC.Data.FastString import GHC.Data.Maybe import GHC.Data.BooleanFormula @@ -147,7 +146,7 @@ tyConToIfaceDecl env tycon | Just fam_flav <- famTyConFlav_maybe tycon = ( tc_env1 , IfaceFamily { ifName = getName tycon, - ifResVar = if_res_var, + ifResVar = mkIfLclName <$> if_res_var, ifFamFlav = to_if_fam_flav fam_flav, ifBinders = if_binders, ifResKind = if_res_kind, @@ -288,7 +287,7 @@ classToIfaceDecl env clas ifClassCtxt = tidyToIfaceContext env1 sc_theta, ifATs = map toIfaceAT clas_ats, ifSigs = map toIfaceClassOp op_stuff, - ifMinDef = toIfaceBooleanFormula $ fmap getOccFS (classMinimalDef clas) + ifMinDef = toIfaceBooleanFormula $ fmap (mkIfLclName . getOccFS) (classMinimalDef clas) } (env1, tc_binders) = tidyTyConBinders env (tyConBinders tycon) @@ -334,7 +333,7 @@ tidyTyConBinder env@(_, subst) tvb@(Bndr tv vis) tidyTyConBinders :: TidyEnv -> [TyConBinder] -> (TidyEnv, [TyConBinder]) tidyTyConBinders = mapAccumL tidyTyConBinder -tidyTyVar :: TidyEnv -> TyVar -> FastString +tidyTyVar :: TidyEnv -> TyVar -> IfLclName tidyTyVar (_, subst) tv = toIfaceTyVar (lookupVarEnv subst tv `orElse` tv) toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula ===================================== compiler/GHC/Iface/Env.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Runtime.Context import GHC.Unit.Module import GHC.Unit.Module.ModIface -import GHC.Data.FastString import GHC.Data.FastString.Env import GHC.Types.Var @@ -190,10 +189,10 @@ setNameModule (Just m) n = ************************************************************************ -} -tcIfaceLclId :: FastString -> IfL Id +tcIfaceLclId :: IfLclName -> IfL Id tcIfaceLclId occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_id_env lcl) occ of + ; case lookupFsEnv (if_id_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM $ vcat @@ -209,10 +208,10 @@ extendIfaceIdEnv ids in env { if_id_env = id_env' } -tcIfaceTyVar :: FastString -> IfL TyVar +tcIfaceTyVar :: IfLclName -> IfL TyVar tcIfaceTyVar occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_tv_env lcl) occ of + ; case lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ) } @@ -220,15 +219,15 @@ tcIfaceTyVar occ lookupIfaceTyVar :: IfaceTvBndr -> IfL (Maybe TyVar) lookupIfaceTyVar (occ, _) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar) lookupIfaceVar (IfaceIdBndr (_, occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_id_env lcl) occ) } + ; return (lookupFsEnv (if_id_env lcl) (ifLclNameFS occ)) } lookupIfaceVar (IfaceTvBndr (occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a extendIfaceTyVarEnv tyvars ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Types.Unique.FM import qualified Data.Array as A import qualified Data.Array.IO as A import qualified Data.Array.Unsafe as A +import Data.Function ( (&) ) import Data.IORef import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS @@ -43,6 +44,7 @@ import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Syntax (getIfaceType, putIfaceType ) data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt @@ -105,10 +107,13 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter (mkWriter putIfaceType) + , mkSomeBinaryWriter (mkWriter $ putName hie_symtab) + , mkSomeBinaryWriter (simpleBindingNameWriter $ mkWriter $ putName hie_symtab) + , mkSomeBinaryWriter (mkWriter $ putFastString hie_dict) + ] + put_ bh hiefile -- write the symtab pointer at the front of the file @@ -219,13 +224,13 @@ readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = addReaderToUserData (mkReader $ getDictFastString dict) bh0 symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) + let bh1' = bh1 + & addReaderToUserData (mkReader getIfaceType) + & addReaderToUserData (mkReader $ getSymTabName symtab) + & addReaderToUserData (simpleBindingNameReader $ mkReader $ getSymTabName symtab) + & addReaderToUserData (mkReader getIfaceType) return bh1' -- load the actual data ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -162,15 +162,15 @@ getEvidenceTree refmap var = go emptyNameSet var hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where - go (HTyVarTy n) = IfaceTyVar $ occNameFS $ getOccName n + go (HTyVarTy n) = IfaceTyVar $ (mkIfLclName (occNameFS $ getOccName n)) go (HAppTy a b) = IfaceAppTy a (hieToIfaceArgs b) go (HLitTy l) = IfaceLitTy l - go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k) + go (HForAllTy ((n,k),af) t) = let b = (mkIfLclName (occNameFS $ getOccName n), k) in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t go (HFunTy w a b) = IfaceFunTy visArgTypeLike w a b go (HQualTy pred b) = IfaceFunTy invisArgTypeLike many_ty pred b go (HCastTy a) = a - go HCoercionTy = IfaceTyVar "" + go HCoercionTy = IfaceTyVar (mkIfLclName "") go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs) -- This isn't fully faithful - we can't produce the 'Inferred' case ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1216,8 +1216,8 @@ addFingerprints hsc_env iface0 getOcc (IfLclTopBndr fs _ _ details) = case details of IfRecSelId { ifRecSelFirstCon = first_con } - -> mkRecFieldOccFS (getOccFS first_con) fs - _ -> mkVarOccFS fs + -> mkRecFieldOccFS (getOccFS first_con) (ifLclNameFS fs) + _ -> mkVarOccFS (ifLclNameFS fs) binding_key (IfaceNonRec b _) = IfaceNonRec (getOcc b) () binding_key (IfaceRec bs) = IfaceRec (map (\(b, _) -> (getOcc b, ())) bs) ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -632,6 +632,7 @@ data IfaceExpr | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E + data IfaceTickish = IfaceHpcTick Module Int -- from HpcTick x | IfaceSCC CostCentre Bool Bool -- from ProfNote @@ -1026,7 +1027,7 @@ pprIfaceDecl ss (IfaceClass { ifName = clas pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions text "{-# MINIMAL" <+> pprBooleanFormula - (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+> + (\_ def -> cparen (isLexSym def) (ppr def)) 0 (fmap ifLclNameFS minDef) <+> text "#-}" -- See Note [Suppressing binder signatures] in GHC.Iface.Type ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -10,7 +10,8 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} module GHC.Iface.Type ( - IfExtName, IfLclName, + IfExtName, + IfLclName(..), mkIfLclName, ifLclNameFS, IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), @@ -32,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, -- Equality testing isIfaceLiftedTypeKind, @@ -90,9 +93,11 @@ import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) import Control.DeepSeq +import Data.Proxy import Control.Monad ((<$!>)) +import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) +import Data.Maybe (isJust) {- ************************************************************************ @@ -102,7 +107,16 @@ import Data.Maybe( isJust ) ************************************************************************ -} -type IfLclName = FastString -- A local name in iface syntax +-- | A local name in iface syntax +newtype IfLclName = IfLclName + { getIfLclName :: LexicalFastString + } deriving (Eq, Ord, Show) + +ifLclNameFS :: IfLclName -> FastString +ifLclNameFS = getLexicalFastString . getIfLclName + +mkIfLclName :: FastString -> IfLclName +mkIfLclName = IfLclName . LexicalFastString type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax -- (However Internal or System Names never should) @@ -110,6 +124,8 @@ type IfExtName = Name -- An External or WiredIn Name can appear in Iface synta data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr + deriving (Eq, Ord) + type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) type IfaceTvBndr = (IfLclName, IfaceKind) @@ -178,6 +194,7 @@ data IfaceType -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression -- in interface file size (in GHC's boot libraries). -- See !3987. + deriving (Eq, Ord) type IfaceMult = IfaceType @@ -186,9 +203,9 @@ type IfaceContext = [IfacePredType] data IfaceTyLit = IfaceNumTyLit Integer - | IfaceStrTyLit FastString + | IfaceStrTyLit LexicalFastString | IfaceCharTyLit Char - deriving (Eq) + deriving (Eq, Ord) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag @@ -230,6 +247,7 @@ data IfaceAppArgs -- arguments in @{...}. IfaceAppArgs -- The rest of the arguments + deriving (Eq, Ord) instance Semi.Semigroup IfaceAppArgs where IA_Nil <> xs = xs @@ -256,7 +274,7 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName -- See Note [Sharing IfaceTyConInfo] for why -- sharing is so important for 'IfaceTyConInfo'. } - deriving (Eq) + deriving (Eq, Ord) -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -276,7 +294,7 @@ data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon -- that is actually being applied to two types -- of the same kind. This affects pretty-printing -- only: see Note [Equality predicates in IfaceType] - deriving (Eq) + deriving (Eq, Ord) instance Outputable IfaceTyConSort where ppr IfaceNormalTyCon = text "normal" @@ -370,7 +388,7 @@ data IfaceTyConInfo -- Used only to guide pretty-printing -- should be printed as 'D to distinguish it from -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } - deriving (Eq) + deriving (Eq, Ord) -- | This smart constructor allows sharing of the two most common -- cases. See Note [Sharing IfaceTyConInfo] @@ -420,7 +438,7 @@ This one change leads to an 15% reduction in residency for GHC when embedding data IfaceMCoercion = IfaceMRefl - | IfaceMCo IfaceCoercion + | IfaceMCo IfaceCoercion deriving (Eq, Ord) data IfaceCoercion = IfaceReflCo IfaceType @@ -445,11 +463,13 @@ data IfaceCoercion | IfaceSubCo IfaceCoercion | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] + deriving (Eq, Ord) data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String + deriving (Eq, Ord) {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -621,11 +641,11 @@ type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType] mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst -- See Note [Substitution on IfaceType] -mkIfaceTySubst eq_spec = mkFsEnv eq_spec +mkIfaceTySubst eq_spec = mkFsEnv (map (first ifLclNameFS) eq_spec) inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool -- See Note [Substitution on IfaceType] -inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs) +inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst (ifLclNameFS fs)) substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType -- See Note [Substitution on IfaceType] @@ -681,7 +701,7 @@ substIfaceAppArgs env args substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType substIfaceTyVar env tv - | Just ty <- lookupFsEnv env tv = ty + | Just ty <- lookupFsEnv env (ifLclNameFS tv) = ty | otherwise = IfaceTyVar tv @@ -1190,7 +1210,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind - = let subs' = extendFsEnv subs var substituted_ty + = let subs' = extendFsEnv subs (ifLclNameFS var) substituted_ty -- Record that we should replace it with LiftedRep/Lifted/Many, -- and recurse, discarding the forall in go subs' True ty @@ -1198,7 +1218,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty go subs rank1 (IfaceForAllTy bndr ty) = IfaceForAllTy (go_ifacebndr subs bndr) (go subs rank1 ty) - go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of + go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs (ifLclNameFS tv) of Just s -> s Nothing -> ty @@ -1626,7 +1646,7 @@ pprTyTcApp ctxt_prec tc tys = , IA_Arg (IfaceLitTy (IfaceStrTyLit n)) Required (IA_Arg ty Required IA_Nil) <- tys -> maybeParen ctxt_prec funPrec - $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty + $ char '?' <> ftext (getLexicalFastString n) <> text "::" <> ppr_ty topPrec ty | IfaceTupleTyCon arity sort <- ifaceTyConSort info , not debug @@ -2014,6 +2034,9 @@ pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) ------------------- +instance Outputable IfLclName where + ppr = ppr . ifLclNameFS + instance Outputable IfaceTyCon where ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc) @@ -2171,38 +2194,47 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) - - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } - - get bh = do + put_ bh tyCon = case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh tyCon + + get bh = case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2230,6 +2262,13 @@ instance Binary IfaceType where _ -> do n <- get bh return (IfaceLitTy n) +instance Binary IfLclName where + put_ bh = put_ bh . ifLclNameFS + + get bh = do + fs <- get bh + pure $ IfLclName $ LexicalFastString fs + instance Binary IfaceMCoercion where put_ bh IfaceMRefl = putByte bh 1 @@ -2475,6 +2514,9 @@ instance NFData IfaceTyConSort where IfaceSumTyCon arity -> rnf arity IfaceEqualityTyCon -> () +instance NFData IfLclName where + rnf (IfLclName lfs) = rnf lfs + instance NFData IfaceTyConInfo where rnf (IfaceTyConInfo f s) = f `seq` rnf s ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -733,7 +733,7 @@ tc_iface_decl parent _ (IfaceFamily {ifName = tc_name, { res_kind' <- tcIfaceType res_kind -- Note [Synonym kind loop] ; rhs <- forkM (mk_doc tc_name) $ tc_fam_flav tc_name fam_flav - ; res_name <- traverse (newIfaceName . mkTyVarOccFS) res + ; res_name <- traverse (newIfaceName . mkTyVarOccFS . ifLclNameFS) res ; let tycon = mkFamilyTyCon tc_name binders' res_kind' res_name rhs parent inj ; return (ATyCon tycon) } where @@ -782,7 +782,7 @@ tc_iface_decl _parent ignore_prags ; fds <- mapM tc_fd rdr_fds ; traceIf (text "tc-iface-class3" <+> ppr tc_name) ; let mindef_occ = fromIfaceBooleanFormula if_mindef - ; mindef <- traverse (lookupIfaceTop . mkVarOccFS) mindef_occ + ; mindef <- traverse (lookupIfaceTop . mkVarOccFS . ifLclNameFS) mindef_occ ; cls <- fixM $ \ cls -> do { ats <- mapM (tc_at cls) rdr_ats ; traceIf (text "tc-iface-class4" <+> ppr tc_name) @@ -936,8 +936,8 @@ mk_top_id (IfLclTopBndr raw_name iface_type info details) = do ; let occ = case details' of RecSelId { sel_tycon = parent } -> let con_fs = getOccFS $ recSelFirstConName parent - in mkRecFieldOccFS con_fs raw_name - _ -> mkVarOccFS raw_name + in mkRecFieldOccFS con_fs (ifLclNameFS raw_name) + _ -> mkVarOccFS (ifLclNameFS raw_name) ; name <- newIfaceName occ } info' <- tcIdInfo False TopLevel name ty info let new_id = mkGlobalId details' name ty info' @@ -1441,7 +1441,7 @@ tcIfaceCtxt sts = mapM tcIfaceType sts ----------------------------------------- tcIfaceTyLit :: IfaceTyLit -> IfL TyLit tcIfaceTyLit (IfaceNumTyLit n) = return (NumTyLit n) -tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) +tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit (getLexicalFastString n)) tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n) {- @@ -1485,7 +1485,7 @@ tcIfaceCo = go go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) - go_var :: FastString -> IfL CoVar + go_var :: IfLclName -> IfL CoVar go_var = tcIfaceLclId tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance @@ -1561,7 +1561,7 @@ tcIfaceExpr (IfaceECase scrut ty) tcIfaceExpr (IfaceCase scrut case_bndr alts) = do scrut' <- tcIfaceExpr scrut - case_bndr_name <- newIfaceName (mkVarOccFS case_bndr) + case_bndr_name <- newIfaceName (mkVarOccFS (ifLclNameFS case_bndr)) let scrut_ty = exprType scrut' case_mult = ManyTy @@ -1580,7 +1580,7 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do return (Case scrut' case_bndr' (coreAltsType alts') alts') tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} NotTopLevel name ty' info @@ -1598,7 +1598,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; return (Let (Rec pairs') body') } } where tc_rec_bndr (IfLetBndr fs ty _ ji) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; return (mkLocalId name ManyTy ty' `asJoinId_maybe` ji) } tc_pair (IfLetBndr _ _ info _, rhs) id @@ -1655,12 +1655,12 @@ tcIfaceAlt scrut mult (tycon, inst_tys) (IfaceAlt (IfaceDataAlt data_occ) arg_st (failIfM (ppr scrut $$ ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon))) ; tcIfaceDataAlt mult con inst_tys arg_strs rhs } -tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [FastString] -> IfaceExpr +tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [IfLclName] -> IfaceExpr -> IfL CoreAlt tcIfaceDataAlt mult con inst_tys arg_strs rhs = do { uniqs <- getUniquesM ; let (ex_tvs, arg_ids) - = dataConRepFSInstPat arg_strs uniqs mult con inst_tys + = dataConRepFSInstPat (map ifLclNameFS arg_strs) uniqs mult con inst_tys ; rhs' <- extendIfaceEnvs ex_tvs $ extendIfaceIdEnv arg_ids $ @@ -2031,7 +2031,7 @@ tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule -- - axioms for type-level literals (Nat and Symbol), -- enumerated in typeNatCoAxiomRules tcIfaceCoAxiomRule n - | Just ax <- lookupUFM typeNatCoAxiomRules n + | Just ax <- lookupUFM typeNatCoAxiomRules (ifLclNameFS n) = return ax | otherwise = pprPanic "tcIfaceCoAxiomRule" (ppr n) @@ -2075,7 +2075,7 @@ tcIfaceImplicit n = do bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a bindIfaceId (w, fs, ty) thing_inside - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; w' <- tcIfaceType w ; let id = mkLocalIdOrCoVar name w' ty' @@ -2118,7 +2118,7 @@ bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside - = do { name <- newIfaceName (mkTyVarOccFS occ) + = do { name <- newIfaceName (mkTyVarOccFS (ifLclNameFS occ)) ; tyvar <- mk_iface_tyvar name kind ; extendIfaceTyVarEnv [tyvar] (thing_inside tyvar) } ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -148,7 +148,7 @@ import qualified Data.Semigroup as Semi ********************************************************************* -} data LeftOrRight = CLeft | CRight - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) pickLR :: LeftOrRight -> (a,a) -> a pickLR CLeft (l,_) = l ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -720,7 +720,7 @@ Currently there are nine different uses of 'VarBndr': data VarBndr var argf = Bndr var argf -- See Note [The VarBndr type and its uses] - deriving( Data ) + deriving( Data, Eq, Ord) -- | Variable Binder -- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -127,7 +136,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (unfoldr) +import Data.List (sortOn, unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -230,22 +239,26 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a @@ -1099,24 +1112,35 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = inner_bh { rbm_off_r = off_r } + seekBinNoExpandReader bh' p_a + f p bh' seekBinNoExpandReader bh p -- skip over the object for now return a @@ -1170,6 +1194,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) @@ -1310,6 +1340,80 @@ data WriterTable = WriterTable { putTable :: WriteBinHandle -> IO Int } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol + } + +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop bound = do + d <- readIORef symtab_map + table_count <- readFastMutInt symtab_next + let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + case vs of + [] -> return table_count + todo -> do + mapM_ (\n -> serialiser bh n) (map snd todo) + loop table_count + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop 0) + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -78,6 +78,7 @@ import Data.Eq import Data.Bool import Data.Char import Prelude (Integer, length) +import Data.Ord (Ord) {- ************************************************************************ @@ -91,7 +92,7 @@ import Prelude (Integer, length) data PromotionFlag = NotPromoted | IsPromoted - deriving ( Eq, Data ) + deriving ( Eq, Data, Ord ) isPromoted :: PromotionFlag -> Bool isPromoted IsPromoted = True ===================================== compiler/Language/Haskell/Syntax/Type.hs-boot ===================================== @@ -2,6 +2,7 @@ module Language.Haskell.Syntax.Type where import Data.Bool import Data.Eq +import Data.Ord {- ************************************************************************ @@ -17,5 +18,6 @@ data PromotionFlag | IsPromoted instance Eq PromotionFlag +instance Ord PromotionFlag isPromoted :: PromotionFlag -> Bool ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 +Subproject commit fc8a6e6bbf4156ba01f0721a6d61d0daec36074d View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/748bf10071f58a54f61baf8c33a4131fddb8f679 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/748bf10071f58a54f61baf8c33a4131fddb8f679 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 13:47:05 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 09:47:05 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] Add deduplication table for `IfaceType` Message-ID: <661000d965de1_180afb19da6d855253@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 043ed148 by Matthew Pickering at 2024-04-05T15:41:41+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 20 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - utils/haddock Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -952,13 +952,13 @@ data CoSel -- See Note [SelCo] | SelForAll -- Decomposes (forall a. co) - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) data FunSel -- See Note [SelCo] = SelMult -- Multiplicity | SelArg -- Argument of function | SelRes -- Result of function - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -121,7 +121,7 @@ toIfaceTvBndr :: TyVar -> IfaceTvBndr toIfaceTvBndr = toIfaceTvBndrX emptyVarSet toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr -toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar) +toIfaceTvBndrX fr tyvar = ( mkIfLclName (occNameFS (getOccName tyvar)) , toIfaceTypeX fr (tyVarKind tyvar) ) @@ -133,7 +133,7 @@ toIfaceIdBndr = toIfaceIdBndrX emptyVarSet toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr toIfaceIdBndrX fr covar = ( toIfaceType (idMult covar) - , occNameFS (getOccName covar) + , mkIfLclName (occNameFS (getOccName covar)) , toIfaceTypeX fr (varType covar) ) @@ -218,11 +218,11 @@ toIfaceTypeX fr (TyConApp tc tys) arity = tyConArity tc n_tys = length tys -toIfaceTyVar :: TyVar -> FastString -toIfaceTyVar = occNameFS . getOccName +toIfaceTyVar :: TyVar -> IfLclName +toIfaceTyVar = mkIfLclName . occNameFS . getOccName -toIfaceCoVar :: CoVar -> FastString -toIfaceCoVar = occNameFS . getOccName +toIfaceCoVar :: CoVar -> IfLclName +toIfaceCoVar = mkIfLclName . occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon @@ -264,7 +264,7 @@ toIfaceTyCon_name n = IfaceTyCon n info toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x -toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x +toIfaceTyLit (StrTyLit x) = IfaceStrTyLit (LexicalFastString x) toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x ---------------- @@ -296,7 +296,7 @@ toIfaceCoercionX fr co go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c) go (SubCo co) = IfaceSubCo (go co) - go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs) + go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (mkIfLclName (coaxrName co)) (map go cs) go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs) go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) @@ -433,7 +433,7 @@ toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang toIfaceLetBndr :: Id -> IfaceLetBndr -toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) +toIfaceLetBndr id = IfLetBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (idJoinPointHood id) @@ -444,7 +444,7 @@ toIfaceTopBndr :: Id -> IfaceTopBndrInfo toIfaceTopBndr id = if isExternalName name then IfGblTopBndr name - else IfLclTopBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) + else IfLclTopBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (toIfaceIdDetails (idDetails id)) where name = getName id @@ -555,7 +555,7 @@ toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfac toIfaceExpr (App f a) = toIfaceApp f [a] toIfaceExpr (Case s x ty as) | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty) - | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as) + | otherwise = IfaceCase (toIfaceExpr s) (mkIfLclName (getOccFS x)) (map toIfaceAlt as) toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e) toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co) toIfaceExpr (Tick t e) = IfaceTick (toIfaceTickish t) (toIfaceExpr e) @@ -610,7 +610,7 @@ toIfaceTopBind b = --------------------- toIfaceAlt :: CoreAlt -> IfaceAlt -toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map getOccFS bs) (toIfaceExpr r) +toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map (mkIfLclName . getOccFS) bs) (toIfaceExpr r) --------------------- toIfaceCon :: AltCon -> IfaceConAlt @@ -655,7 +655,7 @@ toIfaceVar v -- Foreign calls have special syntax | isExternalName name = IfaceExt name - | otherwise = IfaceLcl (occNameFS $ nameOccName name) + | otherwise = IfaceLcl (mkIfLclName (occNameFS $ nameOccName name)) where name = idName v ty = idType v ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -283,13 +283,16 @@ instance Ord NonDetFastString where -- `lexicalCompareFS` (i.e. which compares FastStrings on their String -- representation). Hence it is deterministic from one run to the other. newtype LexicalFastString - = LexicalFastString FastString + = LexicalFastString { getLexicalFastString :: FastString } deriving newtype (Eq, Show) deriving stock Data instance Ord LexicalFastString where compare (LexicalFastString fs1) (LexicalFastString fs2) = lexicalCompareFS fs1 fs2 +instance NFData LexicalFastString where + rnf (LexicalFastString f) = rnf f + -- ----------------------------------------------------------------------------- -- Construction ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -54,6 +54,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -158,9 +161,13 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - fsReaderTable <- initFastStringReaderTable - nameReaderTable <- (initReadNameCachedBinary name_cache) + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameCachedBinary name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud -- The order of these deserialisation matters! -- @@ -168,14 +175,21 @@ getTables name_cache bh = do fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) let fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh + bhFs = addReaderToUserData fsReader bh + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) let nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs + bhName = addReaderToUserData nameReader bhFs - pure bhName + ifaceTypeTable <- Binary.forwardGet bh (getTable ifaceTypeReaderTable bhName) + let + ifaceTypeReader = mkReaderFromTable ifaceTypeReaderTable ifaceTypeTable + bhIfaceType = addReaderToUserData ifaceTypeReader bhName + + writeIORef bhRef (getReaderUserData bhIfaceType) + pure bhIfaceType -- | Write an interface file. -- @@ -238,11 +252,13 @@ putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter , mkSomeBinaryWriter @Name nameWriter , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -250,7 +266,7 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) @@ -335,6 +351,24 @@ Here, a visualisation of the table structure we currently have: -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType = do + sym_tab <- initGenericSymbolTable + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ putGenericSymTab sym_tab + ) + initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) initReadNameCachedBinary cache = do ===================================== compiler/GHC/Iface/Decl.hs ===================================== @@ -45,7 +45,6 @@ import GHC.Types.SrcLoc import GHC.Utils.Panic.Plain import GHC.Utils.Misc -import GHC.Data.FastString import GHC.Data.Maybe import GHC.Data.BooleanFormula @@ -147,7 +146,7 @@ tyConToIfaceDecl env tycon | Just fam_flav <- famTyConFlav_maybe tycon = ( tc_env1 , IfaceFamily { ifName = getName tycon, - ifResVar = if_res_var, + ifResVar = mkIfLclName <$> if_res_var, ifFamFlav = to_if_fam_flav fam_flav, ifBinders = if_binders, ifResKind = if_res_kind, @@ -288,7 +287,7 @@ classToIfaceDecl env clas ifClassCtxt = tidyToIfaceContext env1 sc_theta, ifATs = map toIfaceAT clas_ats, ifSigs = map toIfaceClassOp op_stuff, - ifMinDef = toIfaceBooleanFormula $ fmap getOccFS (classMinimalDef clas) + ifMinDef = toIfaceBooleanFormula $ fmap (mkIfLclName . getOccFS) (classMinimalDef clas) } (env1, tc_binders) = tidyTyConBinders env (tyConBinders tycon) @@ -334,7 +333,7 @@ tidyTyConBinder env@(_, subst) tvb@(Bndr tv vis) tidyTyConBinders :: TidyEnv -> [TyConBinder] -> (TidyEnv, [TyConBinder]) tidyTyConBinders = mapAccumL tidyTyConBinder -tidyTyVar :: TidyEnv -> TyVar -> FastString +tidyTyVar :: TidyEnv -> TyVar -> IfLclName tidyTyVar (_, subst) tv = toIfaceTyVar (lookupVarEnv subst tv `orElse` tv) toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula ===================================== compiler/GHC/Iface/Env.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Runtime.Context import GHC.Unit.Module import GHC.Unit.Module.ModIface -import GHC.Data.FastString import GHC.Data.FastString.Env import GHC.Types.Var @@ -190,10 +189,10 @@ setNameModule (Just m) n = ************************************************************************ -} -tcIfaceLclId :: FastString -> IfL Id +tcIfaceLclId :: IfLclName -> IfL Id tcIfaceLclId occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_id_env lcl) occ of + ; case lookupFsEnv (if_id_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM $ vcat @@ -209,10 +208,10 @@ extendIfaceIdEnv ids in env { if_id_env = id_env' } -tcIfaceTyVar :: FastString -> IfL TyVar +tcIfaceTyVar :: IfLclName -> IfL TyVar tcIfaceTyVar occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_tv_env lcl) occ of + ; case lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ) } @@ -220,15 +219,15 @@ tcIfaceTyVar occ lookupIfaceTyVar :: IfaceTvBndr -> IfL (Maybe TyVar) lookupIfaceTyVar (occ, _) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar) lookupIfaceVar (IfaceIdBndr (_, occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_id_env lcl) occ) } + ; return (lookupFsEnv (if_id_env lcl) (ifLclNameFS occ)) } lookupIfaceVar (IfaceTvBndr (occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a extendIfaceTyVarEnv tyvars ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Types.Unique.FM import qualified Data.Array as A import qualified Data.Array.IO as A import qualified Data.Array.Unsafe as A +import Data.Function ( (&) ) import Data.IORef import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS @@ -43,6 +44,7 @@ import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Syntax (getIfaceType, putIfaceType ) data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt @@ -105,10 +107,13 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter (mkWriter putIfaceType) + , mkSomeBinaryWriter (mkWriter $ putName hie_symtab) + , mkSomeBinaryWriter (simpleBindingNameWriter $ mkWriter $ putName hie_symtab) + , mkSomeBinaryWriter (mkWriter $ putFastString hie_dict) + ] + put_ bh hiefile -- write the symtab pointer at the front of the file @@ -219,13 +224,13 @@ readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = addReaderToUserData (mkReader $ getDictFastString dict) bh0 symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) + let bh1' = bh1 + & addReaderToUserData (mkReader getIfaceType) + & addReaderToUserData (mkReader $ getSymTabName symtab) + & addReaderToUserData (simpleBindingNameReader $ mkReader $ getSymTabName symtab) + & addReaderToUserData (mkReader getIfaceType) return bh1' -- load the actual data ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -162,15 +162,15 @@ getEvidenceTree refmap var = go emptyNameSet var hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where - go (HTyVarTy n) = IfaceTyVar $ occNameFS $ getOccName n + go (HTyVarTy n) = IfaceTyVar $ (mkIfLclName (occNameFS $ getOccName n)) go (HAppTy a b) = IfaceAppTy a (hieToIfaceArgs b) go (HLitTy l) = IfaceLitTy l - go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k) + go (HForAllTy ((n,k),af) t) = let b = (mkIfLclName (occNameFS $ getOccName n), k) in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t go (HFunTy w a b) = IfaceFunTy visArgTypeLike w a b go (HQualTy pred b) = IfaceFunTy invisArgTypeLike many_ty pred b go (HCastTy a) = a - go HCoercionTy = IfaceTyVar "" + go HCoercionTy = IfaceTyVar (mkIfLclName "") go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs) -- This isn't fully faithful - we can't produce the 'Inferred' case ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1216,8 +1216,8 @@ addFingerprints hsc_env iface0 getOcc (IfLclTopBndr fs _ _ details) = case details of IfRecSelId { ifRecSelFirstCon = first_con } - -> mkRecFieldOccFS (getOccFS first_con) fs - _ -> mkVarOccFS fs + -> mkRecFieldOccFS (getOccFS first_con) (ifLclNameFS fs) + _ -> mkVarOccFS (ifLclNameFS fs) binding_key (IfaceNonRec b _) = IfaceNonRec (getOcc b) () binding_key (IfaceRec bs) = IfaceRec (map (\(b, _) -> (getOcc b, ())) bs) ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -632,6 +632,7 @@ data IfaceExpr | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E + data IfaceTickish = IfaceHpcTick Module Int -- from HpcTick x | IfaceSCC CostCentre Bool Bool -- from ProfNote @@ -1026,7 +1027,7 @@ pprIfaceDecl ss (IfaceClass { ifName = clas pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions text "{-# MINIMAL" <+> pprBooleanFormula - (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+> + (\_ def -> cparen (isLexSym def) (ppr def)) 0 (fmap ifLclNameFS minDef) <+> text "#-}" -- See Note [Suppressing binder signatures] in GHC.Iface.Type ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -10,7 +10,8 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} module GHC.Iface.Type ( - IfExtName, IfLclName, + IfExtName, + IfLclName(..), mkIfLclName, ifLclNameFS, IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), @@ -32,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, -- Equality testing isIfaceLiftedTypeKind, @@ -90,9 +93,11 @@ import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) import Control.DeepSeq +import Data.Proxy import Control.Monad ((<$!>)) +import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) +import Data.Maybe (isJust) {- ************************************************************************ @@ -102,7 +107,16 @@ import Data.Maybe( isJust ) ************************************************************************ -} -type IfLclName = FastString -- A local name in iface syntax +-- | A local name in iface syntax +newtype IfLclName = IfLclName + { getIfLclName :: LexicalFastString + } deriving (Eq, Ord, Show) + +ifLclNameFS :: IfLclName -> FastString +ifLclNameFS = getLexicalFastString . getIfLclName + +mkIfLclName :: FastString -> IfLclName +mkIfLclName = IfLclName . LexicalFastString type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax -- (However Internal or System Names never should) @@ -110,6 +124,8 @@ type IfExtName = Name -- An External or WiredIn Name can appear in Iface synta data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr + deriving (Eq, Ord) + type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) type IfaceTvBndr = (IfLclName, IfaceKind) @@ -178,6 +194,7 @@ data IfaceType -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression -- in interface file size (in GHC's boot libraries). -- See !3987. + deriving (Eq, Ord) type IfaceMult = IfaceType @@ -186,9 +203,9 @@ type IfaceContext = [IfacePredType] data IfaceTyLit = IfaceNumTyLit Integer - | IfaceStrTyLit FastString + | IfaceStrTyLit LexicalFastString | IfaceCharTyLit Char - deriving (Eq) + deriving (Eq, Ord) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag @@ -230,6 +247,7 @@ data IfaceAppArgs -- arguments in @{...}. IfaceAppArgs -- The rest of the arguments + deriving (Eq, Ord) instance Semi.Semigroup IfaceAppArgs where IA_Nil <> xs = xs @@ -256,7 +274,7 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName -- See Note [Sharing IfaceTyConInfo] for why -- sharing is so important for 'IfaceTyConInfo'. } - deriving (Eq) + deriving (Eq, Ord) -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -276,7 +294,7 @@ data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon -- that is actually being applied to two types -- of the same kind. This affects pretty-printing -- only: see Note [Equality predicates in IfaceType] - deriving (Eq) + deriving (Eq, Ord) instance Outputable IfaceTyConSort where ppr IfaceNormalTyCon = text "normal" @@ -370,7 +388,7 @@ data IfaceTyConInfo -- Used only to guide pretty-printing -- should be printed as 'D to distinguish it from -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } - deriving (Eq) + deriving (Eq, Ord) -- | This smart constructor allows sharing of the two most common -- cases. See Note [Sharing IfaceTyConInfo] @@ -420,7 +438,7 @@ This one change leads to an 15% reduction in residency for GHC when embedding data IfaceMCoercion = IfaceMRefl - | IfaceMCo IfaceCoercion + | IfaceMCo IfaceCoercion deriving (Eq, Ord) data IfaceCoercion = IfaceReflCo IfaceType @@ -445,11 +463,13 @@ data IfaceCoercion | IfaceSubCo IfaceCoercion | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] + deriving (Eq, Ord) data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String + deriving (Eq, Ord) {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -621,11 +641,11 @@ type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType] mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst -- See Note [Substitution on IfaceType] -mkIfaceTySubst eq_spec = mkFsEnv eq_spec +mkIfaceTySubst eq_spec = mkFsEnv (map (first ifLclNameFS) eq_spec) inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool -- See Note [Substitution on IfaceType] -inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs) +inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst (ifLclNameFS fs)) substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType -- See Note [Substitution on IfaceType] @@ -681,7 +701,7 @@ substIfaceAppArgs env args substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType substIfaceTyVar env tv - | Just ty <- lookupFsEnv env tv = ty + | Just ty <- lookupFsEnv env (ifLclNameFS tv) = ty | otherwise = IfaceTyVar tv @@ -1190,7 +1210,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind - = let subs' = extendFsEnv subs var substituted_ty + = let subs' = extendFsEnv subs (ifLclNameFS var) substituted_ty -- Record that we should replace it with LiftedRep/Lifted/Many, -- and recurse, discarding the forall in go subs' True ty @@ -1198,7 +1218,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty go subs rank1 (IfaceForAllTy bndr ty) = IfaceForAllTy (go_ifacebndr subs bndr) (go subs rank1 ty) - go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of + go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs (ifLclNameFS tv) of Just s -> s Nothing -> ty @@ -1626,7 +1646,7 @@ pprTyTcApp ctxt_prec tc tys = , IA_Arg (IfaceLitTy (IfaceStrTyLit n)) Required (IA_Arg ty Required IA_Nil) <- tys -> maybeParen ctxt_prec funPrec - $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty + $ char '?' <> ftext (getLexicalFastString n) <> text "::" <> ppr_ty topPrec ty | IfaceTupleTyCon arity sort <- ifaceTyConSort info , not debug @@ -2014,6 +2034,9 @@ pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) ------------------- +instance Outputable IfLclName where + ppr = ppr . ifLclNameFS + instance Outputable IfaceTyCon where ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc) @@ -2171,38 +2194,47 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) - - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } - - get bh = do + put_ bh tyCon = case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh tyCon + + get bh = case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2230,6 +2262,13 @@ instance Binary IfaceType where _ -> do n <- get bh return (IfaceLitTy n) +instance Binary IfLclName where + put_ bh = put_ bh . ifLclNameFS + + get bh = do + fs <- get bh + pure $ IfLclName $ LexicalFastString fs + instance Binary IfaceMCoercion where put_ bh IfaceMRefl = putByte bh 1 @@ -2475,6 +2514,9 @@ instance NFData IfaceTyConSort where IfaceSumTyCon arity -> rnf arity IfaceEqualityTyCon -> () +instance NFData IfLclName where + rnf (IfLclName lfs) = rnf lfs + instance NFData IfaceTyConInfo where rnf (IfaceTyConInfo f s) = f `seq` rnf s ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -733,7 +733,7 @@ tc_iface_decl parent _ (IfaceFamily {ifName = tc_name, { res_kind' <- tcIfaceType res_kind -- Note [Synonym kind loop] ; rhs <- forkM (mk_doc tc_name) $ tc_fam_flav tc_name fam_flav - ; res_name <- traverse (newIfaceName . mkTyVarOccFS) res + ; res_name <- traverse (newIfaceName . mkTyVarOccFS . ifLclNameFS) res ; let tycon = mkFamilyTyCon tc_name binders' res_kind' res_name rhs parent inj ; return (ATyCon tycon) } where @@ -782,7 +782,7 @@ tc_iface_decl _parent ignore_prags ; fds <- mapM tc_fd rdr_fds ; traceIf (text "tc-iface-class3" <+> ppr tc_name) ; let mindef_occ = fromIfaceBooleanFormula if_mindef - ; mindef <- traverse (lookupIfaceTop . mkVarOccFS) mindef_occ + ; mindef <- traverse (lookupIfaceTop . mkVarOccFS . ifLclNameFS) mindef_occ ; cls <- fixM $ \ cls -> do { ats <- mapM (tc_at cls) rdr_ats ; traceIf (text "tc-iface-class4" <+> ppr tc_name) @@ -936,8 +936,8 @@ mk_top_id (IfLclTopBndr raw_name iface_type info details) = do ; let occ = case details' of RecSelId { sel_tycon = parent } -> let con_fs = getOccFS $ recSelFirstConName parent - in mkRecFieldOccFS con_fs raw_name - _ -> mkVarOccFS raw_name + in mkRecFieldOccFS con_fs (ifLclNameFS raw_name) + _ -> mkVarOccFS (ifLclNameFS raw_name) ; name <- newIfaceName occ } info' <- tcIdInfo False TopLevel name ty info let new_id = mkGlobalId details' name ty info' @@ -1441,7 +1441,7 @@ tcIfaceCtxt sts = mapM tcIfaceType sts ----------------------------------------- tcIfaceTyLit :: IfaceTyLit -> IfL TyLit tcIfaceTyLit (IfaceNumTyLit n) = return (NumTyLit n) -tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) +tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit (getLexicalFastString n)) tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n) {- @@ -1485,7 +1485,7 @@ tcIfaceCo = go go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) - go_var :: FastString -> IfL CoVar + go_var :: IfLclName -> IfL CoVar go_var = tcIfaceLclId tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance @@ -1561,7 +1561,7 @@ tcIfaceExpr (IfaceECase scrut ty) tcIfaceExpr (IfaceCase scrut case_bndr alts) = do scrut' <- tcIfaceExpr scrut - case_bndr_name <- newIfaceName (mkVarOccFS case_bndr) + case_bndr_name <- newIfaceName (mkVarOccFS (ifLclNameFS case_bndr)) let scrut_ty = exprType scrut' case_mult = ManyTy @@ -1580,7 +1580,7 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do return (Case scrut' case_bndr' (coreAltsType alts') alts') tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} NotTopLevel name ty' info @@ -1598,7 +1598,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; return (Let (Rec pairs') body') } } where tc_rec_bndr (IfLetBndr fs ty _ ji) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; return (mkLocalId name ManyTy ty' `asJoinId_maybe` ji) } tc_pair (IfLetBndr _ _ info _, rhs) id @@ -1655,12 +1655,12 @@ tcIfaceAlt scrut mult (tycon, inst_tys) (IfaceAlt (IfaceDataAlt data_occ) arg_st (failIfM (ppr scrut $$ ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon))) ; tcIfaceDataAlt mult con inst_tys arg_strs rhs } -tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [FastString] -> IfaceExpr +tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [IfLclName] -> IfaceExpr -> IfL CoreAlt tcIfaceDataAlt mult con inst_tys arg_strs rhs = do { uniqs <- getUniquesM ; let (ex_tvs, arg_ids) - = dataConRepFSInstPat arg_strs uniqs mult con inst_tys + = dataConRepFSInstPat (map ifLclNameFS arg_strs) uniqs mult con inst_tys ; rhs' <- extendIfaceEnvs ex_tvs $ extendIfaceIdEnv arg_ids $ @@ -2031,7 +2031,7 @@ tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule -- - axioms for type-level literals (Nat and Symbol), -- enumerated in typeNatCoAxiomRules tcIfaceCoAxiomRule n - | Just ax <- lookupUFM typeNatCoAxiomRules n + | Just ax <- lookupUFM typeNatCoAxiomRules (ifLclNameFS n) = return ax | otherwise = pprPanic "tcIfaceCoAxiomRule" (ppr n) @@ -2075,7 +2075,7 @@ tcIfaceImplicit n = do bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a bindIfaceId (w, fs, ty) thing_inside - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; w' <- tcIfaceType w ; let id = mkLocalIdOrCoVar name w' ty' @@ -2118,7 +2118,7 @@ bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside - = do { name <- newIfaceName (mkTyVarOccFS occ) + = do { name <- newIfaceName (mkTyVarOccFS (ifLclNameFS occ)) ; tyvar <- mk_iface_tyvar name kind ; extendIfaceTyVarEnv [tyvar] (thing_inside tyvar) } ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -148,7 +148,7 @@ import qualified Data.Semigroup as Semi ********************************************************************* -} data LeftOrRight = CLeft | CRight - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) pickLR :: LeftOrRight -> (a,a) -> a pickLR CLeft (l,_) = l ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -720,7 +720,7 @@ Currently there are nine different uses of 'VarBndr': data VarBndr var argf = Bndr var argf -- See Note [The VarBndr type and its uses] - deriving( Data ) + deriving( Data, Eq, Ord) -- | Variable Binder -- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -127,7 +136,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (unfoldr) +import Data.List (sortOn, unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -230,22 +239,26 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a @@ -1099,24 +1112,35 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = inner_bh { rbm_off_r = off_r } + seekBinNoExpandReader bh' p_a + f p bh' seekBinNoExpandReader bh p -- skip over the object for now return a @@ -1170,6 +1194,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) @@ -1310,6 +1340,80 @@ data WriterTable = WriterTable { putTable :: WriteBinHandle -> IO Int } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol + } + +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop bound = do + d <- readIORef symtab_map + table_count <- readFastMutInt symtab_next + let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + case vs of + [] -> return table_count + todo -> do + mapM_ (\n -> serialiser bh n) (map snd todo) + loop table_count + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop 0) + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -78,6 +78,7 @@ import Data.Eq import Data.Bool import Data.Char import Prelude (Integer, length) +import Data.Ord (Ord) {- ************************************************************************ @@ -91,7 +92,7 @@ import Prelude (Integer, length) data PromotionFlag = NotPromoted | IsPromoted - deriving ( Eq, Data ) + deriving ( Eq, Data, Ord ) isPromoted :: PromotionFlag -> Bool isPromoted IsPromoted = True ===================================== compiler/Language/Haskell/Syntax/Type.hs-boot ===================================== @@ -2,6 +2,7 @@ module Language.Haskell.Syntax.Type where import Data.Bool import Data.Eq +import Data.Ord {- ************************************************************************ @@ -17,5 +18,6 @@ data PromotionFlag | IsPromoted instance Eq PromotionFlag +instance Ord PromotionFlag isPromoted :: PromotionFlag -> Bool ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 +Subproject commit fc8a6e6bbf4156ba01f0721a6d61d0daec36074d View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/043ed148bb082b93884dd0fac361cafd90f83abf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/043ed148bb082b93884dd0fac361cafd90f83abf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 14:34:07 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Fri, 05 Apr 2024 10:34:07 -0400 Subject: [Git][ghc/ghc][wip/andreask/fix_fallthrough] NCG: Fix a bug where we errounously removed a required jump instruction. Message-ID: <66100bdfe8c08_180afb1fe213459048@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/fix_fallthrough at Glasgow Haskell Compiler / GHC Commits: 421dcd85 by Andreas Klebinger at 2024-04-05T16:33:55+02:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 13 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm Changes: ===================================== compiler/GHC/CmmToAsm/AArch64.hs ===================================== @@ -47,6 +47,7 @@ instance Instruction AArch64.Instr where patchRegsOfInstr = AArch64.patchRegsOfInstr isJumpishInstr = AArch64.isJumpishInstr jumpDestsOfInstr = AArch64.jumpDestsOfInstr + canFallthroughTo = AArch64.canFallthroughTo patchJumpInstr = AArch64.patchJumpInstr mkSpillInstr = AArch64.mkSpillInstr mkLoadInstr = AArch64.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -311,6 +311,12 @@ jumpDestsOfInstr (BL t _ _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr _ = [] +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid +canFallthroughTo (J (TBlock target)) bid = bid == target +canFallthroughTo (B (TBlock target)) bid = bid == target +canFallthroughTo _ _ = False + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points. ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -771,10 +771,9 @@ dropJumps :: forall a i. Instruction i => LabelMap a -> [GenBasicBlock i] dropJumps _ [] = [] dropJumps info (BasicBlock lbl ins:todo) | Just ins <- nonEmpty ins --This can happen because of shortcutting - , [dest] <- jumpDestsOfInstr (NE.last ins) , BasicBlock nextLbl _ : _ <- todo - , not (mapMember dest info) - , nextLbl == dest + , canFallthroughTo (NE.last ins) nextLbl + , not (mapMember nextLbl info) = BasicBlock lbl (NE.init ins) : dropJumps info todo | otherwise = BasicBlock lbl ins : dropJumps info todo ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -71,11 +71,17 @@ class Instruction instr where :: instr -> Bool - -- | Give the possible destinations of this jump instruction. + -- | Give the possible *local block* destinations of this jump instruction. -- Must be defined for all jumpish instructions. jumpDestsOfInstr :: instr -> [BlockId] + -- | Check if the instr always transfers control flow + -- to the given block. Used by code layout to eliminate + -- jumps that can be replaced by fall through. + canFallthroughTo + :: instr -> BlockId -> Bool + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join ===================================== compiler/GHC/CmmToAsm/Monad.hs ===================================== @@ -78,8 +78,15 @@ data NcgImpl statics instr jumpDest = NcgImpl { cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl statics instr], generateJumpTableForInstr :: instr -> Maybe (NatCmmDecl statics instr), getJumpDestBlockId :: jumpDest -> Maybe BlockId, + -- | Does this jump always jump to a single destination and is shortcutable? + -- + -- We use this to determine shortcutable instructions - See Note [What is shortcutting] + -- Note that if we return a destination here we *most* support the relevant shortcutting in + -- shortcutStatics for jump tables and shortcutJump for the instructions itself. canShortcut :: instr -> Maybe jumpDest, + -- | Replace references to blockIds with other destinations - used to update jump tables. shortcutStatics :: (BlockId -> Maybe jumpDest) -> statics -> statics, + -- | Change the jump destination(s) of an instruction. shortcutJump :: (BlockId -> Maybe jumpDest) -> instr -> instr, -- | 'Module' is only for printing internal labels. See Note [Internal proc -- labels] in CLabel. @@ -105,6 +112,25 @@ data NcgImpl statics instr jumpDest = NcgImpl { -- when possible. } +{- Note [supporting shortcutting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For the concept of shortcutting see Note [What is shortcutting]. + +In order to support shortcutting across multiple backends uniformly we +use canShortcut, shortcutStatics and shortcutJump. + +canShortcut tells us if the backend support shortcutting of a instruction +and if so what destination we should retarget instruction to instead. + +shortcutStatics exists to allow us to update jump destinations in jump tables. + +shortcutJump updates the instructions itself. + +A backend can opt out of those by always returning Nothing for canShortcut +and implementing shortcutStatics/shortcutJump as \_ x -> x + +-} + {- Note [pprNatCmmDeclS and pprNatCmmDeclH] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each NcgImpl provides two implementations of its CmmDecl printer, pprNatCmmDeclS ===================================== compiler/GHC/CmmToAsm/PPC.hs ===================================== @@ -46,6 +46,7 @@ instance Instruction PPC.Instr where patchRegsOfInstr = PPC.patchRegsOfInstr isJumpishInstr = PPC.isJumpishInstr jumpDestsOfInstr = PPC.jumpDestsOfInstr + canFallthroughTo = PPC.canFallthroughTo patchJumpInstr = PPC.patchJumpInstr mkSpillInstr = PPC.mkSpillInstr mkLoadInstr = PPC.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/PPC/Instr.hs ===================================== @@ -22,6 +22,7 @@ module GHC.CmmToAsm.PPC.Instr , patchJumpInstr , patchRegsOfInstr , jumpDestsOfInstr + , canFallthroughTo , takeRegRegMoveInstr , takeDeltaInstr , mkRegRegMoveInstr @@ -509,6 +510,13 @@ isJumpishInstr instr JMP{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo instr bid + = case instr of + BCC _ target _ -> target == bid + BCCFAR _ target _ -> target == bid + _ -> False + -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the ===================================== compiler/GHC/CmmToAsm/Reg/Liveness.hs ===================================== @@ -126,6 +126,11 @@ instance Instruction instr => Instruction (InstrSR instr) where Instr instr -> isJumpishInstr instr _ -> False + jumpDestsOfInstr i + = case i of + Instr instr -> canFallthroughTo instr + _ -> [] + jumpDestsOfInstr i = case i of Instr instr -> jumpDestsOfInstr instr ===================================== compiler/GHC/CmmToAsm/X86.hs ===================================== @@ -51,6 +51,7 @@ instance Instruction X86.Instr where patchRegsOfInstr = X86.patchRegsOfInstr isJumpishInstr = X86.isJumpishInstr jumpDestsOfInstr = X86.jumpDestsOfInstr + canFallthroughTo = X86.canFallthroughTo patchJumpInstr = X86.patchJumpInstr mkSpillInstr = X86.mkSpillInstr mkLoadInstr = X86.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -31,6 +31,7 @@ module GHC.CmmToAsm.X86.Instr , mkSpillInstr , mkRegRegMoveInstr , jumpDestsOfInstr + , canFallthroughTo , patchRegsOfInstr , patchJumpInstr , isMetaInstr @@ -669,6 +670,16 @@ isJumpishInstr instr CALL{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo insn bid + = case insn of + JXX _ target -> bid == target + JMP_TBL _ targets _ _ -> all isTargetBid targets + where + isTargetBid target = case target of + Nothing -> True + Just (DestBlockId target) -> target == bid + _ -> False jumpDestsOfInstr :: Instr ===================================== testsuite/tests/codeGen/should_run/T24507.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} + +module Main where + +import GHC.Exts + +foreign import prim "foo" foo :: Int# -> Int# + +main = do + + let f x = case x of I# x' -> case foo x' of x -> print (I# x) + mapM_ f [1..7] \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/T24507.stdout ===================================== @@ -0,0 +1,7 @@ +1 +2 +2 +2 +2 +2 +2 ===================================== testsuite/tests/codeGen/should_run/T24507_cmm.cmm ===================================== @@ -0,0 +1,35 @@ +#include "Cmm.h" + +bar() { + return (2); +} + +foo(W_ x) { + + switch(x) { + case 1: goto a; + case 2: goto b; + case 3: goto c; + case 4: goto d; + case 5: goto e; + case 6: goto f; + case 7: goto g; + } + return (1); + + a: + return (1); + b: + jump bar(); + c: + jump bar(); + d: + jump bar(); + e: + jump bar(); + f: + jump bar(); + g: + jump bar(); + +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/421dcd85b8425707eabb2300136cc143f78868f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/421dcd85b8425707eabb2300136cc143f78868f2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 14:37:16 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Fri, 05 Apr 2024 10:37:16 -0400 Subject: [Git][ghc/ghc][wip/andreask/fix_fallthrough] NCG: Fix a bug where we errounously removed a required jump instruction. Message-ID: <66100c9c3b981_180afb20ea748608fb@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/fix_fallthrough at Glasgow Haskell Compiler / GHC Commits: 39a08d71 by Andreas Klebinger at 2024-04-05T16:37:02+02:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 13 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm Changes: ===================================== compiler/GHC/CmmToAsm/AArch64.hs ===================================== @@ -47,6 +47,7 @@ instance Instruction AArch64.Instr where patchRegsOfInstr = AArch64.patchRegsOfInstr isJumpishInstr = AArch64.isJumpishInstr jumpDestsOfInstr = AArch64.jumpDestsOfInstr + canFallthroughTo = AArch64.canFallthroughTo patchJumpInstr = AArch64.patchJumpInstr mkSpillInstr = AArch64.mkSpillInstr mkLoadInstr = AArch64.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -311,6 +311,12 @@ jumpDestsOfInstr (BL t _ _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr _ = [] +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid +canFallthroughTo (J (TBlock target)) bid = bid == target +canFallthroughTo (B (TBlock target)) bid = bid == target +canFallthroughTo _ _ = False + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points. ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -771,10 +771,9 @@ dropJumps :: forall a i. Instruction i => LabelMap a -> [GenBasicBlock i] dropJumps _ [] = [] dropJumps info (BasicBlock lbl ins:todo) | Just ins <- nonEmpty ins --This can happen because of shortcutting - , [dest] <- jumpDestsOfInstr (NE.last ins) , BasicBlock nextLbl _ : _ <- todo - , not (mapMember dest info) - , nextLbl == dest + , canFallthroughTo (NE.last ins) nextLbl + , not (mapMember nextLbl info) = BasicBlock lbl (NE.init ins) : dropJumps info todo | otherwise = BasicBlock lbl ins : dropJumps info todo ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -71,11 +71,17 @@ class Instruction instr where :: instr -> Bool - -- | Give the possible destinations of this jump instruction. + -- | Give the possible *local block* destinations of this jump instruction. -- Must be defined for all jumpish instructions. jumpDestsOfInstr :: instr -> [BlockId] + -- | Check if the instr always transfers control flow + -- to the given block. Used by code layout to eliminate + -- jumps that can be replaced by fall through. + canFallthroughTo + :: instr -> BlockId -> Bool + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join ===================================== compiler/GHC/CmmToAsm/Monad.hs ===================================== @@ -78,8 +78,15 @@ data NcgImpl statics instr jumpDest = NcgImpl { cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl statics instr], generateJumpTableForInstr :: instr -> Maybe (NatCmmDecl statics instr), getJumpDestBlockId :: jumpDest -> Maybe BlockId, + -- | Does this jump always jump to a single destination and is shortcutable? + -- + -- We use this to determine shortcutable instructions - See Note [What is shortcutting] + -- Note that if we return a destination here we *most* support the relevant shortcutting in + -- shortcutStatics for jump tables and shortcutJump for the instructions itself. canShortcut :: instr -> Maybe jumpDest, + -- | Replace references to blockIds with other destinations - used to update jump tables. shortcutStatics :: (BlockId -> Maybe jumpDest) -> statics -> statics, + -- | Change the jump destination(s) of an instruction. shortcutJump :: (BlockId -> Maybe jumpDest) -> instr -> instr, -- | 'Module' is only for printing internal labels. See Note [Internal proc -- labels] in CLabel. @@ -105,6 +112,25 @@ data NcgImpl statics instr jumpDest = NcgImpl { -- when possible. } +{- Note [supporting shortcutting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For the concept of shortcutting see Note [What is shortcutting]. + +In order to support shortcutting across multiple backends uniformly we +use canShortcut, shortcutStatics and shortcutJump. + +canShortcut tells us if the backend support shortcutting of a instruction +and if so what destination we should retarget instruction to instead. + +shortcutStatics exists to allow us to update jump destinations in jump tables. + +shortcutJump updates the instructions itself. + +A backend can opt out of those by always returning Nothing for canShortcut +and implementing shortcutStatics/shortcutJump as \_ x -> x + +-} + {- Note [pprNatCmmDeclS and pprNatCmmDeclH] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each NcgImpl provides two implementations of its CmmDecl printer, pprNatCmmDeclS ===================================== compiler/GHC/CmmToAsm/PPC.hs ===================================== @@ -46,6 +46,7 @@ instance Instruction PPC.Instr where patchRegsOfInstr = PPC.patchRegsOfInstr isJumpishInstr = PPC.isJumpishInstr jumpDestsOfInstr = PPC.jumpDestsOfInstr + canFallthroughTo = PPC.canFallthroughTo patchJumpInstr = PPC.patchJumpInstr mkSpillInstr = PPC.mkSpillInstr mkLoadInstr = PPC.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/PPC/Instr.hs ===================================== @@ -22,6 +22,7 @@ module GHC.CmmToAsm.PPC.Instr , patchJumpInstr , patchRegsOfInstr , jumpDestsOfInstr + , canFallthroughTo , takeRegRegMoveInstr , takeDeltaInstr , mkRegRegMoveInstr @@ -509,6 +510,13 @@ isJumpishInstr instr JMP{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo instr bid + = case instr of + BCC _ target _ -> target == bid + BCCFAR _ target _ -> target == bid + _ -> False + -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the ===================================== compiler/GHC/CmmToAsm/Reg/Liveness.hs ===================================== @@ -126,6 +126,11 @@ instance Instruction instr => Instruction (InstrSR instr) where Instr instr -> isJumpishInstr instr _ -> False + canFallthroughTo i bid + = case i of + Instr instr -> canFallthroughTo instr bid + _ -> False + jumpDestsOfInstr i = case i of Instr instr -> jumpDestsOfInstr instr ===================================== compiler/GHC/CmmToAsm/X86.hs ===================================== @@ -51,6 +51,7 @@ instance Instruction X86.Instr where patchRegsOfInstr = X86.patchRegsOfInstr isJumpishInstr = X86.isJumpishInstr jumpDestsOfInstr = X86.jumpDestsOfInstr + canFallthroughTo = X86.canFallthroughTo patchJumpInstr = X86.patchJumpInstr mkSpillInstr = X86.mkSpillInstr mkLoadInstr = X86.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -31,6 +31,7 @@ module GHC.CmmToAsm.X86.Instr , mkSpillInstr , mkRegRegMoveInstr , jumpDestsOfInstr + , canFallthroughTo , patchRegsOfInstr , patchJumpInstr , isMetaInstr @@ -669,6 +670,16 @@ isJumpishInstr instr CALL{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo insn bid + = case insn of + JXX _ target -> bid == target + JMP_TBL _ targets _ _ -> all isTargetBid targets + where + isTargetBid target = case target of + Nothing -> True + Just (DestBlockId target) -> target == bid + _ -> False jumpDestsOfInstr :: Instr ===================================== testsuite/tests/codeGen/should_run/T24507.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} + +module Main where + +import GHC.Exts + +foreign import prim "foo" foo :: Int# -> Int# + +main = do + + let f x = case x of I# x' -> case foo x' of x -> print (I# x) + mapM_ f [1..7] \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/T24507.stdout ===================================== @@ -0,0 +1,7 @@ +1 +2 +2 +2 +2 +2 +2 ===================================== testsuite/tests/codeGen/should_run/T24507_cmm.cmm ===================================== @@ -0,0 +1,35 @@ +#include "Cmm.h" + +bar() { + return (2); +} + +foo(W_ x) { + + switch(x) { + case 1: goto a; + case 2: goto b; + case 3: goto c; + case 4: goto d; + case 5: goto e; + case 6: goto f; + case 7: goto g; + } + return (1); + + a: + return (1); + b: + jump bar(); + c: + jump bar(); + d: + jump bar(); + e: + jump bar(); + f: + jump bar(); + g: + jump bar(); + +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/39a08d7159a369755e6c3978805de2e0819fd0bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/39a08d7159a369755e6c3978805de2e0819fd0bd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 14:42:28 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Fri, 05 Apr 2024 10:42:28 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Touch up the new Note Message-ID: <66100dd4c8a4e_180afb2299cb06115e@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 6eedc476 by Mikolaj Konarski at 2024-04-05T16:01:14+02:00 Touch up the new Note - - - - - 1 changed file: - compiler/GHC/Core/TyCo/Rep.hs Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1796,7 +1796,6 @@ In particular, given | tv `elemVarSet` acc = acc | otherwise = acc `extendVarSet` tv - we want to end up with fvs ty = go emptyVarSet ty emptyVarSet where @@ -1832,9 +1831,9 @@ Note [Use explicit recursion in foldTyCo] In foldTyCo you'll see things like: go_tys _ [] = mempty go_tys env (t:ts) = go_ty env t `mappend` go_tys env ts -where we use /explicit recursion/. You might wonder about using foldr instead: +where we use /explicit recursion/. You might wonder about using foldl instead: go_tys env = foldl (\t acc -> go_ty env t `mappend` acc) mempty -Or maybe or foldl', or foldr. +Or maybe foldl', or foldr. But don't do that for two reasons (see #24591) @@ -1848,7 +1847,7 @@ But don't do that for two reasons (see #24591) But in the foldl form that is /much/ less obvious, and the strictness analyser fails utterly. Result: lots and lots of thunks get built. In - !12037, Mikolaj found that GHC allocated allocated /six times/ as much heap + !12037, Mikolaj found that GHC allocated /six times/ as much heap on test perf/compiler/T9198 as a result of this single problem! * Second, while I think that using `foldr` would be fine (simple experiments in View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6eedc47691c7078c731a3e51db92b9c68bf35b3a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6eedc47691c7078c731a3e51db92b9c68bf35b3a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 15:35:28 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 05 Apr 2024 11:35:28 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 60 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <66101a407eb99_2ba06f5f6e14674c2@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - ed3fb50d by Fendor at 2024-04-05T13:14:59+01:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: T21839c ------------------------- - - - - - adf68fba by Fendor at 2024-04-05T15:13:12+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 87897928 by Matthew Pickering at 2024-04-05T17:20:36+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 19 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/043ed148bb082b93884dd0fac361cafd90f83abf...87897928c0e0e7f44ddfac6633ef1301a5d2778f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/043ed148bb082b93884dd0fac361cafd90f83abf...87897928c0e0e7f44ddfac6633ef1301a5d2778f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 16:24:14 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 05 Apr 2024 12:24:14 -0400 Subject: [Git][ghc/ghc][wip/T20749] 478 commits: Make forall a keyword (#23719) Message-ID: <661025aed6bf9_2ba06fba6c9c733dc@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 9d7cb414 by Sebastian Graf at 2024-04-05T16:04:01+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 68499bef by Sebastian Graf at 2024-04-05T18:24:00+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 18 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - .gitmodules - CODEOWNERS - compiler/GHC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12b80370a82b4191558aef01eb7203035193c0a2...68499bef56baf617dd17168c25437d8f692ba5d7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12b80370a82b4191558aef01eb7203035193c0a2...68499bef56baf617dd17168c25437d8f692ba5d7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 18:08:27 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 05 Apr 2024 14:08:27 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: compiler: Allow more types in GHCForeignImportPrim Message-ID: <66103e1b11704_2ba06f17d1d8c921ac@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - f7f3164e by Alan Zimmerman at 2024-04-05T14:08:10-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - 81bbfde9 by Matthew Pickering at 2024-04-05T14:08:11-04:00 Remove accidentally committed test.hs - - - - - 23 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/ThToHs.hs - − test.hs - testsuite/tests/ffi/should_fail/ccfail001.stderr - + testsuite/tests/ffi/should_run/T24598.hs - + testsuite/tests/ffi/should_run/T24598.stdout - + testsuite/tests/ffi/should_run/T24598_cmm.cmm - + testsuite/tests/ffi/should_run/T24598b.hs - + testsuite/tests/ffi/should_run/T24598b.stdout - + testsuite/tests/ffi/should_run/T24598b_cmm.cmm - + testsuite/tests/ffi/should_run/T24598c.hs - + testsuite/tests/ffi/should_run/T24598c.stdout - + testsuite/tests/ffi/should_run/T24598c_cmm.cmm - testsuite/tests/ffi/should_run/all.T - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1131,10 +1131,10 @@ type instance XForeignExport GhcTc = Coercion type instance XXForeignDecl (GhcPass _) = DataConCantHappen -type instance XCImport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCImport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignImport (GhcPass _) = DataConCantHappen -type instance XCExport (GhcPass _) = Located SourceText -- original source text for the C entity +type instance XCExport (GhcPass _) = LocatedE SourceText -- original source text for the C entity type instance XXForeignExport (GhcPass _) = DataConCantHappen -- pretty printing of foreign declarations @@ -1399,6 +1399,6 @@ type instance Anno (WarnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (AnnDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (RoleAnnotDecl (GhcPass p)) = SrcSpanAnnA type instance Anno (Maybe Role) = EpAnnCO -type instance Anno CCallConv = SrcSpan -type instance Anno Safety = SrcSpan -type instance Anno CExportSpec = SrcSpan +type instance Anno CCallConv = EpaLocation +type instance Anno Safety = EpaLocation +type instance Anno CExportSpec = EpaLocation ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -350,7 +350,7 @@ hsRecUpdFieldOcc = fmap unambiguousFieldOcc . hfbLHS instance Outputable (HsTyPat p) => Outputable (HsConPatTyArg p) where ppr (HsConPatTyArg _ ty) = char '@' <> ppr ty -instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ Located RecFieldsDotDot) +instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ LocatedE RecFieldsDotDot) => Outputable (HsRecFields p arg) where ppr (HsRecFields { rec_flds = flds, rec_dotdot = Nothing }) = braces (fsep (punctuate comma (map ppr flds))) @@ -976,4 +976,4 @@ type instance Anno (Pat (GhcPass p)) = SrcSpanAnnA type instance Anno (HsOverLit (GhcPass p)) = EpAnnCO type instance Anno ConLike = SrcSpanAnnN type instance Anno (HsFieldBind lhs rhs) = SrcSpanAnnA -type instance Anno RecFieldsDotDot = SrcSpan +type instance Anno RecFieldsDotDot = EpaLocation ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1830,7 +1830,7 @@ lPatImplicits = hs_lpat details (RecCon (HsRecFields { rec_dotdot = Nothing, rec_flds })) = hs_lpats $ map (hfbRHS . unLoc) rec_flds details (RecCon (HsRecFields { rec_dotdot = Just (L err_loc rec_dotdot), rec_flds })) - = [(err_loc, implicit_field_binders)] + = [(l2l err_loc, implicit_field_binders)] ++ hs_lpats explicit_pats where (explicit_pats, implicit_field_binders) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2095,15 +2095,15 @@ instance ToHie (LocatedA (ForeignDecl GhcRn)) where instance ToHie (ForeignImport GhcRn) where toHie (CImport (L c _) (L a _) (L b _) _ _) = concatM $ - [ locOnly a - , locOnly b - , locOnly c + [ locOnlyE a + , locOnlyE b + , locOnlyE c ] instance ToHie (ForeignExport GhcRn) where toHie (CExport (L b _) (L a _)) = concatM $ - [ locOnly a - , locOnly b + [ locOnlyE a + , locOnlyE b ] instance ToHie (LocatedA (WarnDecls GhcRn)) where ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -533,6 +533,10 @@ locOnly (RealSrcSpan span _) = do pure [Node e span []] locOnly _ = pure [] +locOnlyE :: Monad m => EpaLocation -> ReaderT NodeOrigin m [HieAST a] +locOnlyE (EpaSpan s) = locOnly s +locOnlyE _ = pure [] + mkScope :: (HasLoc a) => a -> Scope mkScope a = case getHasLoc a of (RealSrcSpan sp _) -> LocalScope sp ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -39,6 +39,7 @@ module GHC.Parser.Annotation ( -- ** Annotations in 'GenLocated' LocatedA, LocatedL, LocatedC, LocatedN, LocatedAn, LocatedP, SrcSpanAnnA, SrcSpanAnnL, SrcSpanAnnP, SrcSpanAnnC, SrcSpanAnnN, + LocatedE, -- ** Annotation data types used in 'GenLocated' @@ -644,6 +645,8 @@ type SrcSpanAnnL = EpAnn AnnList type SrcSpanAnnP = EpAnn AnnPragma type SrcSpanAnnC = EpAnn AnnContext +type LocatedE = GenLocated EpaLocation + -- | General representation of a 'GenLocated' type carrying a -- parameterised annotation type. type LocatedAn an = GenLocated (EpAnn an) @@ -1049,9 +1052,12 @@ reLoc (L la a) = L (noAnnSrcSpan $ locA (L la a) ) a class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e -instance HasAnnotation (SrcSpan) where +instance HasAnnotation SrcSpan where noAnnSrcSpan l = l +instance HasAnnotation EpaLocation where + noAnnSrcSpan l = EpaSpan l + instance (NoAnn ann) => HasAnnotation (EpAnn ann) where noAnnSrcSpan l = EpAnn (spanAsAnchor l) noAnn emptyComments @@ -1452,6 +1458,10 @@ instance (Outputable a, OutputableBndr e) pprInfixOcc = pprInfixOcc . unLoc pprPrefixOcc = pprPrefixOcc . unLoc +instance (Outputable e) + => Outputable (GenLocated EpaLocation e) where + ppr = pprLocated + instance Outputable ParenType where ppr t = text (show t) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2679,7 +2679,7 @@ mkRdrRecordCon con flds anns mk_rec_fields :: [LocatedA (HsRecField (GhcPass p) arg)] -> Maybe SrcSpan -> HsRecFields (GhcPass p) arg mk_rec_fields fs Nothing = HsRecFields { rec_flds = fs, rec_dotdot = Nothing } mk_rec_fields fs (Just s) = HsRecFields { rec_flds = fs - , rec_dotdot = Just (L s (RecFieldsDotDot $ length fs)) } + , rec_dotdot = Just (L (l2l s) (RecFieldsDotDot $ length fs)) } mk_rec_upd_field :: HsRecField GhcPs (LHsExpr GhcPs) -> HsRecUpdField GhcPs GhcPs mk_rec_upd_field (HsFieldBind noAnn (L loc (FieldOcc _ rdr)) arg pun) @@ -2766,7 +2766,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- name (cf section 8.5.1 in Haskell 2010 report). mkCImport = do let e = unpackFS entity - case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc esrc) of + case parseCImport (reLoc cconv) (reLoc safety) (mkExtName (unLoc v)) e (L loc esrc) of Nothing -> addFatalError $ mkPlainErrorMsgEnvelope loc $ PsErrMalformedEntityString Just importSpec -> return importSpec @@ -2782,7 +2782,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = then mkExtName (unLoc v) else entity funcTarget = CFunction (StaticTarget esrc entity' Nothing True) - importSpec = CImport (L loc esrc) cconv safety Nothing funcTarget + importSpec = CImport (L (l2l loc) esrc) (reLoc cconv) (reLoc safety) Nothing funcTarget returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport { fd_i_ext = ann @@ -2796,7 +2796,7 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) = -- the string "foo" is ambiguous: either a header or a C identifier. The -- C identifier case comes first in the alternatives below, so we pick -- that one. -parseCImport :: Located CCallConv -> Located Safety -> FastString -> String +parseCImport :: LocatedE CCallConv -> LocatedE Safety -> FastString -> String -> Located SourceText -> Maybe (ForeignImport (GhcPass p)) parseCImport cconv safety nm str sourceText = @@ -2826,7 +2826,7 @@ parseCImport cconv safety nm str sourceText = | id_char c -> pfail _ -> return () - mk h n = CImport sourceText cconv safety h n + mk h n = CImport (reLoc sourceText) (reLoc cconv) (reLoc safety) h n hdr_char c = not (isSpace c) -- header files are filenames, which can contain @@ -2861,7 +2861,7 @@ mkExport :: Located CCallConv mkExport (L lc cconv) (L le (StringLiteral esrc entity _), v, ty) = return $ \ann -> ForD noExtField $ ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty - , fd_fe = CExport (L le esrc) (L lc (CExportStatic esrc entity' cconv)) } + , fd_fe = CExport (L (l2l le) esrc) (L (l2l lc) (CExportStatic esrc entity' cconv)) } where entity' | nullFS entity = mkExtName (unLoc v) | otherwise = entity ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -775,7 +775,7 @@ rnHsRecPatsAndThen mk (L _ con) do { arg' <- rnLPatAndThen (nested_mk dd mk (RecFieldsDotDot n')) (hfbRHS fld) ; return (L l (fld { hfbRHS = arg' })) } - loc = maybe noSrcSpan getLoc dd + loc = maybe noSrcSpan getLocA dd -- Don't warn for let P{..} = ... in ... check_unused_wildcard = case mk of @@ -873,12 +873,12 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) , hfbRHS = arg' , hfbPun = pun } } - rn_dotdot :: Maybe (Located RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat + rn_dotdot :: Maybe (LocatedE RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat -> Maybe Name -- The constructor (Nothing for an -- out of scope constructor) -> [LHsRecField GhcRn (LocatedA arg)] -- Explicit fields -> RnM ([LHsRecField GhcRn (LocatedA arg)]) -- Field Labels we need to fill in - rn_dotdot (Just (L loc (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match + rn_dotdot (Just (L loc_e (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match | not (isUnboundName con) -- This test is because if the constructor -- isn't in scope the constructor lookup will add -- an error but still return an unbound name. We @@ -910,6 +910,7 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) _other -> True ] ; addUsedGREs NoDeprecationWarnings dot_dot_gres + ; let loc = locA loc_e ; let locn = noAnnSrcSpan loc ; return [ L (noAnnSrcSpan loc) (HsFieldBind { hfbAnn = noAnn ===================================== compiler/GHC/Tc/Gen/Foreign.hs ===================================== @@ -84,7 +84,6 @@ import Control.Monad.Trans.Writer.CPS import Control.Monad.Trans.Class ( lift ) import Data.Maybe (isJust) -import GHC.Types.RepType (tyConPrimRep) import GHC.Builtin.Types (unitTyCon) -- Defines a binding @@ -737,7 +736,6 @@ marshalablePrimTyCon tc = isPrimTyCon tc && not (isLiftedTypeKind (tyConResKind marshalableTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledReason marshalableTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | otherwise = boxedMarshalableTyCon tc @@ -772,7 +770,6 @@ legalFIPrimResultTyCon :: DynFlags -> TyCon -> Validity' TypeCannotBeMarshaledRe -- types and also unboxed tuple and sum result types. legalFIPrimResultTyCon dflags tc | marshalablePrimTyCon tc - , not (null (tyConPrimRep tc)) -- Note [Marshalling void] = validIfUnliftedFFITypes dflags | isUnboxedTupleTyCon tc || isUnboxedSumTyCon tc @@ -786,13 +783,3 @@ validIfUnliftedFFITypes dflags | xopt LangExt.UnliftedFFITypes dflags = IsValid | otherwise = NotValid UnliftedFFITypesNeeded -{- -Note [Marshalling void] -~~~~~~~~~~~~~~~~~~~~~~~ -We don't treat State# (whose PrimRep is VoidRep) as marshalable. -In turn that means you can't write - foreign import foo :: Int -> State# RealWorld - -Reason: the back end falls over with panic "primRepHint:VoidRep"; - and there is no compelling reason to permit it --} ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -799,7 +799,8 @@ cvt_fundep (TH.FunDep xs ys) = do { xs' <- mapM tNameN xs cvtForD :: Foreign -> CvtM (ForeignDecl GhcPs) cvtForD (ImportF callconv safety from nm ty) = - do { l <- getL + do { ls <- getL + ; let l = l2l ls ; if -- the prim and javascript calling conventions do not support headers -- and are inserted verbatim, analogous to mkImport in GHC.Parser.PostProcess | callconv == TH.Prim || callconv == TH.JavaScript @@ -809,7 +810,7 @@ cvtForD (ImportF callconv safety from nm ty) = True))) | Just impspec <- parseCImport (L l (cvt_conv callconv)) (L l safety') (mkFastString (TH.nameBase nm)) - from (L l $ quotedSourceText from) + from (L ls $ quotedSourceText from) -> mk_imp impspec | otherwise -> failWith $ InvalidCCallImpent from } @@ -831,7 +832,8 @@ cvtForD (ImportF callconv safety from nm ty) = cvtForD (ExportF callconv as nm ty) = do { nm' <- vNameN nm ; ty' <- cvtSigType ty - ; l <- getL + ; ls <- getL + ; let l = l2l ls ; let astxt = mkFastString as ; let e = CExport (L l (SourceText astxt)) (L l (CExportStatic (SourceText astxt) astxt ===================================== test.hs deleted ===================================== @@ -1,14 +0,0 @@ -import Data.Char -import Data.Foldable --- | Just like 'GHC.ResponseFile.escapeArg', but it is not exposed from base. -escapeArg :: String -> String -escapeArg = reverse . foldl' escape [] - -escape :: String -> Char -> String -escape cs c - | isSpace c - || '\\' == c - || '\'' == c - || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result - | otherwise = c:cs - ===================================== testsuite/tests/ffi/should_fail/ccfail001.stderr ===================================== @@ -1,6 +1,8 @@ -ccfail001.hs:10:1: error: [GHC-89401] +ccfail001.hs:10:1: error: [GHC-10964] • Unacceptable result type in foreign declaration: ‘State# RealWorld’ cannot be marshalled in a foreign call + UnliftedFFITypes is required to marshal unlifted types • When checking declaration: foreign import ccall safe foo :: Int -> State# RealWorld + Suggested fix: Perhaps you intended to use UnliftedFFITypes ===================================== testsuite/tests/ffi/should_run/T24598.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in results correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello >>= print + +hello :: IO Int +hello = IO $ \s -> case hello# s of (# s', n# #) -> (# s', I# n# #) ===================================== testsuite/tests/ffi/should_run/T24598.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello() { + return (42); +} ===================================== testsuite/tests/ffi/should_run/T24598b.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Int +import GHC.Exts + +foreign import prim "hello" + hello# :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +main :: IO () +main = hello 21 >>= print + +hello :: Int -> IO Int +hello (I# n#) = IO $ \s -> + case hello# n# s of (# s', n# #) -> (# s', I# n# #) + ===================================== testsuite/tests/ffi/should_run/T24598b.stdout ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ffi/should_run/T24598b_cmm.cmm ===================================== @@ -0,0 +1,5 @@ +#include "Cmm.h" + +hello(W_ n) { + return (2*n); +} ===================================== testsuite/tests/ffi/should_run/T24598c.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} + +-- | Test that `foreign import prim` imports handle `State#` in arguments correctly. +module Main where + +import GHC.IO +import GHC.Exts + +foreign import prim "hello" + hello# :: State# RealWorld -> State# RealWorld + +main :: IO () +main = hello + +hello :: IO () +hello = IO $ \s -> + case hello# s of s' -> (# s', () #) + ===================================== testsuite/tests/ffi/should_run/T24598c.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/ffi/should_run/T24598c_cmm.cmm ===================================== @@ -0,0 +1,15 @@ +#include "Cmm.h" + +#if !defined(UnregisterisedCompiler) +import CLOSURE test_str; +#endif + +section "data" { + test_str: bits8[] "hello"; +} + +hello() { + CInt r; + (r) = ccall puts(test_str "ptr"); + return (); +} ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -268,3 +268,7 @@ test('T24314', # libffi-wasm doesn't support more than 4 args yet when(arch('wasm32'), skip)], compile_and_run, ['T24314_c.c']) + +test('T24598', req_cmm, compile_and_run, ['T24598_cmm.cmm']) +test('T24598b', req_cmm, compile_and_run, ['T24598b_cmm.cmm']) +test('T24598c', req_cmm, compile_and_run, ['T24598c_cmm.cmm']) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -738,9 +738,9 @@ printStringAtAAC capture (EpaDelta d cs) s = do -- --------------------------------------------------------------------- -markExternalSourceText :: (Monad m, Monoid w) => SrcSpan -> SourceText -> String -> EP w m () -markExternalSourceText l NoSourceText txt = printStringAtRs (realSrcSpan l) txt >> return () -markExternalSourceText l (SourceText txt) _ = printStringAtRs (realSrcSpan l) (unpackFS txt) >> return () +markExternalSourceTextE :: (Monad m, Monoid w) => EpaLocation -> SourceText -> String -> EP w m EpaLocation +markExternalSourceTextE l NoSourceText txt = printStringAtAA l txt +markExternalSourceTextE l (SourceText txt) _ = printStringAtAA l (unpackFS txt) -- --------------------------------------------------------------------- @@ -1587,6 +1587,15 @@ instance (ExactPrint a) => ExactPrint (Located a) where exact (L l a) = L l <$> markAnnotated a +instance (ExactPrint a) => ExactPrint (LocatedE a) where + getAnnotationEntry (L l _) = Entry l [] emptyComments NoFlushComments CanUpdateAnchorOnly + setAnnotationAnchor (L _ a) anc _ts _cs = L anc a + + exact (L la a) = do + debugM $ "LocatedE a:la loc=" ++ show (ss2range $ locA la) + a' <- markAnnotated a + return (L la a') + instance (ExactPrint a) => ExactPrint (LocatedA a) where getAnnotationEntry = entryFromLocatedA setAnnotationAnchor la anc ts cs = setAnchorAn la anc ts cs @@ -2009,11 +2018,15 @@ instance ExactPrint (ForeignDecl GhcPs) where instance ExactPrint (ForeignImport GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CImport (L ls src) cconv safety@(L ll _) mh imp) = do + exact (CImport (L ls src) cconv safety@(L l _) mh imp) = do cconv' <- markAnnotated cconv - unless (ll == noSrcSpan) $ markAnnotated safety >> return () - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" >> return () - return (CImport (L ls src) cconv' safety mh imp) + safety' <- if notDodgyE l + then markAnnotated safety + else return safety + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CImport (L ls' src) cconv' safety' mh imp) -- --------------------------------------------------------------------- @@ -2023,8 +2036,10 @@ instance ExactPrint (ForeignExport GhcPs) where exact (CExport (L ls src) spec) = do debugM $ "CExport starting" spec' <- markAnnotated spec - unless (ls == noSrcSpan) $ markExternalSourceText ls src "" - return (CExport (L ls src) spec') + ls' <- if notDodgyE ls + then markExternalSourceTextE ls src "" + else return ls + return (CExport (L ls' src) spec') -- --------------------------------------------------------------------- @@ -3240,6 +3255,12 @@ markMaybeDodgyStmts an stmts = return (an, r) else return (an, stmts) +notDodgyE :: EpaLocation -> Bool +notDodgyE anc = + case anc of + EpaSpan s -> isGoodSrcSpan s + EpaDelta{} -> True + -- --------------------------------------------------------------------- instance ExactPrint (HsPragE GhcPs) where getAnnotationEntry HsPragSCC{} = NoEntryVal @@ -3307,12 +3328,13 @@ instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where setAnnotationAnchor a _ _ _ = a exact (HsRecFields fields mdot) = do fields' <- markAnnotated fields - case mdot of - Nothing -> return () - Just (L ss _) -> - printStringAtSs ss ".." >> return () + mdot' <- case mdot of + Nothing -> return Nothing + Just (L ss d) -> do + ss' <- printStringAtAA ss ".." + return $ Just (L ss' d) -- Note: mdot contains the SrcSpan where the ".." appears, if present - return (HsRecFields fields' mdot) + return (HsRecFields fields' mdot') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c52eb51a530ef4e6e6cf108056e87a74aecdeae1...81bbfde980e4a60daafd22de09609e91c261ae4a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c52eb51a530ef4e6e6cf108056e87a74aecdeae1...81bbfde980e4a60daafd22de09609e91c261ae4a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 20:58:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 05 Apr 2024 16:58:45 -0400 Subject: [Git][ghc/ghc][master] EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <66106605e0bf9_a58d32be83c10456@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - 5 changed files: - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Pat.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -350,7 +350,7 @@ hsRecUpdFieldOcc = fmap unambiguousFieldOcc . hfbLHS instance Outputable (HsTyPat p) => Outputable (HsConPatTyArg p) where ppr (HsConPatTyArg _ ty) = char '@' <> ppr ty -instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ Located RecFieldsDotDot) +instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ LocatedE RecFieldsDotDot) => Outputable (HsRecFields p arg) where ppr (HsRecFields { rec_flds = flds, rec_dotdot = Nothing }) = braces (fsep (punctuate comma (map ppr flds))) @@ -976,4 +976,4 @@ type instance Anno (Pat (GhcPass p)) = SrcSpanAnnA type instance Anno (HsOverLit (GhcPass p)) = EpAnnCO type instance Anno ConLike = SrcSpanAnnN type instance Anno (HsFieldBind lhs rhs) = SrcSpanAnnA -type instance Anno RecFieldsDotDot = SrcSpan +type instance Anno RecFieldsDotDot = EpaLocation ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1830,7 +1830,7 @@ lPatImplicits = hs_lpat details (RecCon (HsRecFields { rec_dotdot = Nothing, rec_flds })) = hs_lpats $ map (hfbRHS . unLoc) rec_flds details (RecCon (HsRecFields { rec_dotdot = Just (L err_loc rec_dotdot), rec_flds })) - = [(err_loc, implicit_field_binders)] + = [(l2l err_loc, implicit_field_binders)] ++ hs_lpats explicit_pats where (explicit_pats, implicit_field_binders) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2679,7 +2679,7 @@ mkRdrRecordCon con flds anns mk_rec_fields :: [LocatedA (HsRecField (GhcPass p) arg)] -> Maybe SrcSpan -> HsRecFields (GhcPass p) arg mk_rec_fields fs Nothing = HsRecFields { rec_flds = fs, rec_dotdot = Nothing } mk_rec_fields fs (Just s) = HsRecFields { rec_flds = fs - , rec_dotdot = Just (L s (RecFieldsDotDot $ length fs)) } + , rec_dotdot = Just (L (l2l s) (RecFieldsDotDot $ length fs)) } mk_rec_upd_field :: HsRecField GhcPs (LHsExpr GhcPs) -> HsRecUpdField GhcPs GhcPs mk_rec_upd_field (HsFieldBind noAnn (L loc (FieldOcc _ rdr)) arg pun) ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -775,7 +775,7 @@ rnHsRecPatsAndThen mk (L _ con) do { arg' <- rnLPatAndThen (nested_mk dd mk (RecFieldsDotDot n')) (hfbRHS fld) ; return (L l (fld { hfbRHS = arg' })) } - loc = maybe noSrcSpan getLoc dd + loc = maybe noSrcSpan getLocA dd -- Don't warn for let P{..} = ... in ... check_unused_wildcard = case mk of @@ -873,12 +873,12 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) , hfbRHS = arg' , hfbPun = pun } } - rn_dotdot :: Maybe (Located RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat + rn_dotdot :: Maybe (LocatedE RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat -> Maybe Name -- The constructor (Nothing for an -- out of scope constructor) -> [LHsRecField GhcRn (LocatedA arg)] -- Explicit fields -> RnM ([LHsRecField GhcRn (LocatedA arg)]) -- Field Labels we need to fill in - rn_dotdot (Just (L loc (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match + rn_dotdot (Just (L loc_e (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match | not (isUnboundName con) -- This test is because if the constructor -- isn't in scope the constructor lookup will add -- an error but still return an unbound name. We @@ -910,6 +910,7 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) _other -> True ] ; addUsedGREs NoDeprecationWarnings dot_dot_gres + ; let loc = locA loc_e ; let locn = noAnnSrcSpan loc ; return [ L (noAnnSrcSpan loc) (HsFieldBind { hfbAnn = noAnn ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -3328,12 +3328,13 @@ instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where setAnnotationAnchor a _ _ _ = a exact (HsRecFields fields mdot) = do fields' <- markAnnotated fields - case mdot of - Nothing -> return () - Just (L ss _) -> - printStringAtSs ss ".." >> return () + mdot' <- case mdot of + Nothing -> return Nothing + Just (L ss d) -> do + ss' <- printStringAtAA ss ".." + return $ Just (L ss' d) -- Note: mdot contains the SrcSpan where the ".." appears, if present - return (HsRecFields fields' mdot) + return (HsRecFields fields' mdot') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19883a23b8bc704118fa663d8bab00a503b5a527 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19883a23b8bc704118fa663d8bab00a503b5a527 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 20:59:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 05 Apr 2024 16:59:25 -0400 Subject: [Git][ghc/ghc][master] Remove accidentally committed test.hs Message-ID: <6610662d10708_a58d33d7fc01075cf@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 1 changed file: - − test.hs Changes: ===================================== test.hs deleted ===================================== @@ -1,14 +0,0 @@ -import Data.Char -import Data.Foldable --- | Just like 'GHC.ResponseFile.escapeArg', but it is not exposed from base. -escapeArg :: String -> String -escapeArg = reverse . foldl' escape [] - -escape :: String -> Char -> String -escape cs c - | isSpace c - || '\\' == c - || '\'' == c - || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result - | otherwise = c:cs - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8724327d995a67d3eb066dfe4f9ee03e64dd6b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8724327d995a67d3eb066dfe4f9ee03e64dd6b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 21:25:47 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 05 Apr 2024 17:25:47 -0400 Subject: [Git][ghc/ghc][wip/bump-terminfo] 4487 commits: Remove outdated note about pragma layout Message-ID: <66106c5b6cb87_a58d38a7e3810812e@gitlab.mail> Ben Gamari pushed to branch wip/bump-terminfo at Glasgow Haskell Compiler / GHC Commits: 62b4a89b by taylorfausak at 2021-09-28T09:57:37-04:00 Remove outdated note about pragma layout - - - - - 028abd5b by Benjamin Maurer at 2021-09-28T09:58:13-04:00 Documented yet undocumented dump flags #18641 - - - - - b8d98827 by Richard Eisenberg at 2021-09-29T09:40:14-04:00 Compare FunTys as if they were TyConApps. See Note [Equality on FunTys] in TyCoRep. Close #17675. Close #17655, about documentation improvements included in this patch. Close #19677, about a further mistake around FunTy. test cases: typecheck/should_compile/T19677 - - - - - be77a9e0 by Fabian Thorand at 2021-09-29T09:40:51-04:00 Remove special case for large objects in allocateForCompact allocateForCompact() is called when the current allocation for the compact region does not fit in the nursery. It previously had a special case for objects exceeding the large object threshold. In that case, it would allocate a new compact region block just for that object. That led to a lot of small blocks being allocated in compact regions with a larger default block size (`autoBlockW`). This commit removes this special case because having a lot of small compact region blocks contributes significantly to memory fragmentation. The removal should be valid because - a more generic case for allocating a new compact region block follows at the end of allocateForCompact(), and that one takes `autoBlockW` into account - the reason for allocating separate blocks for large objects in the main heap seems to be to avoid copying during GCs, but once inside the compact region, the object will never be copied anyway. Fixes #18757. A regression test T18757 was added. - - - - - cd603062 by Kirill Zaborsky at 2021-09-29T09:41:27-04:00 Fix comment typos - - - - - 162492ea by Alexander Kjeldaas at 2021-09-29T09:41:27-04:00 Document interaction between unsafe FFI and GC In the multi-threaded RTS this can lead to hard to debug performance issues. - - - - - 361da88a by Kamil Dworakowski at 2021-09-29T09:42:04-04:00 Add a regression test for #17912 - - - - - 5cc4bd57 by Benjamin Maurer at 2021-09-29T09:42:41-04:00 Rectifying COMMENT and `mkComment` across platforms to work with SDoc and exhibit similar behaviors. Issue 20400 - - - - - a2be9f34 by Ziyang Liu at 2021-09-29T09:43:19-04:00 Document that `eqType`/`coreView` do not look through type families This isn't clear from the existing doc. - - - - - c668fd2c by Andrea Condoluci at 2021-09-29T09:44:04-04:00 TH stage restriction check for constructors, selectors, and class methods Closes ticket #17820. - - - - - d46e34d0 by Andrea Condoluci at 2021-09-29T09:44:04-04:00 Add tests for T17820 - - - - - 770fcac8 by Ben Gamari at 2021-09-29T09:44:40-04:00 GHC: Drop dead packageDbModules It was already commented out and contained a reference to the non-deterministic nameEnvElts so let's just drop it. - - - - - 42492b76 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Reimplement seqEltsUFM in terms of fold Rather than nonDetEltsUFM; this should eliminate some unnecessary list allocations. - - - - - 97ffd6d9 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Rewrite all eltsUFM occurrences to nonDetEltsUFM And remove the former. - - - - - df8c5961 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Fix name of GHC.Core.TyCon.Env.nameEnvElts Rename to nonDetTyConEnvElts. - - - - - 1f2ba67a by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Make nubAvails deterministic Surprisingly this previously didn't appear to introduce any visible non-determinism but it seems worth avoiding non-determinism here. - - - - - 7c90a180 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Rename nameEnvElts -> nonDetNameEnvElts - - - - - 2e68d4fa by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Use seqEltsNameEnv rather that nameEnvElts - - - - - f66eaefd by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: occEnvElts -> nonDetOccEnvElts - - - - - 594ee2f4 by Matthew Pickering at 2021-09-30T00:56:30-04:00 testsuite: Make cabal01 more robust to large environments Sebastian unfortunately wrote a very long commit message in !5667 which caused `xargs` to fail on windows because the environment was too big. Fortunately `xargs` and `rm` don't need anything from the environment so just run those commands in an empty environment (which is what env -i achieves). - - - - - c261f220 by Sebastian Graf at 2021-09-30T00:56:30-04:00 Nested CPR light unleashed (#18174) This patch enables worker/wrapper for nested constructed products, as described in `Note [Nested CPR]`. The machinery for expressing Nested CPR was already there, since !5054. Worker/wrapper is equipped to exploit Nested CPR annotations since !5338. CPR analysis already handles applications in batches since !5753. This patch just needs to flip a few more switches: 1. In `cprTransformDataConWork`, we need to look at the field expressions and their `CprType`s to see whether the evaluation of the expressions terminates quickly (= is in HNF) or if they are put in strict fields. If that is the case, then we retain their CPR info and may unbox nestedly later on. More details in `Note [Nested CPR]`. 2. Enable nested `ConCPR` signatures in `GHC.Types.Cpr`. 3. In the `asConCpr` call in `GHC.Core.Opt.WorkWrap.Utils`, pass CPR info of fields to the `Unbox`. 4. Instead of giving CPR signatures to DataCon workers and wrappers, we now have `cprTransformDataConWork` for workers and treat wrappers by analysing their unfolding. As a result, the code from GHC.Types.Id.Make went away completely. 5. I deactivated worker/wrappering for recursive DataCons and wrote a function `isRecDataCon` to detect them. We really don't want to give `repeat` or `replicate` the Nested CPR property. See Note [CPR for recursive data structures] for which kind of recursive DataCons we target. 6. Fix a couple of tests and their outputs. I also documented that CPR can destroy sharing and lead to asymptotic increase in allocations (which is tracked by #13331/#19326) in `Note [CPR for data structures can destroy sharing]`. Nofib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- ben-raytrace -3.1% -0.4% binary-trees +0.8% -2.9% digits-of-e2 +5.8% +1.2% event +0.8% -2.1% fannkuch-redux +0.0% -1.4% fish 0.0% -1.5% gamteb -1.4% -0.3% mkhprog +1.4% +0.8% multiplier +0.0% -1.9% pic -0.6% -0.1% reptile -20.9% -17.8% wave4main +4.8% +0.4% x2n1 -100.0% -7.6% -------------------------------------------------------------------------------- Min -95.0% -17.8% Max +5.8% +1.2% Geometric Mean -2.9% -0.4% ``` The huge wins in x2n1 (loopy list) and reptile (see #19970) are due to refraining from unboxing (:). Other benchmarks like digits-of-e2 or wave4main regress because of that. Ultimately there are no great improvements due to Nested CPR alone, but at least it's a win. Binary sizes decrease by 0.6%. There are a significant number of metric decreases. The most notable ones (>1%): ``` ManyAlternatives(normal) ghc/alloc 771656002.7 762187472.0 -1.2% ManyConstructors(normal) ghc/alloc 4191073418.7 4114369216.0 -1.8% MultiLayerModules(normal) ghc/alloc 3095678333.3 3128720704.0 +1.1% PmSeriesG(normal) ghc/alloc 50096429.3 51495664.0 +2.8% PmSeriesS(normal) ghc/alloc 63512989.3 64681600.0 +1.8% PmSeriesV(normal) ghc/alloc 62575424.0 63767208.0 +1.9% T10547(normal) ghc/alloc 29347469.3 29944240.0 +2.0% T11303b(normal) ghc/alloc 46018752.0 47367576.0 +2.9% T12150(optasm) ghc/alloc 81660890.7 82547696.0 +1.1% T12234(optasm) ghc/alloc 59451253.3 60357952.0 +1.5% T12545(normal) ghc/alloc 1705216250.7 1751278952.0 +2.7% T12707(normal) ghc/alloc 981000472.0 968489800.0 -1.3% GOOD T13056(optasm) ghc/alloc 389322664.0 372495160.0 -4.3% GOOD T13253(normal) ghc/alloc 337174229.3 341954576.0 +1.4% T13701(normal) ghc/alloc 2381455173.3 2439790328.0 +2.4% BAD T14052(ghci) ghc/alloc 2162530642.7 2139108784.0 -1.1% T14683(normal) ghc/alloc 3049744728.0 2977535064.0 -2.4% GOOD T14697(normal) ghc/alloc 362980213.3 369304512.0 +1.7% T15164(normal) ghc/alloc 1323102752.0 1307480600.0 -1.2% T15304(normal) ghc/alloc 1304607429.3 1291024568.0 -1.0% T16190(normal) ghc/alloc 281450410.7 284878048.0 +1.2% T16577(normal) ghc/alloc 7984960789.3 7811668768.0 -2.2% GOOD T17516(normal) ghc/alloc 1171051192.0 1153649664.0 -1.5% T17836(normal) ghc/alloc 1115569746.7 1098197592.0 -1.6% T17836b(normal) ghc/alloc 54322597.3 55518216.0 +2.2% T17977(normal) ghc/alloc 47071754.7 48403408.0 +2.8% T17977b(normal) ghc/alloc 42579133.3 43977392.0 +3.3% T18923(normal) ghc/alloc 71764237.3 72566240.0 +1.1% T1969(normal) ghc/alloc 784821002.7 773971776.0 -1.4% GOOD T3294(normal) ghc/alloc 1634913973.3 1614323584.0 -1.3% GOOD T4801(normal) ghc/alloc 295619648.0 292776440.0 -1.0% T5321FD(normal) ghc/alloc 278827858.7 276067280.0 -1.0% T5631(normal) ghc/alloc 586618202.7 577579960.0 -1.5% T5642(normal) ghc/alloc 494923048.0 487927208.0 -1.4% T5837(normal) ghc/alloc 37758061.3 39261608.0 +4.0% T9020(optasm) ghc/alloc 257362077.3 254672416.0 -1.0% T9198(normal) ghc/alloc 49313365.3 50603936.0 +2.6% BAD T9233(normal) ghc/alloc 704944258.7 685692712.0 -2.7% GOOD T9630(normal) ghc/alloc 1476621560.0 1455192784.0 -1.5% T9675(optasm) ghc/alloc 443183173.3 433859696.0 -2.1% GOOD T9872a(normal) ghc/alloc 1720926653.3 1693190072.0 -1.6% GOOD T9872b(normal) ghc/alloc 2185618061.3 2162277568.0 -1.1% GOOD T9872c(normal) ghc/alloc 1765842405.3 1733618088.0 -1.8% GOOD TcPlugin_RewritePerf(normal) ghc/alloc 2388882730.7 2365504696.0 -1.0% WWRec(normal) ghc/alloc 607073186.7 597512216.0 -1.6% T9203(normal) run/alloc 107284064.0 102881832.0 -4.1% haddock.Cabal(normal) run/alloc 24025329589.3 23768382560.0 -1.1% haddock.base(normal) run/alloc 25660521653.3 25370321824.0 -1.1% haddock.compiler(normal) run/alloc 74064171706.7 73358712280.0 -1.0% ``` The biggest exception to the rule is T13701 which seems to fluctuate as usual (not unlike T12545). T14697 has a similar quality, being a generated multi-module test. T5837 is small enough that it similarly doesn't measure anything significant besides module loading overhead. T13253 simply does one additional round of Simplification due to Nested CPR. There are also some apparent regressions in T9198, T12234 and PmSeriesG that we (@mpickering and I) were simply unable to reproduce locally. @mpickering tried to run the CI script in a local Docker container and actually found that T9198 and PmSeriesG *improved*. In MRs that were rebased on top this one, like !4229, I did not experience such increases. Let's not get hung up on these regression tests, they were meant to test for asymptotic regressions. The build-cabal test improves by 1.2% in -O0. Metric Increase: T10421 T12234 T12545 T13035 T13056 T13701 T14697 T18923 T5837 T9198 Metric Decrease: ManyConstructors T12545 T12707 T13056 T14683 T16577 T18223 T1969 T3294 T9203 T9233 T9675 T9872a T9872b T9872c T9961 TcPlugin_RewritePerf - - - - - 205f0f92 by Andrea Condoluci at 2021-09-30T00:57:09-04:00 Trees That Grow refactor for HsTick and HsBinTick Move HsTick and HsBinTick to XExpr, the extension tree of HsExpr. Part of #16830 . - - - - - e0923b98 by Ben Gamari at 2021-09-30T00:57:44-04:00 ghc-boot: Eliminate unnecessary use of getEnvironment Previously we were using `System.Environment.getEnvironment`, which decodes all environment variables into Haskell `String`s, where a simple environment lookup would do. This made the compiler's allocations unnecessarily dependent on the environment. Fixes #20431. - - - - - 941d3792 by Sylvain Henry at 2021-09-30T19:41:09-04:00 Rules for sized conversion primops (#19769) Metric Decrease: T12545 - - - - - adc41a77 by Matthew Pickering at 2021-09-30T19:41:44-04:00 driver: Fix -E -XCPP, copy output from CPP ouput rather than .hs output Fixes #20416 I thought about adding a test for this case but I struggled to think of something robust. Grepping -v3 will include different paths on different systems and the structure of the result file depends on which preprocessor you are using. - - - - - 94f3ce7e by Matthew Pickering at 2021-09-30T19:42:19-04:00 Recompilation: Handle -plugin-package correctly If a plugins was specified using the -plugin-package-(id) flag then the module it applied to was always recompiled. The recompilation checker was previously using `findImportedModule`, which looked for packages in the HPT and then in the package database but only for modules specified using `-package`. The correct lookup function for plugins is `findPluginModule`, therefore we check normal imports with `findImportedModule` and plugins with `findPluginModule`. Fixes #20417 - - - - - ef92a009 by Andreas Klebinger at 2021-09-30T19:42:54-04:00 NCG: Linear-reg-alloc: A few small implemenation tweaks. Removed an intermediate list via a fold. realRegsAlias: Manually inlined the list functions to get better code. Linear.hs added a bang somewhere. - - - - - 9606774d by Aaron Allen at 2021-10-01T09:04:10-04:00 Convert Diagnostics GHC.Tc.Gen.* (Part 3) Converts all diagnostics in the `GHC.Tc.Gen.Expr` module. (#20116) - - - - - 9600a5fb by Matthew Pickering at 2021-10-01T09:04:46-04:00 code gen: Improve efficiency of findPrefRealReg Old strategy: For each variable linearly scan through all the blocks and check to see if the variable is any of the block register mappings. This is very slow when you have a lot of blocks. New strategy: Maintain a map from virtual registers to the first real register the virtual register was assigned to. Consult this map in findPrefRealReg. The map is updated when the register mapping is updated and is hidden behind the BlockAssigment abstraction. On the mmark package this reduces compilation time from about 44s to 32s. Ticket: #19471 - - - - - e3701815 by Matthew Pickering at 2021-10-01T09:05:20-04:00 ci: Unset CI_* variables before run_hadrian and test_make The goal here is to somewhat sanitize the environment so that performance tests don't fluctuate as much as they have been doing. In particular the length of the commit message was causing benchmarks to increase because gitlab stored the whole commit message twice in environment variables. Therefore when we used `getEnvironment` it would cause more allocation because more string would be created. See #20431 ------------------------- Metric Decrease: T10421 T13035 T18140 T18923 T9198 T12234 T12425 ------------------------- - - - - - e401274a by Ben Gamari at 2021-10-02T05:18:03-04:00 gitlab-ci: Bump docker images To install libncurses-dev on Debian targets. - - - - - 42f49c4e by Ben Gamari at 2021-10-02T05:18:03-04:00 Bump terminfo submodule to 0.4.1.5 Closes #20307. - - - - - cb862ecf by Andreas Schwab at 2021-10-02T05:18:40-04:00 CmmToLlvm: Sign/Zero extend parameters for foreign calls on RISC-V Like S390 and PPC64, RISC-V requires parameters for foreign calls to be extended to full words. - - - - - 0d455a18 by Richard Eisenberg at 2021-10-02T05:19:16-04:00 Use eqType, not tcEqType, in metavar kind check Close #20356. See addendum to Note [coreView vs tcView] in GHC.Core.Type for the details. Also killed old Note about metaTyVarUpdateOK, which has been gone for some time. test case: typecheck/should_fail/T20356 - - - - - 4264e74d by Ben Gamari at 2021-10-02T05:19:51-04:00 rts: Add missing write barriers in MVar wake-up paths Previously PerformPut failed to respect the non-moving collector's snapshot invariant, hiding references to an MVar and its new value by overwriting a stack frame without dirtying the stack. Fix this. PerformTake exhibited a similar bug, failing to dirty (and therefore mark) the blocked stack before mutating it. Closes #20399. - - - - - 040c347e by Ben Gamari at 2021-10-02T05:19:51-04:00 rts: Unify stack dirtiness check This fixes an inconsistency where one dirtiness check would not mask out the STACK_DIRTY flag, meaning it may also be affected by the STACK_SANE flag. - - - - - 4bdafb48 by Sylvain Henry at 2021-10-02T05:20:29-04:00 Add (++)/literal rule When we derive the Show instance of the big record in #16577, I get the following compilation times (with -O): Before: 0.91s After: 0.77s Metric Decrease: T19695 - - - - - 8b3d98ff by Sylvain Henry at 2021-10-02T05:21:07-04:00 Don't use FastString for UTF-8 encoding only - - - - - f4554f1d by Ben Gamari at 2021-10-03T14:23:36-04:00 ci: Use https:// transport and access token to push perf notes Previously we would push perf notes using a standard user and SSH key-based authentication. However, configuring SSH is unnecessarily fiddling. We now rather use HTTPS and a project access token. - - - - - 91cd1248 by Ben Gamari at 2021-10-03T14:23:45-04:00 ci/test-metrics: Clean up various bash quoting issues - - - - - ed0e29f1 by Ben Gamari at 2021-10-03T23:24:37-04:00 base: Update Unicode database to 14.0 Closes #20404. - - - - - e8693713 by Ben Gamari at 2021-10-03T23:25:11-04:00 configure: Fix redundant-argument warning from -no-pie check Modern clang versions are quite picky when it comes to reporting redundant arguments. In particular, they will warn when -no-pie is passed when no linking is necessary. Previously the configure script used a `$CC -Werror -no-pie -E` invocation to test whether `-no-pie` is necessary. Unfortunately, this meant that clang would throw a redundant argument warning, causing configure to conclude that `-no-pie` was not supported. We now rather use `$CC -Werror -no-pie`, ensuring that linking is necessary and avoiding this failure mode. Fixes #20463. - - - - - b3267fad by Sylvain Henry at 2021-10-04T08:28:23+00:00 Constant folding for negate (#20347) Only for small integral types for now. - - - - - 2308a130 by Vladislav Zavialov at 2021-10-04T18:44:07-04:00 Clean up HiePass constraints - - - - - 40c81dd2 by Matthew Pickering at 2021-10-04T23:45:11-04:00 ci: Run hadrian builds verbosely, but not tests This reduces the output from the testsuite to a more manageable level. Fixes #20432 - - - - - 347537a5 by Ben Gamari at 2021-10-04T23:45:46-04:00 compiler: Improve Haddocks of atomic MachOps - - - - - a0f44ceb by Ben Gamari at 2021-10-04T23:45:46-04:00 compiler: Fix racy ticker counter registration Previously registration of ticky entry counters was racy, performing a read-modify-write to add the new counter to the ticky_entry_ctrs list. This could result in the list becoming cyclic if multiple threads entered the same closure simultaneously. Fixes #20451. - - - - - a7629334 by Vladislav Zavialov at 2021-10-04T23:46:21-04:00 Bespoke TokenLocation data type The EpaAnnCO we were using contained an Anchor instead of EpaLocation, making it harder to work with. At the same time, using EpaLocation by itself isn't possible either, as we may have tokens without location information. Hence the new data type: data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation - - - - - a14d0e63 by sheaf at 2021-10-04T23:46:58-04:00 Bump TcLevel of failing kind equality implication Not bumping the TcLevel meant that we could end up trying to add evidence terms for the implication constraint created to wrap failing kind equalities (to avoid their deferral). fixes #20043 - - - - - 48b0f17a by sheaf at 2021-10-04T23:47:35-04:00 Add a regression test for #17723 The underlying bug was fixed by b8d98827, see MR !2477 - - - - - 5601b9e2 by Matthías Páll Gissurarson at 2021-10-05T03:18:39-04:00 Speed up valid hole-fits by adding early abort and checks. By adding an early abort flag in `TcSEnv`, we can fail fast in the presence of insoluble constraints. This helps us avoid a lot of work in valid hole-fits, and we geta massive speed-up by avoiding a lot of useless work solving constraints that never come into play. Additionally, we add a simple check for degenerate hole types, such as when the type of the hole is an immutable type variable (as is the case when the hole is completely unconstrained). Then the only valid fits are the locals, so we can ignore the global candidates. This fixes #16875 - - - - - 298df16d by Krzysztof Gogolewski at 2021-10-05T03:19:14-04:00 Reject type family equation with wrong name (#20260) We should reject "type family Foo where Bar = ()". This check was done in kcTyFamInstEqn but not in tcTyFamInstEqn. I factored out arity checking, which was duplicated. - - - - - 643b6f01 by Sebastian Graf at 2021-10-05T14:32:51-04:00 WorkWrap: Nuke CPR signatures of join points (#18824) In #18824 we saw that the Simplifier didn't nuke a CPR signature of a join point when it pushed a continuation into it when it better should have. But join points are local, mostly non-exported bindings. We don't use their CPR signature anyway and would discard it at the end of the Core pipeline. Their main purpose is to propagate CPR info during CPR analysis and by the time worker/wrapper runs the signature will have served its purpose. So we zap it! Fixes #18824. - - - - - b4c0cc36 by Sebastian Graf at 2021-10-05T14:32:51-04:00 Simplifier: Get rid of demand zapping based on Note [Arity decrease] The examples in the Note were inaccurate (`$s$dm` has arity 1 and that seems OK) and the code didn't actually nuke the demand *signature* anyway. Specialise has to nuke it, but it starts from a clean IdInfo anyway (in `newSpecIdM`). So I just deleted the code. Fixes #20450. - - - - - cd1b016f by Sebastian Graf at 2021-10-05T14:32:51-04:00 CprAnal: Activate Sum CPR for local bindings We've had Sum CPR (#5075) for top-level bindings for a couple of years now. That begs the question why we didn't also activate it for local bindings, and the reasons for that are described in `Note [CPR for sum types]`. Only that it didn't make sense! The Note said that Sum CPR would destroy let-no-escapes, but that should be a non-issue since we have syntactic join points in Core now and we don't WW for them (`Note [Don't w/w join points for CPR]`). So I simply activated CPR for all bindings of sum type, thus fixing #5075 and \#16570. NoFib approves: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- comp_lab_zift -0.0% +0.7% fluid +1.7% +0.7% reptile +0.1% +0.1% -------------------------------------------------------------------------------- Min -0.0% -0.2% Max +1.7% +0.7% Geometric Mean +0.0% +0.0% ``` There were quite a few metric decreases on the order of 1-4%, but T6048 seems to regress significantly, by 26.1%. WW'ing for a `Just` constructor and the nested data type meant additional Simplifier iterations and a 30% increase in term sizes as well as a 200-300% in type sizes due to unboxed 9-tuples. There's not much we can do about it, I'm afraid: We're just doing much more work there. Metric Decrease: T12425 T18698a T18698b T20049 T9020 WWRec Metric Increase: T6048 - - - - - 000f2a30 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Address some Foldable documentation nits - Add link to laws from the class head - Simplify wording of left/right associativity intro paragraph - Avoid needless mention of "endomorphisms" - - - - - 7059a729 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Add laws link and tweak Traversable class text - - - - - 43358ab9 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Note linear `elem` cost This is a writeup of the state of play for better than linear `elem` via a helper type class. - - - - - 56899c8d by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Note elem ticket 20421 - - - - - fb6b772f by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Minor wording tweaks/fixes - - - - - f49c7012 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Adopt David Feuer's explantion of foldl' via foldr - - - - - 5282eaa1 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Explain Endo, Dual, ... in laws - - - - - f52df067 by Alfredo Di Napoli at 2021-10-05T14:34:04-04:00 Make GHC.Utils.Error.Validity type polymorphic This commit makes the `Validity` type polymorphic: ``` data Validity' a = IsValid -- ^ Everything is fine | NotValid a -- ^ A problem, and some indication of why -- | Monomorphic version of @Validity'@ specialised for 'SDoc's. type Validity = Validity' SDoc ``` The type has been (provisionally) renamed to Validity' to not break existing code, as the monomorphic `Validity` type is quite pervasive in a lot of signatures in GHC. Why having a polymorphic Validity? Because it carries the evidence of "what went wrong", but the old type carried an `SDoc`, which clashed with the new GHC diagnostic infrastructure (#18516). Having it polymorphic it means we can carry an arbitrary, richer diagnostic type, and this is very important for things like the `checkOriginativeSideConditions` function, which needs to report the actual diagnostic error back to `GHC.Tc.Deriv`. It also generalises Validity-related functions to be polymorphic in @a at . - - - - - ac275f42 by Alfredo Di Napoli at 2021-10-05T14:34:04-04:00 Eradicate TcRnUnknownMessage from GHC.Tc.Deriv This (big) commit finishes porting the GHC.Tc.Deriv module to support the new diagnostic infrastructure (#18516) by getting rid of the legacy calls to `TcRnUnknownMessage`. This work ended up being quite pervasive and touched not only the Tc.Deriv module but also the Tc.Deriv.Utils and Tc.Deriv.Generics module, which needed to be adapted to use the new infrastructure. This also required generalising `Validity`. More specifically, this is a breakdown of the work done: * Add and use the TcRnUselessTypeable data constructor * Add and use TcRnDerivingDefaults data constructor * Add and use the TcRnNonUnaryTypeclassConstraint data constructor * Add and use TcRnPartialTypeSignatures * Add T13324_compile2 test to test another part of the TcRnPartialTypeSignatures diagnostic * Add and use TcRnCannotDeriveInstance data constructor, which introduces a new data constructor to TcRnMessage called TcRnCannotDeriveInstance, which is further sub-divided to carry a `DeriveInstanceErrReason` which explains the reason why we couldn't derive a typeclass instance. * Add DerivErrSafeHaskellGenericInst data constructor to DeriveInstanceErrReason * Add DerivErrDerivingViaWrongKind and DerivErrNoEtaReduce * Introduce the SuggestExtensionInOrderTo Hint, which adds (and use) a new constructor to the hint type `LanguageExtensionHint` called `SuggestExtensionInOrderTo`, which can be used to give a bit more "firm" recommendations when it's obvious what the required extension is, like in the case for the `DerivingStrategies`, which automatically follows from having enabled both `DeriveAnyClass` and `GeneralizedNewtypeDeriving`. * Wildcard-free pattern matching in mk_eqn_stock, which removes `_` in favour of pattern matching explicitly on `CanDeriveAnyClass` and `NonDerivableClass`, because that determine whether or not we can suggest to the user `DeriveAnyClass` or not. - - - - - 52400ebb by Simon Peyton Jones at 2021-10-05T14:34:39-04:00 Ensure top-level binders in scope in SetLevels Ticket #20200 (the Agda failure) showed another case in which lookupIdSubst would fail to find a local Id in the InScopeSet. This time it was because SetLevels was given a program in which the top-level bindings were not in dependency order. The Simplifier (see Note [Glomming] in GHC.Core.Opt.Occuranal) and the specialiser (see Note [Top level scope] in GHC.Core.Opt.Specialise) may both produce top-level bindings where an early binding refers to a later one. One solution would be to run the occurrence analyser again to put them all in the right order. But a simpler one is to make SetLevels OK with this input by bringing all top-level binders into scope at the start. That's what this patch does. - - - - - 11240b74 by Sylvain Henry at 2021-10-05T14:35:17-04:00 Constant folding for (.&.) maxBound (#20448) - - - - - 29ee04f3 by Zubin Duggal at 2021-10-05T14:35:52-04:00 docs: Clarify documentation of `getFileSystemEncoding` (#20344) It may not always be a Unicode encoding - - - - - 435ff398 by Mann mit Hut at 2021-10-06T00:11:07-04:00 Corrected types of thread ids obtained from the RTS While the thread ids had been changed to 64 bit words in e57b7cc6d8b1222e0939d19c265b51d2c3c2b4c0 the return type of the foreign import function used to retrieve these ids - namely 'GHC.Conc.Sync.getThreadId' - was never updated accordingly. In order to fix that this function returns now a 'CUULong'. In addition to that the types used in the thread labeling subsystem were adjusted as well and several format strings were modified throughout the whole RTS to display thread ids in a consistent and correct way. Fixes #16761 - - - - - 89e98bdf by Alan Zimmerman at 2021-10-06T00:11:42-04:00 EPA: Remove duplicate AnnOpenP/AnnCloseP in DataDecl The parens EPAs were added in the tyvars where they belong, but also at the top level of the declaration. Closes #20452 - - - - - fc4c7ffb by Ryan Scott at 2021-10-06T00:12:17-04:00 Remove the Maybe in primRepName's type There's no need for this `Maybe`, as it will always be instantiated to `Just` in practice. Fixes #20482. - - - - - 4e91839a by sheaf at 2021-10-06T00:12:54-04:00 Add a regression test for #13233 This test fails on GHC 8.0.1, only when profiling is enabled, with the error: ghc: panic! (the 'impossible' happened) kindPrimRep.go a_12 This was fixed by commit b460d6c9. - - - - - 7fc986e1 by Sebastian Graf at 2021-10-06T00:13:29-04:00 CprAnal: Two regression tests For #16040 and #2387. - - - - - 9af29e7f by Matthew Pickering at 2021-10-06T10:57:24-04:00 Disable -dynamic-too if -dynamic is also passed Before if you passed both options then you would generate two identical hi/dyn_hi and o/dyn_o files, both in the dynamic way. It's better to warn this is happening rather than duplicating the work and causing potential confusion. -dynamic-too should only be used with -static. Fixes #20436 - - - - - a466b024 by sheaf at 2021-10-06T10:58:03-04:00 Improve overlap error for polykinded constraints There were two problems around `mkDictErr`: 1. An outdated call to `flattenTys` meant that we missed out on some instances. As we no longer flatten type-family applications, the logic is obsolete and can be removed. 2. We reported "out of scope" errors in a poly-kinded situation because `BoxedRep` and `Lifted` were considered out of scope. We fix this by using `pretendNameIsInScope`. fixes #20465 - - - - - b041fc6e by Ben Gamari at 2021-10-07T03:40:49-04:00 hadrian: Generate ghcii.sh in binary distributions Technically we should probably generate this in the in-place build tree as well, but I am not bothering to do so here as ghcii.sh will be removed in 9.4 when WinIO becomes the default anyways (see #12720). Fixes #19339. - - - - - 75a766a3 by Ben Gamari at 2021-10-07T03:40:49-04:00 hadrian: Fix incorrect ticket reference This was supposed to refer to #20253. - - - - - 62157287 by Teo Camarasu at 2021-10-07T03:41:27-04:00 fix non-moving gc heap space requirements estimate The space requirements of the non-moving gc are comparable to the compacting gc, not the copying gc. The copying gc requires a much larger overhead. Fixes #20475 - - - - - e82c8dd2 by Joachim Breitner at 2021-10-07T03:42:01-04:00 Fix rst syntax mistakes in release notes - - - - - 358f6222 by Benjamin Maurer at 2021-10-07T03:42:36-04:00 Removed left-over comment from `nonDetEltsUFM`-removal in `seqEltsUFM`. - - - - - 0cf23263 by Alan Zimmerman at 2021-10-07T03:43:11-04:00 EPA: Add comments to EpaDelta The EpaDelta variant of EpaLocation cannot be sorted by location. So we capture any comments that need to be printed between the prior output and this location, when creating an EpaDelta offset in ghc-exactprint. And make the EpaLocation fields strict. - - - - - e1d02fb0 by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow naturalEq#/Ne# to inline (#20361) We now perform constant folding on bigNatEq# instead. - - - - - 44886aab by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow inlining of naturalEq/Ne/Gt/Lt/Ge/Le/Compare (#20361) Perform constant folding on bigNatCompare instead. Some functions of the Enum class for Natural now need to be inlined explicitly to be specialized at call sites (because `x > lim` for Natural is inlined and the resulting function is a little too big to inline). If we don't do this, T17499 runtime allocations regresses by 16%. - - - - - 3a5a5c85 by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow naturalToWordClamp/Negate/Signum to inline (#20361) We don't need built-in rules now that bignum literals (e.g. 123 :: Natural) match with their constructors (e.g. NS 123##). - - - - - 714568bb by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: remove outdated comment - - - - - 4d44058d by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: transfer NOINLINE from Natural to BigNat - - - - - 01f5324f by Joachim Breitner at 2021-10-07T20:20:36-04:00 Recover test case for T11547 commit 98c7749 has reverted commit 59d7ee53, including the test that that file added. That test case is still valuable, so I am re-adding it. I add it with it’s current (broken) behavior so that whoever fixes it intentionally or accidentially will notice and then commit the actual desired behavior (which is kinda unspecified, see https://gitlab.haskell.org/ghc/ghc/-/issues/20455#note_382030) - - - - - 3d31f11e by Sylvain Henry at 2021-10-08T13:08:16-04:00 Don't link plugins' units with target code (#20218) Before this patch, plugin units were linked with the target code even when the unit was passed via `-plugin-package`. This is an issue to support plugins in cross-compilers (plugins are definitely not ABI compatible with target code). We now clearly separate unit dependencies for plugins and unit dependencies for target code and only link the latter ones. We've also added a test to ensure that plugin units passed via `-package` are linked with target code so that `thNameToGhcName` can still be used in plugins that need it (see T20218b). - - - - - 75aea732 by Joachim Breitner at 2021-10-08T13:08:51-04:00 New test case: Variant of T14052 with data type definitions previous attempts at fixing #11547 and #20455 were reverted because they showed some quadratic behaviour, and the test case T15052 was added to catch that. I believe that similar quadratic behavor can be triggered with current master, by using type definitions rather than value definitions, so this adds a test case similar to T14052. I have hopes that my attempts at fixing #11547 will lead to code that avoid the quadratic increase here. Or not, we will see. In any case, having this in `master` and included in future comparisons will be useful. - - - - - 374a718e by Teo Camarasu at 2021-10-08T18:09:56-04:00 Fix nonmoving gen label in gc stats report The current code assumes the non-moving generation is always generation 1, but this isn't the case if the amount of generations is greater than 2 Fixes #20461 - - - - - a37275a3 by Matthew Pickering at 2021-10-08T18:10:31-04:00 ci: Remove BROKEN_TESTS for x86 darwin builds The tests Capi_Ctype_001 Capi_Ctype_002 T12010 pass regularly on CI so let's mark them unbroken and hopefully then we can fix #20013. - - - - - e6838872 by Matthew Pickering at 2021-10-08T18:10:31-04:00 ci: Expect x86-darwin to pass Closes #20013 - - - - - 1f160cd9 by Matthew Pickering at 2021-10-08T18:10:31-04:00 Normalise output of T20199 test - - - - - 816d2561 by CarrieMY at 2021-10-08T18:11:08-04:00 Fix -E -fno-code undesirable interactions #20439 - - - - - 55a6377a by Matthew Pickering at 2021-10-08T18:11:43-04:00 code gen: Disable dead code elimination when -finfo-table-map is enabled It's important that when -finfo-table-map is enabled that we generate IPE entries just for those info tables which are actually used. To this end, the info tables which are used are collected just before code generation starts and entries only created for those tables. Not accounted for in this scheme was the dead code elimination in the native code generator. When compiling GHC this optimisation removed an info table which had an IPE entry which resulting in the following kind of linker error: ``` /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sS_info' /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sH_info' /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sm_info' collect2: error: ld returned 1 exit status `cc' failed in phase `Linker'. (Exit code: 1) Development.Shake.cmd, system command failed ``` Unfortunately, by the time this optimisation happens the structure of the CmmInfoTable has been lost, we only have the generated code for the info table to play with so we can no longer just collect all the used info tables and generate the IPE map. This leaves us with two options: 1. Return a list of the names of the discarded info tables and then remove them from the map. This is awkward because we need to do code generation for the map as well. 2. Just disable this small code size optimisation when -finfo-table-map is enabled. The option produces very big object files anyway. Option 2 is much easier to implement and means we don't have to thread information around awkwardly. It's at the cost of slightly larger object files (as dead code is not eliminated). Disabling this optimisation allows an IPE build of GHC to complete successfully. Fixes #20428 - - - - - a76409c7 by Andrei Barbu at 2021-10-08T19:45:29-04:00 Add defaulting plugins. Like the built-in type defaulting rules these plugins can propose candidates to resolve ambiguous type variables. Machine learning and other large APIs like those for game engines introduce new numeric types and other complex typed APIs. The built-in defaulting mechanism isn't powerful enough to resolve ambiguous types in these cases forcing users to specify minutia that they might not even know how to do. There is an example defaulting plugin linked in the documentation. Applications include defaulting the device a computation executes on, if a gradient should be computed for a tensor, or the size of a tensor. See https://github.com/ghc-proposals/ghc-proposals/pull/396 for details. - - - - - 31983ab4 by sheaf at 2021-10-09T04:46:05-04:00 Reject GADT pattern matches in arrow notation Tickets #20469 and #20470 showed that the current implementation of arrows is not at all up to the task of supporting GADTs: GHC produces ill-scoped Core programs because it doesn't propagate the evidence introduced by a GADT pattern match. For the time being, we reject GADT pattern matches in arrow notation. Hopefully we are able to add proper support for GADTs in arrows in the future. - - - - - a356bd56 by Matthew Pickering at 2021-10-10T15:07:52+02:00 driver: Fix assertion failure on self-import Fixes #20459 - - - - - 245ab166 by Ben Gamari at 2021-10-10T17:55:10-04:00 hadrian: Include Cabal flags in verbose configure output - - - - - 9f9d6280 by Zejun Wu at 2021-10-12T01:39:53-04:00 Derive Eq instance for the HieTypeFix type We have `instance Eq a => Eq (HieType a)` already. This instance can be handy when we want to impement a function to find all `fromIntegral :: a -> a` using `case ty of { Roll (HFunTy _ a b) -> a == b; _ -> False }`. - - - - - 8d6de541 by Ben Gamari at 2021-10-12T01:40:29-04:00 nonmoving: Fix and factor out mark_trec_chunk We need to ensure that the TRecChunk itself is marked, in addition to the TRecs it contains. - - - - - aa520ba1 by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/nonmoving: Rename mark_* to trace_* These functions really do no marking; they merely trace pointers. - - - - - 2c02ea8d by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/primops: Fix write barrier in stg_atomicModifyMutVarzuzh Previously the call to dirty_MUT_VAR in stg_atomicModifyMutVarzuzh was missing its final argument. Fixes #20414. - - - - - 2e0c13ab by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/nonmoving: Enable selector optimisation by default - - - - - 2c06720e by GHC GitLab CI at 2021-10-12T01:41:04-04:00 rts/Linker: Fix __dso_handle handling Previously the linker's handling of __dso_handle was quite wrong. Not only did we claim that __dso_handle could be NULL when statically linking (which it can not), we didn't even implement this mislead theory faithfully and instead resolved the symbol to a random pointer. This lead to the failing relocations on AArch64 noted in #20493. Here we try to implement __dso_handle as a dynamic linker would do, choosing an address within the loaded object (specifically its start address) to serve as the object's handle. - - - - - 58223dfa by Carrie Xu at 2021-10-12T01:41:41-04:00 Add Hint to "Empty 'do' block" Error Message#20147 - - - - - 8e88ef36 by Carrie Xu at 2021-10-12T01:41:41-04:00 Change affected tests stderr - - - - - 44384696 by Zubin Duggal at 2021-10-12T01:42:15-04:00 driver: Share the graph of dependencies We want to share the graph instead of recomputing it for each key. - - - - - e40feab0 by Matthew Pickering at 2021-10-12T01:42:50-04:00 Make ms_ghc_prim_import field strict If you don't promptly force this field then it ends up retaining a lot of data structures related to parsing. For example, the following retaining chain can be observed when using GHCi. ``` PState 0x4289365ca0 0x4289385d68 0x4289385db0 0x7f81b37a7838 0x7f81b3832fd8 0x4289365cc8 0x4289365cd8 0x4289365cf0 0x4289365cd8 0x4289365d08 0x4289385e48 0x7f81b4e4c290 0x7f818f63f440 0x7f818f63f440 0x7f81925ccd18 0x7f81b4e41230 0x7f818f63f440 0x7f81925ccd18 0x7f818f63f4a8 0x7f81b3832fd8 0x7f81b3832fd8 0x4289365d20 0x7f81b38233b8 0 19 <PState:GHC.Parser.Lexer:_build-ipe/stage1/compiler/build/GHC/Parser/Lexer.hs:3779:46> _thunk( ) 0x4289384230 0x4289384160 <([LEpaComment], [LEpaComment]):GHC.Parser.Lexer:> _thunk( ) 0x4289383250 <EpAnnComments:GHC.Parser.Lexer:compiler/GHC/Parser/Lexer.x:2306:19-40> _thunk( ) 0x4289399850 0x7f818f63f440 0x4289399868 <SrcSpanAnnA:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12527:13-30> L 0x4289397600 0x42893975a8 <GenLocated:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12527:32> 0x4289c4e8c8 : 0x4289c4e8b0 <[]:GHC.Parser.Header:compiler/GHC/Parser/Header.hs:104:36-54> (0x4289c4da70,0x7f818f63f440) <(,):GHC.Parser.Header:compiler/GHC/Parser/Header.hs:104:36-54> _thunk( ) 0x4289c4d030 <Bool:GHC.Parser.Header:compiler/GHC/Parser/Header.hs:(112,22)-(115,27)> ExtendedModSummary 0x422e9c8998 0x7f81b617be78 0x422e9c89b0 0x4289c4c0c0 0x7f81925ccd18 0x7f81925ccd18 0x7f81925ccd18 0x7f81925ccd18 0x7f818f63f440 0x4289c4c0d8 0x4289c4c0f0 0x7f81925ccd18 0x422e9c8a20 0x4289c4c108 0x4289c4c730 0x7f818f63f440 <ExtendedModSummary:GHC.Driver.Make:compiler/GHC/Driver/Make.hs:2041:30-38> ModuleNode 0x4289c4b850 <ModuleGraphNode:GHC.Unit.Module.Graph:compiler/GHC/Unit/Module/Graph.hs:139:14-36> 0x4289c4b590 : 0x4289c4b578 <[]:GHC.Unit.Module.Graph:compiler/GHC/Unit/Module/Graph.hs:139:31-36> ModuleGraph 0x4289c4b2f8 0x4289c4b310 0x4289c4b340 0x7f818f63f4a0 <ModuleGraph:GHC.Driver.Make:compiler/GHC/Driver/Make.hs:(242,19)-(244,40)> HscEnv 0x4289d9a4a8 0x4289d9aad0 0x4289d9aae8 0x4217062a88 0x4217060b38 0x4217060b58 0x4217060b68 0x7f81b38a7ce0 0x4217060b78 0x7f818f63f440 0x7f818f63f440 0x4217062af8 0x4289d9ab10 0x7f81b3907b60 0x4217060c00 114 <HscEnv:GHC.Runtime.Eval:compiler/GHC/Runtime/Eval.hs:790:31-44> ``` - - - - - 5c266b59 by Ben Gamari at 2021-10-12T19:16:40-04:00 hadrian: Introduce `static` flavour - - - - - 683011c7 by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Introduce static Alpine job - - - - - 9257abeb by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Drop :set from ghci scripts The ghci scripts for T9293 and ghci057 used `:set` to print the currently-set options. However, in neither case was this necessary to the correctness of the test and moreover it would introduce spurious platform-dependence (e.g. since `-fexternal-dynamic-refs` is set by default only on platforms that support dynamic linking). - - - - - 82a89df7 by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/linker: Define _DYNAMIC when necessary Usually the dynamic linker would define _DYNAMIC. However, when dynamic linking is not supported (e.g. on musl) it is safe to define it to be NULL. - - - - - fcd970b5 by GHC GitLab CI at 2021-10-12T19:16:40-04:00 rts/linker: Resolve __fini_array_* symbols to NULL If the __fini_array_{start,end} symbols are not defined (e.g. as is often the case when linking against musl) then resolve them to NULL. - - - - - 852ec4f5 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark T13702 as requiring share libraries It fails on statically-built Alpine with ``` T13702.hs:1:1: error: Could not find module ‘Prelude’ Perhaps you haven't installed the "dyn" libraries for package ‘base-4.15.0.0’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. | 1 | {-# LANGUAGE ForeignFunctionInterface #-} | ^ ``` - - - - - b604bfd9 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark ghcilink00[25] as requiring dynamic linking - - - - - d709a133 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark all ghci/linking/dyn tests as requiring dynamic linking - - - - - 99b8177a by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark T14931 as requiring dynamic linking - - - - - 2687f65e by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Compile safeInfered tests with -v0 This eliminates some spurious platform-dependence due to static linking (namely in UnsafeInfered02 due to dynamic-too). - - - - - 587d7e66 by Brian Jaress at 2021-10-12T19:16:40-04:00 documentation: flavours.md static details - - - - - 91cfe121 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Make recomp021 less environment-sensitive Suppress output from diff to eliminate unnecessary environmental-dependence. - - - - - dc094597 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Make T12600 more robust Previously we would depend upon `grep ... | head -n1`. In principle this should work, but on Alpine Linux `grep` complains when its stdout stream has been closed. - - - - - cdd45a61 by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Mark more broken tests on Alpine - - - - - 9ebda74e by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: Add environ - - - - - 08aa7a1d by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/linker: Introduce a notion of strong symbols - - - - - 005b1848 by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: Declare atexit as a strong symbol - - - - - 5987357b by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: fini array - - - - - 9074b748 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Move big-obj test from ghci/linking/dyn to ghci/linking There was nothing dynamic about this test. - - - - - 3b1c12d3 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Fix overzealous command-line mangling Previously this attempt at suppressing make's -s flag would mangle otherwise valid arguments. - - - - - 05303f68 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Clean up dynlib support predicates Previously it was unclear whether req_shared_libs should require: * that the platform supports dynamic library loading, * that GHC supports dynamic linking of Haskell code, or * that the dyn way libraries were built Clarify by splitting the predicate into two: * `req_dynamic_lib_support` demands that the platform support dynamic linking * `req_dynamic_hs` demands that the GHC support dynamic linking of Haskell code on the target platform Naturally `req_dynamic_hs` cannot be true unless `req_dynamic_lib_support` is also true. - - - - - 9859eede by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Bump docker images Bumps bootstrap compiler to GHC 9.0.1. - - - - - af5ed156 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make the OccName field of NotOrphan strict In GHCi, by default the ModIface is not written to disk, this can leave a thunk which retains a TyCon which ends up retaining a great deal more on the heap. For example, here is the retainer trace from ghc-debug. ``` ... many other closures ... <TyCon:GHC.Core.TyCon:compiler/GHC/Core/TyCon.hs:1755:34-97> Just 0x423162aaa8 <Maybe:GHC.Core.TyCon:compiler/GHC/Core/TyCon.hs:(1936,11)-(1949,13)> FamilyTyCon 0x4231628318 0x4210e06260 0x4231628328 0x4231628340 0x421730a398 0x4231628358 0x4231628380 0x4231628390 0x7f0f5a171d18 0x7f0f7b1d7850 0x42316283a8 0x7f0f7b1d7830 <TyCon:GHC.Core.TyCon:compiler/GHC/Cor e/TyCon.hs:1948:30-32> _thunk( ) 0x4231624000 <OccName:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:724:22-43> NotOrphan 0x42357d8ed8 <IsOrphan:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:724:12-43> IfaceFamInst 0x4210e06260 0x42359aed10 0x4210e0c6b8 0x42359aed28 <IfaceFamInst:GHC.Iface.Make:> ``` Making the field strict squashes this retainer leak when using GHCi. - - - - - 0c5d9ca8 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Be more careful about retaining KnotVars It is quite easy to end up accidently retaining a KnotVars, which contains pointers to a stale TypeEnv because they are placed in the HscEnv. One place in particular we have to be careful is when loading a module into the EPS in `--make` mode, we have to remove the reference to KnotVars as otherwise the interface loading thunks will forever retain reference to the KnotVars which are live at the time the interface was loaded. These changes do not go as far as to enforce the invariant described in Note [KnotVar invariants] * At the end of upsweep, there should be no live KnotVars but at least improve the situation. This is left for future work (#20491) - - - - - 105e2711 by Matthew Pickering at 2021-10-12T19:17:15-04:00 driver: Pass hsc_env with empty HPT into upsweep Otherwise you end up retaining the whole old HPT when reloading in GHCi. - - - - - 7215f6de by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make fields of Linkable strict The Module field can end up retaining part of a large structure and is always calculated by projection. - - - - - 053d9deb by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make the fields of MakeEnv strict There's no reason for them to be lazy, and in particular we would like to make sure the old_hpt field is evaluated. - - - - - 0d711791 by Matthew Pickering at 2021-10-12T19:17:15-04:00 More strictness around HomePackageTable This patch makes some operations to do with HomePackageTable stricter * Adding a new entry into the HPT would not allow the old HomeModInfo to be collected because the function used by insertWith wouldn't be forced. * We're careful to force the new MVar value before it's inserted into the global MVar as otherwise we retain references to old entries. - - - - - ff0409d0 by Matthew Pickering at 2021-10-12T19:17:15-04:00 driver: Filter out HPT modules **before** typecheck loop It's better to remove the modules first before performing the typecheckLoop as otherwise you can end up with thunks which reference stale HomeModInfo which are difficult to force due to the knot-tie. - - - - - c2ce1b17 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Add GHCi recompilation performance test - - - - - 82938981 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Force name_exe field to avoid retaining entire UnitEnv (including whole HPT) Not forcing this one place will result in GHCi using 2x memory on a reload. - - - - - 90f06a0e by Haochen Tong at 2021-10-12T19:17:53-04:00 Check for libatomic dependency for atomic operations Some platforms (e.g. RISC-V) require linking against libatomic for some (e.g. sub-word-sized) atomic operations. Fixes #19119. - - - - - 234bf368 by Haochen Tong at 2021-10-12T19:17:53-04:00 Move libatomic check into m4/fp_gcc_supports_atomics.m4 - - - - - 4cf43b2a by Haochen Tong at 2021-10-12T19:17:53-04:00 Rename fp_gcc_supports__atomics to fp_cc_supports__atomics - - - - - 0aae1b4e by Joachim Breitner at 2021-10-13T01:07:45+00:00 shadowNames: Accept an OccName, not a GreName previously, the `shadowNames` function would take `[GreName]`. This has confused me for two reasons: * Why `GreName` and not `Name`? Does the difference between a normal name and a field name matter? The code of `shadowNames` shows that it does not, but really its better if the type signatures says so. * Why `Name` and not `OccName`? The point of `shadowNames` is to shadow _unqualified names_, at least in the two use cases I am aware of (names defined on the GHCI prompt or in TH splices). The code of `shadowNames` used to have cases that peek at the module of the given name and do something if that module appears in the `GlobalRdrElt`, but I think these cases are dead code, I don’t see how they could occur in the above use cases. Also, I replaced them with `errors` and GHC would still validate. Hence removing this code (yay!) This change also allows `shadowNames` to accept an `OccSet` instead, which allows for a faster implemenation; I’ll try that separately. This in stead might help with !6703. - - - - - 19cd403b by Norman Ramsey at 2021-10-13T03:32:21-04:00 Define and export Outputable instance for StgOp - - - - - 58bd0cc1 by Zubin Duggal at 2021-10-13T13:50:10+05:30 ci: build validate-x86_64-linux-deb9-debug with hyperlinked source (#20067) - - - - - 4536e8ca by Zubin Duggal at 2021-10-13T13:51:00+05:30 hadrian, testsuite: Teach Hadrian to query the testsuite driver for dependencies Issues #19072, #17728, #20176 - - - - - 60d3e33d by Zubin Duggal at 2021-10-13T13:51:03+05:30 hadrian: Fix location for haddocks in installed pkgconfs - - - - - 337a31db by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: Run haddock tests on out of tree compiler - - - - - 8c224b6d by Zubin Duggal at 2021-10-13T13:51:03+05:30 ci: test in-tree compiler in hadrian - - - - - 8d5a5ecf by Zubin Duggal at 2021-10-13T13:51:03+05:30 hadrian: avoid building check-{exact,ppr} and count-deps when the tests don't need them hadrian: build optional dependencies with test compiler - - - - - d0e87d0c by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: remove 'req_smp' from testwsdeque - - - - - 3c0e60b8 by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: strip windows line endings for haddock haddock: deterministic SCC Updates haddock submodule Metric Increase: haddock.Cabal haddock.base haddock.compiler - - - - - 64460b20 by Ben Gamari at 2021-10-13T18:44:12-04:00 distrib/configure: Add AC_CONFIG_MACRO_DIRS Sadly, autoconf cannot warn when it encounters an undefined macro and therefore this bug went unnoticed for altogether far too long. - - - - - e46edfcf by sheaf at 2021-10-13T18:44:49-04:00 Set logger flags in --backpack mode Backpack used to initialise the logger before obtaining the DynFlags. This meant that logging options (such as dump flags) were not set. Initialising the logger after the session flags have been set fixes the issue. fixes #20396 - - - - - df016e4e by Matthew Pickering at 2021-10-14T08:41:17-04:00 Make sure paths are quoted in install Makefile Previously it would fail with this error: ``` if [ -L wrappers/ghc ]; then echo "ghc is a symlink"; fi ghc is a symlink cp: target 'dir/bin/ghc' is not a directory make: *** [Makefile:197: install_wrappers] Error 1 ``` which is because the install path contains a space. Fixes #20506 - - - - - 7f2ce0d6 by Joachim Breitner at 2021-10-14T08:41:52-04:00 Move BreakInfo into own module while working on GHCi stuff, e.g. `GHC.Runtime.Eval.Types`, I observed a fair amount of modules being recompiled that I didn’t expect to depend on this, from byte code interpreters to linkers. Turns out that the rather simple `BreakInfo` type is all these modules need from the `GHC.Runtime.Eval.*` hierarchy, so by moving that into its own file we make the dependency tree wider and shallower, which is probably worth it. - - - - - 557d26fa by Ziyang Liu at 2021-10-14T14:32:57-04:00 Suggest -dynamic-too in failNonStd when applicable I encountered an error that says ``` Cannot load -dynamic objects when GHC is built the normal way To fix this, either: (1) Use -fexternal-interpreter, or (2) Build the program twice: once the normal way, and then with -dynamic using -osuf to set a different object file suffix. ``` Or it could say ``` (2) Use -dynamic-too ``` - - - - - f450e948 by Joachim Breitner at 2021-10-14T14:33:32-04:00 fuzzyLookup: More deterministic order else the output may depend on the input order, which seems it may depend on the concrete Uniques, which is causing headaches when including test cases about that. - - - - - 8b7f5424 by Alan Zimmerman at 2021-10-14T14:34:07-04:00 EPA: Preserve semicolon order in annotations Ensure the AddSemiAnn items appear in increasing order, so that if they are converted to delta format they are still in the correct order. Prior to this the exact printer sorted by Span, which is meaningless for EpaDelta locations. - - - - - 481e6b54 by Matthew Pickering at 2021-10-14T14:34:42-04:00 Some extra strictness in annotation fields Locations can be quite long-lived so it's important that things which live in locations, such as annotations are forced promptly. Otherwise they end up retaining the entire PState, as evidenced by this retainer trace: ``` PState 0x4277ce6cd8 0x4277ce6d00 0x7f61f12d37d8 0x7f61f12d37d8 0x7f61f135ef78 0x4277ce6d48 0x4277ce6d58 0x4277ce6d70 0x4277ce6d58 0x4277ce6d88 0x4277ce6da0 0x7f61f29782f0 0x7f61cd16b440 0x7f61cd16b440 0x7f61d00f8d18 0x7f61f296d290 0x7f61cd16b440 0x7f61d00f8d18 0x7f61cd16b4a8 0x7f61f135ef78 0x4277ce6db8 0x4277ce6dd0 0x7f61f134f358 0 3 <PState:GHC.Parser.Lexer:_build-ipe/stage1/compiler/build/GHC/Parser/Lexer.hs:3779:46> _thunk( ) 0x4277ce6280 0x4277ce68a0 <([LEpaComment], [LEpaComment]):GHC.Parser.Lexer:> _thunk( ) 0x4277ce6568 <EpAnnComments:GHC.Parser.Lexer:compiler/GHC/Parser/Lexer.x:2306:19-40> _thunk( ) 0x4277ce62b0 0x4277ce62c0 0x4277ce6280 0x7f61f287fc58 <EpAnn AnnList:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12664:13-32> SrcSpanAnn 0x4277ce6060 0x4277ce6048 <SrcSpanAnn':GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12664:3-35> L 0x4277ce4e70 0x428f8c9158 <GenLocated:GHC.Data.BooleanFormula:compiler/GHC/Data/BooleanFormula.hs:40:23-29> 0x428f8c8318 : 0x428f8c8300 <[]:GHC.Base:libraries/base/GHC/Base.hs:1316:16-29> Or 0x428f8c7890 <BooleanFormula:GHC.Data.BooleanFormula:compiler/GHC/Data/BooleanFormula.hs:40:23-29> IfConcreteClass 0x7f61cd16b440 0x7f61cd16b440 0x428f8c7018 0x428f8c7030 <IfaceClassBody:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:(640,12)-(645,13)> ``` Making these few places strict is sufficient for now but there are perhaps more places which will need strictifying in future. ------------------------- Metric Increase: parsing001 ------------------------- - - - - - 7a8171bc by Tom Sydney Kerckhove at 2021-10-15T06:51:18+00:00 Insert warnings in the documentation of dangerous functions - - - - - 1cda768c by Joachim Breitner at 2021-10-15T18:15:36-04:00 GHC.Builtin.Uniques: Remove unused code a number of functions exported by this module are (no longer) used, so let’s remove them. In particular, it no longer seems to be the case that type variables have tag `'t'`, so removed the special handling when showing them. * the use of `initTyVarUnique` was removed in 7babb1 (with the notable commit message of "Before merging to HEAD we need to tidy up and write a proper commit message.") * `mkPseudoUniqueD`and `mkPseudoUniqueH` were added in 423d477, but never ever used? * `mkCoVarUnique` was added in 674654, but never ever used? - - - - - 88e913d4 by Oleg Grenrus at 2021-10-15T18:16:14-04:00 Null eventlog writer - - - - - bbb1f6da by Sylvain Henry at 2021-10-15T18:16:51-04:00 Hadrian: display command line above errors (#20490) - - - - - b6954f0c by Joachim Breitner at 2021-10-15T18:17:26-04:00 shadowNames: Use OccEnv a, not [OccName] this allows us to use a smarter implementation based on `Data.IntSet.differenceWith`, which should do less work. Also, it will unblock improvements to !6703. The `OccEnv a` really denotes a set of `OccName`s. We are not using `OccSet`, though, because that is an `OccEnv OccName`, and we in !6703 we want to use this with differently-valued `OccEnv`s. But `OccSet`s are readily and safely coerced into `OccEnv`s. There is no other use of `delLocalRdrEnvList` remaining, so removing that. - - - - - c9922a8e by Matthew Pickering at 2021-10-15T18:18:00-04:00 hadrian: Document lint targets Fixes #20508 - - - - - 65bf3992 by Matthew Pickering at 2021-10-17T14:06:08-04:00 ghci: Explicitly store and restore interface file cache In the old days the old HPT was used as an interface file cache when using ghci. The HPT is a `ModuleEnv HomeModInfo` and so if you were using hs-boot files then the interface file from compiling the .hs file would be present in the cache but not the hi-boot file. This used to be ok, because the .hi file used to just be a better version of the .hi-boot file, with more information so it was fine to reuse it. Now the source hash of a module is kept track of in the interface file and the source hash for the .hs and .hs-boot file are correspondingly different so it's no longer safe to reuse an interface file. I took the decision to move the cache management of interface files to GHCi itself, and provide an API where `load` can be provided with a list of interface files which can be used as a cache. An alternative would be to manage this cache somewhere in the HscEnv but it seemed that an API user should be responsible for populating and suppling the cache rather than having it managed implicitly. Fixes #20217 - - - - - 81740ce8 by sheaf at 2021-10-17T14:06:46-04:00 Introduce Concrete# for representation polymorphism checks PHASE 1: we never rewrite Concrete# evidence. This patch migrates all the representation polymorphism checks to the typechecker, using a new constraint form Concrete# :: forall k. k -> TupleRep '[] Whenever a type `ty` must be representation-polymorphic (e.g. it is the type of an argument to a function), we emit a new `Concrete# ty` Wanted constraint. If this constraint goes unsolved, we report a representation-polymorphism error to the user. The 'FRROrigin' datatype keeps track of the context of the representation-polymorphism check, for more informative error messages. This paves the way for further improvements, such as allowing type families in RuntimeReps and improving the soundness of typed Template Haskell. This is left as future work (PHASE 2). fixes #17907 #20277 #20330 #20423 #20426 updates haddock submodule ------------------------- Metric Decrease: T5642 ------------------------- - - - - - 19d1237e by Koz Ross at 2021-10-19T03:29:40-04:00 Fix infelicities in docs for lines, unlines, words, unwords - - - - - 3035d1a2 by Matthew Pickering at 2021-10-19T03:30:16-04:00 tests: Remove $(CABAL_MINIMAL_CONFIGURATION) from T16219 There is a latent issue in T16219 where -dynamic-too is enabled when compiling a signature file which causes us to enter the DT_Failed state because library-a-impl doesn't generate dyn_o files. Somehow this used to work in 8.10 (that also entered the DT_Failed state) We don't need dynamic object files when compiling a signature file but the code loads interfaces, and if dynamic-too is enabled then it will also try to load the dyn_hi file and check the two are consistent. There is another hack to do with this in `GHC.Iface.Recomp`. The fix for this test is to remove CABAL_MINIMAL_CONFIGURATION, which stops cabal building shared libraries by default. I'm of the opinion that the DT_Failed state indicates an error somewhere so we should hard fail rather than this confusing (broken) rerun logic. Whether this captures the original intent of #16219 is debateable, but it's not clear how it was supposed to work in the first place if the libraries didn't build dynamic object files. Module C imports module A, which is from a library where shared objects are not built so the test would never have worked anyway (if anything from A was used in a TH splice). - - - - - d25868b6 by Matthew Pickering at 2021-10-19T03:30:16-04:00 dynamic-too: Expand GHC.Iface.Recomp comment about the backpack hack - - - - - 837ce6cf by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Check the correct flag to see if dynamic-too is enabled. We just need to check the flag here rather than read the variable which indicates whether dynamic-too compilation has failed. - - - - - 981f2c74 by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Update cached DynFlags in ModSummary if we are enabling -dynamic-too - - - - - 1bc77a85 by Matthew Pickering at 2021-10-19T03:30:16-04:00 dynamic-too: Check the dynamic-too status in hscPipeline This "fixes" DT_Failed in --make mode, but only "fixes" because I still believe DT_Failed is pretty broken. - - - - - 51281e81 by Matthew Pickering at 2021-10-19T03:30:16-04:00 Add test for implicit dynamic too This test checks that we check for missing dynamic objects if dynamic-too is enabled implicitly by the driver. - - - - - 8144a92f by Matthew Pickering at 2021-10-19T03:30:16-04:00 WW: Use module name rather than filename for absent error messages WwOpts in WorkWrap.Utils initialised the wo_output_file field with the result of outputFile dflags. This is misguided because outputFile is only set when -o is specified, which is barely ever (and never in --make mode). It seems this is just used to add more context to an error message, a more appropriate thing to use I think would be a module name. Fixes #20438 - - - - - df419c1a by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Cleanups related to ModLocation ModLocation is the data type which tells you the locations of all the build products which can affect recompilation. It is now computed in one place and not modified through the pipeline. Important locations will now just consult ModLocation rather than construct the dynamic object path incorrectly. * Add paths for dynamic object and dynamic interface files to ModLocation. * Always use the paths from mod location when looking for where to find any interface or object file. * Always use the paths in a ModLocation when deciding where to write an interface and object file. * Remove `dynamicOutputFile` and `dynamicOutputHi` functions which *calculated* (incorrectly) the location of `dyn_o` and `dyn_hi` files. * Don't set `outputFile_` and so-on in `enableCodeGenWhen`, `-o` and hence `outputFile_` should not affect the location of object files in `--make` mode. It is now sufficient to just update the ModLocation with the temporary paths. * In `hscGenBackendPipeline` don't recompute the `ModLocation` to account for `-dynamic-too`, the paths are now accurate from the start of the run. * Rename `getLocation` to `mkOneShotModLocation`, as that's the only place it's used. Increase the locality of the definition by moving it close to the use-site. * Load the dynamic interface from ml_dyn_hi_file rather than attempting to reconstruct it in load_dynamic_too. * Add a variety of tests to check how -o -dyno etc interact with each other. Some other clean-ups * DeIOify mkHomeModLocation and friends, they are all pure functions. * Move FinderOpts into GHC.Driver.Config.Finder, next to initFinderOpts. * Be more precise about whether we mean outputFile or outputFile_: there were many places where outputFile was used but the result shouldn't have been affected by `-dyno` (for example the filename of the resulting executable). In these places dynamicNow would never be set but it's still more precise to not allow for this possibility. * Typo fixes suffices -> suffixes in the appropiate places. - - - - - 3d6eb85e by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Correct output of -fno-code and -dynamic-too Before we would print [1 of 3] Compiling T[boot] ( T.hs-boot, nothing, T.dyn_o ) Which was clearly wrong for two reasons. 1. No dynamic object file was produced for T[boot] 2. The file would be called T.dyn_o-boot if it was produced. Fixes #20300 - - - - - 753b921d by Matthew Pickering at 2021-10-19T03:30:16-04:00 Remove DT_Failed state At the moment if `-dynamic-too` fails then we rerun the whole pipeline as if we were just in `-dynamic` mode. I argue this is a misfeature and we should remove the so-called `DT_Failed` mode. In what situations do we fall back to `DT_Failed`? 1. If the `dyn_hi` file corresponding to a `hi` file is missing completely. 2. If the interface hash of `dyn_hi` doesn't match the interface hash of `hi`. What happens in `DT_Failed` mode? * The whole compiler pipeline is rerun as if the user had just passed `-dynamic`. * Therefore `dyn_hi/dyn_o` files are used which don't agree with the `hi/o` files. (As evidenced by `dynamicToo001` test). * This is very confusing as now a single compiler invocation has produced further `hi`/`dyn_hi` files which are different to each other. Why should we remove it? * In `--make` mode, which is predominately used `DT_Failed` does not work (#19782), there can't be users relying on this functionality. * In `-c` mode, the recovery doesn't fix the root issue, which is the `dyn_hi` and `hi` files are mismatched. We should instead produce an error and pass responsibility to the build system using `-c` to ensure that the prerequisites for `-dynamic-too` (dyn_hi/hi) files are there before we start compiling. * It is a misfeature to support use cases like `dynamicToo001` which allow you to mix different versions of dynamic/non-dynamic interface files. It's more likely to lead to subtle bugs in your resulting programs where out-dated build products are used rather than a deliberate choice. * In practice, people are usually compiling with `-dynamic-too` rather than separately with `-dynamic` and `-static`, so the build products always match and `DT_Failed` is only entered due to compiler bugs (see !6583) What should we do instead? * In `--make` mode, for home packages check during recompilation checking that `dyn_hi` and `hi` are both present and agree, recompile the modules if they do not. * For package modules, when loading the interface check that `dyn_hi` and `hi` are there and that they agree but fail with an error message if they are not. * In `--oneshot` mode, fail with an error message if the right files aren't already there. Closes #19782 #20446 #9176 #13616 - - - - - 7271bf78 by Joachim Breitner at 2021-10-19T03:30:52-04:00 InteractiveContext: Smarter caching when rebuilding the ic_rn_gbl_env The GlobalRdrEnv of a GHCI session changes in odd ways: New bindings are not just added "to the end", but also "in the middle", namely when changing the set of imports: These are treated as if they happened before all bindings from the prompt, even those that happened earlier. Previously, this meant that the `ic_rn_gbl_env` is recalculated from the `ic_tythings`. But this wasteful if `ic_tythings` has many entries that define the same unqualified name. By separately keeping track of a `GlobalRdrEnv` of all the locally defined things we can speed this operation up significantly. This change improves `T14052Type` by 60% (It used to be 70%, but it looks that !6723 already reaped some of the rewards). But more importantly, it hopefully unblocks #20455, becaues with this smarter caching, the change needed to fix that issue will no longer make `T14052` explode. I hope. It does regress `T14052` by 30%; caching isn’t free. Oh well. Metric Decrease: T14052Type Metric Increase: T14052 - - - - - 53c0e771 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Add test for T20509 This test checks to see whether a signature can depend on another home module. Whether it should or not is up for debate, see #20509 for more details. - - - - - fdfb3b03 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Make the fields of Target and TargetId strict Targets are long-lived through GHC sessions so we don't want to end up retaining In particular in 'guessTarget', the call to `unitIdOrHomeUnit` was retaining reference to an entire stale HscEnv, which in turn retained reference to a stale HomePackageTable. Making the fields strict forces that place promptly and helps ensure that mistakes like this don't happen again. - - - - - 877e6685 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Temporary fix for leak with -fno-code (#20509) This hack inserted for backpack caused a very bad leak when using -fno-code where EPS entries would end up retaining stale HomePackageTables. For any interactive user, such as HLS, this is really bad as once the entry makes it's way into the EPS then it's there for the rest of the session. This is a temporary fix which "solves" the issue by filtering the HPT to only the part which is needed for the hack to work, but in future we want to separate out hole modules from the HPT entirely to avoid needing to do this kind of special casing. ------------------------- Metric Decrease: MultiLayerModulesDefsGhci ------------------------- - - - - - cfacac68 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Add performance test for ghci, -fno-code and reloading (#20509) This test triggers the bad code path identified by #20509 where an entry into the EPS caused by importing Control.Applicative will retain a stale HomePackageTable. - - - - - 12d74ef7 by Richard Eisenberg at 2021-10-19T13:36:36-04:00 Care about specificity in pattern type args Close #20443. - - - - - 79c9c816 by Zubin Duggal at 2021-10-19T13:37:12-04:00 Don't print Shake Diagnostic messages (#20484) - - - - - f8ce38e6 by Emily Martins at 2021-10-19T22:21:26-04:00 Fix #19884: add warning to tags command, drop T10989 - - - - - d73131b9 by Ben Gamari at 2021-10-19T22:22:02-04:00 hadrian: Fix quoting in binary distribution installation Makefile Previously we failed to quote various paths in Hadrian's installation Makefile, resulting in #20506. - - - - - 949d7398 by Matthew Pickering at 2021-10-20T14:05:23-04:00 Add note about heap invariants [skip ci] At the moment the note just covers three important invariants but now there is a place to add more to if we think of them. - - - - - 2f75ffac by Ben Gamari at 2021-10-20T14:06:00-04:00 hadrian/doc: Add margin to staged-compilation figure - - - - - 5f274fbf by Ben Gamari at 2021-10-20T14:06:00-04:00 hadrian: Fix binary-dist support for cross-compilers Previously the logic which called ghc-pkg failed to account for the fact that the executable name may be prefixed with a triple. Moreover, the call must occur before we delete the settings file as ghc-pkg needs the latter. Fixes #20267. - - - - - 3e4b51ff by Matthew Pickering at 2021-10-20T14:06:36-04:00 Fix perf-nofib CI job The main change is to install the necessary build dependencies into an environment file using `caball install --lib`. Also updates the nofib submodule with a few fixes needed for the job to work. - - - - - ef92d889 by Matthew Pickering at 2021-10-20T14:07:12-04:00 Distribute HomeModInfo cache before starting upsweep This change means the HomeModInfo cache isn't retained until the end of upsweep and each cached interface can be collected immediately after its module is compiled. The result is lower peak memory usage when using GHCi. For Agda it reduced peak memory usage from about 1600M to 1200M. - - - - - 05b8a218 by Matthew Pickering at 2021-10-20T14:07:49-04:00 Make fields of GlobalRdrElt strict In order to do this I thought it was prudent to change the list type to a bag type to avoid doing a lot of premature work in plusGRE because of ++. Fixes #19201 - - - - - 0b575899 by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: constant folding for bigNatCompareWord# (#20361) - - - - - 758e0d7b by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: allow Integer predicates to inline (#20361) T17516 allocations increase by 48% because Integer's predicates are inlined in some Ord instance methods. These methods become too big to be inlined while they probably should: this is tracked in #20516. Metric Increase: T17516 - - - - - a901a1ae by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: allow Integer's signum to inline (#20361) Allow T12545 to increase because it only happens on CI with dwarf enabled and probably not related to this patch. Metric Increase: T12545 - - - - - 9ded1b17 by Matthew Pickering at 2021-10-20T17:49:42-04:00 Make sure ModIface values are still forced even if not written When we are not writing a ModIface to disk then the result can retain a lot of stuff. For example, in the case I was debugging the DocDeclsMap field was holding onto the entire HomePackageTable due to a single unforced thunk. Therefore, now if we're not going to write the interface then we still force deeply it in order to remove these thunks. The fields in the data structure are not made strict because when we read the field from the interface we don't want to load it immediately as there are parts of an interface which are unused a lot of the time. Also added a note to explain why not all the fields in a ModIface field are strict. The result of this is being able to load Agda in ghci and not leaking information across subsequent reloads. - - - - - 268857af by Matthew Pickering at 2021-10-20T17:50:19-04:00 ci: Move hlint jobs from quick-built into full-build This somewhat fixes the annoyance of not getting any "useful" feedback from a CI pipeline if you have a hlint failure. Now the hlint job runs in parallel with the other CI jobs so the feedback is recieved at the same time as other testsuite results. Fixes #20507 - - - - - f6f24515 by Joachim Breitner at 2021-10-20T17:50:54-04:00 instance Ord Name: Do not repeat default methods it is confusing to see what looks like it could be clever code, only to see that it does precisely the same thing as the default methods. Cleaning this up, to spare future readers the confusion. - - - - - 56b2b04f by Ziyang Liu at 2021-10-22T10:57:28-04:00 Document that `InScopeSet` is a superset of currently in-scope variables - - - - - 7f4e0e91 by Moritz Angermann at 2021-10-22T10:58:04-04:00 Do not sign extend CmmInt's unless negative. Might fix #20526. - - - - - 77c6f3e6 by sheaf at 2021-10-22T10:58:44-04:00 Use tcEqType in GHC.Core.Unify.uVar Because uVar used eqType instead of tcEqType, it was possible to accumulate a substitution that unified Type and Constraint. For example, a call to `tc_unify_tys` with arguments tys1 = [ k, k ] tys2 = [ Type, Constraint ] would first add `k = Type` to the substitution. That's fine, but then the second call to `uVar` would claim that the substitution also unifies `k` with `Constraint`. This could then be used to cause trouble, as per #20521. Fixes #20521 - - - - - fa5870d3 by Sylvain Henry at 2021-10-22T19:20:05-04:00 Add test for #19641 Now that Bignum predicates are inlined (!6696), we only need to add a test. Fix #19641 - - - - - 6fd7da74 by Sylvain Henry at 2021-10-22T19:20:44-04:00 Remove Indefinite We no longer need it after previous IndefUnitId refactoring. - - - - - 806e49ae by Sylvain Henry at 2021-10-22T19:20:44-04:00 Refactor package imports Use an (Raw)PkgQual datatype instead of `Maybe FastString` to represent package imports. Factorize the code that renames RawPkgQual into PkgQual in function `rnPkgQual`. Renaming consists in checking if the FastString is the magic "this" keyword, the home-unit unit-id or something else. Bump haddock submodule - - - - - 47ba842b by Haochen Tong at 2021-10-22T19:21:21-04:00 Fix compilerConfig stages Fix the call to compilerConfig because it accepts 1-indexed stage numbers. Also fixes `make stage=3`. - - - - - 621608c9 by Matthew Pickering at 2021-10-22T19:21:56-04:00 driver: Don't use the log queue abstraction when j = 1 This simplifies the code path for -j1 by not using the log queue queue abstraction. The result is that trace output isn't interleaved with other dump output like it can be with -j<N>. - - - - - dd2dba80 by Sebastian Graf at 2021-10-22T19:22:31-04:00 WorkWrap: `isRecDataCon` should not eta-reduce NewTyCon field tys (#20539) In #20539 we had a type ```hs newtype Measured a = Measured { unmeasure :: () -> a } ``` and `isRecDataCon Measured` recursed into `go_arg_ty` for `(->) ()`, because `unwrapNewTyConEtad_maybe` eta-reduced it. That triggered an assertion error a bit later. Eta reducing the field type is completely wrong to do here! Just call `unwrapNewTyCon_maybe` instead. Fixes #20539 and adds a regression test T20539. - - - - - 8300ca2e by Ben Gamari at 2021-10-24T01:26:11-04:00 driver: Export wWarningFlagMap A new feature requires Ghcide to be able to convert warnings to CLI flags (WarningFlag -> String). This is most easily implemented in terms of the internal function flagSpecOf, which uses an inefficient implementation based on linear search through a linked list. This PR derives Ord for WarningFlag, and replaces that list with a Map. Closes #19087. - - - - - 3bab222c by Sebastian Graf at 2021-10-24T01:26:46-04:00 DmdAnal: Implement Boxity Analysis (#19871) This patch fixes some abundant reboxing of `DynFlags` in `GHC.HsToCore.Match.Literal.warnAboutOverflowedLit` (which was the topic of #19407) by introducing a Boxity analysis to GHC, done as part of demand analysis. This allows to accurately capture ad-hoc unboxing decisions previously made in worker/wrapper in demand analysis now, where the boxity info can propagate through demand signatures. See the new `Note [Boxity analysis]`. The actual fix for #19407 is described in `Note [No lazy, Unboxed demand in demand signature]`, but `Note [Finalising boxity for demand signature]` is probably a better entry-point. To support the fix for #19407, I had to change (what was) `Note [Add demands for strict constructors]` a bit (now `Note [Unboxing evaluated arguments]`). In particular, we now take care of it in `finaliseBoxity` (which is only called from demand analaysis) instead of `wantToUnboxArg`. I also had to resurrect `Note [Product demands for function body]` and rename it to `Note [Unboxed demand on function bodies returning small products]` to avoid huge regressions in `join004` and `join007`, thereby fixing #4267 again. See the updated Note for details. A nice side-effect is that the worker/wrapper transformation no longer needs to look at strictness info and other bits such as `InsideInlineableFun` flags (needed for `Note [Do not unbox class dictionaries]`) at all. It simply collects boxity info from argument demands and interprets them with a severely simplified `wantToUnboxArg`. All the smartness is in `finaliseBoxity`, which could be moved to DmdAnal completely, if it wasn't for the call to `dubiousDataConInstArgTys` which would be awkward to export. I spent some time figuring out the reason for why `T16197` failed prior to my amendments to `Note [Unboxing evaluated arguments]`. After having it figured out, I minimised it a bit and added `T16197b`, which simply compares computed strictness signatures and thus should be far simpler to eyeball. The 12% ghc/alloc regression in T11545 is because of the additional `Boxity` field in `Poly` and `Prod` that results in more allocation during `lubSubDmd` and `plusSubDmd`. I made sure in the ticky profiles that the number of calls to those functions stayed the same. We can bear such an increase here, as we recently improved it by -68% (in b760c1f). T18698* regress slightly because there is more unboxing of dictionaries happening and that causes Lint (mostly) to allocate more. Fixes #19871, #19407, #4267, #16859, #18907 and #13331. Metric Increase: T11545 T18698a T18698b Metric Decrease: T12425 T16577 T18223 T18282 T4267 T9961 - - - - - 691c450f by Alan Zimmerman at 2021-10-24T01:27:21-04:00 EPA: Use LocatedA for ModuleName This allows us to use an Anchor with a DeltaPos in it when exact printing. - - - - - 3417a81a by Joachim Breitner at 2021-10-24T01:27:57-04:00 undefined: Neater CallStack in error message Users of `undefined` don’t want to see ``` files.hs: Prelude.undefined: CallStack (from HasCallStack): error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err undefined, called at file.hs:151:19 in main:Main ``` but want to see ``` files.hs: Prelude.undefined: CallStack (from HasCallStack): undefined, called at file.hs:151:19 in main:Main ``` so let’s make that so. The function for that is `withFrozenCallStack`, but that is not usable here (module dependencies, and also not representation-polymorphic). And even if it were, it could confuse GHC’s strictness analyzer, leading to big regressions in some perf tests (T10421 in particular). So after shuffling modules and definitions around, I eventually noticed that the easiest way is to just not call `error` here. Fixes #19886 - - - - - 98aa29d3 by John Ericson at 2021-10-24T01:28:33-04:00 Fix dangling reference to RtsConfig.h It hasn't existed since a2a67cd520b9841114d69a87a423dabcb3b4368e -- in 2009! - - - - - 9cde38a0 by John Ericson at 2021-10-25T17:45:15-04:00 Remove stray reference to `dist-ghcconstants` I think this hasn't been a thing since 86054b4ab5125a8b71887b06786d0a428539fb9c, almost 10 years ago! - - - - - 0f7541dc by Viktor Dukhovni at 2021-10-25T17:45:51-04:00 Tweak descriptions of lines and unlines It seems more clear to think of lines as LF-terminated rather than LF-separated. - - - - - 0255ef38 by Zubin Duggal at 2021-10-26T12:36:24-04:00 Warn if unicode bidirectional formatting characters are found in the source (#20263) - - - - - 9cc6c193 by sheaf at 2021-10-26T12:37:02-04:00 Don't default type variables in type families This patch removes the following defaulting of type variables in type and data families: - type variables of kind RuntimeRep defaulting to LiftedRep - type variables of kind Levity defaulting to Lifted - type variables of kind Multiplicity defaulting to Many It does this by passing "defaulting options" to the `defaultTyVars` function; when calling from `tcTyFamInstEqnGuts` or `tcDataFamInstHeader` we pass options that avoid defaulting. This avoids wildcards being defaulted, which caused type families to unexpectedly fail to reduce. Note that kind defaulting, applicable only with -XNoPolyKinds, is not changed by this patch. Fixes #17536 ------------------------- Metric Increase: T12227 ------------------------- - - - - - cc113616 by Artyom Kuznetsov at 2021-10-26T20:27:33+00:00 Change CaseAlt and LambdaExpr to FunRhs in deriving Foldable and Traversable (#20496) - - - - - 9bd6daa4 by John Ericson at 2021-10-27T13:29:39-04:00 Make build system: Generalize and/or document distdirs `manual-package-config` should not hard-code the distdir, and no longer does Elsewhere, we must continue to hard-code due to inconsitent distdir names across stages, so we document this referring to the existing note "inconsistent distdirs". - - - - - 9d577ea1 by John Ericson at 2021-10-27T13:30:15-04:00 Compiler dosen't need to know about certain settings from file - RTS and libdw - SMP - RTS ways I am leaving them in the settings file because `--info` currently prints all the fields in there, but in the future I do believe we should separate the info GHC actually needs from "extra metadata". The latter could go in `+RTS --info` and/or a separate file that ships with the RTS for compile-time inspection instead. - - - - - ed9ec655 by Ben Gamari at 2021-10-27T13:30:55-04:00 base: Note export of Data.Tuple.Solo in changelog - - - - - 638f6548 by Ben Gamari at 2021-10-27T13:30:55-04:00 hadrian: Turn the `static` flavour into a transformer This turns the `static` flavour into the `+fully_static` flavour transformer. - - - - - 522eab3f by Ziyang Liu at 2021-10-29T05:01:50-04:00 Show family TyCons in mk_dict_error in the case of a single match - - - - - 71700526 by Sebastian Graf at 2021-10-29T05:02:25-04:00 Add more INLINABLE and INLINE pragmas to `Enum Int*` instances Otherwise the instances aren't good list producers. See Note [Stable Unfolding for list producers]. - - - - - 925c47b4 by Sebastian Graf at 2021-10-29T05:02:25-04:00 WorkWrap: Update Unfolding with WW'd body prior to `tryWW` (#20510) We have a function in #20510 that is small enough to get a stable unfolding in WW: ```hs small :: Int -> Int small x = go 0 x where go z 0 = z * x go z y = go (z+y) (y-1) ``` But it appears we failed to use the WW'd RHS as the stable unfolding. As a result, inlining `small` would expose the non-WW'd version of `go`. That appears to regress badly in #19727 which is a bit too large to extract a reproducer from that is guaranteed to reproduce across GHC versions. The solution is to simply update the unfolding in `certainlyWillInline` with the WW'd RHS. Fixes #20510. - - - - - 7b67724b by John Ericson at 2021-10-29T16:57:48-04:00 make build system: RTS should use dist-install not dist This is the following find and replace: - `rts/dist` -> `rts/dist-install` # for paths - `rts_dist` -> `rts_dist-install` # for make rules and vars - `,dist` -> `,dist-install` # for make, just in rts/ghc.mk` Why do this? Does it matter when the RTS is just built once? The answer is, yes, I think it does, because I want the distdir--stage correspondence to be consistent. In particular, for #17191 and continuing from d5de970dafd5876ef30601697576167f56b9c132 I am going to make the headers (`rts/includes`) increasingly the responsibility of the RTS (hence their new location). However, those headers are current made for multiple stages. This will probably become unnecessary as work on #17191 progresses and the compiler proper becomes more of a freestanding cabal package (e.g. a library that can be downloaded from Hackage and built without any autoconf). However, until that is finished, we have will transitional period where the RTS and headers need to agree on dirs for multiple stages. I know the make build system is going away, but it's not going yet, so I need to change it to unblock things :). - - - - - b0a1ed55 by Sylvain Henry at 2021-10-29T16:58:35-04:00 Add test for T15547 (#15547) Fix #15547 - - - - - c8d89f62 by Sylvain Henry at 2021-10-29T16:58:35-04:00 Bignum: add missing rule Add missing "Natural -> Integer -> Word#" rule. - - - - - 2a4581ff by sheaf at 2021-10-29T16:59:13-04:00 User's guide: data family kind-inference changes Explain that the kind of a data family instance must now be fully determined by the header of the instance, and how one might migrate code to account for this change. Fixes #20527 - - - - - ea862ef5 by Ben Gamari at 2021-10-30T15:43:28-04:00 ghci: Make getModBreaks robust against DotO Unlinked Previously getModBreaks assumed that an interpreted linkable will have only a single `BCOs` `Unlinked` entry. However, in general an object may also contain `DotO`s; ignore these. Fixes #20570. - - - - - e4095c0c by John Ericson at 2021-10-31T09:04:41-04:00 Make build system: Put make generated include's in RTS distdirs These are best thought of as being part of the RTS. - After !6791, `ghcautoconf.h` won't be used by the compiler inappropriately. - `ghcversion.h` is only used once outside the RTS, which is `compiler/cbits/genSym.c`. Except we *do* mean the RTS GHC is built against there, so it's better if we always get get the installed version. - `ghcplatform.h` alone is used extensively outside the RTS, but since we no longer have a target platform it is perfectly safe/correct to get the info from the previous RTS. All 3 are exported from the RTS currently and in the bootstrap window. This commit just swaps directories around, such that the new headers may continue to be used in stage 0 despite the reasoning above, but the idea is that we can subsequently make more interesting changes doubling down on the reasoning above. In particular, in !6803 we'll start "morally" moving `ghcautonconf.h` over, introducing an RTS configure script and temporary header of its `AC_DEFINE`s until the top-level configure script doesn't define any more. Progress towards #17191 - - - - - f5471c0b by John Ericson at 2021-10-31T09:05:16-04:00 Modularize autoconf platform detection This will allow better reuse of it, such as in the upcoming RTS configure script. Progress towards #17191 - - - - - 6b38c8a6 by Ben Gamari at 2021-10-31T09:05:52-04:00 ghc: Bump Cabal-Version to 1.22 This is necessary to use reexported-modules - - - - - 6544446d by Ben Gamari at 2021-10-31T09:05:52-04:00 configure: Hide error output from --target check - - - - - 7445bd71 by Andreas Klebinger at 2021-11-01T12:13:45+00:00 Update comment in Lint.hs mkWwArgs has been renamed to mkWorkerArgs. - - - - - f1a782dd by Vladislav Zavialov at 2021-11-02T01:36:32-04:00 HsToken for let/in (#19623) One more step towards the new design of EPA. - - - - - 37a37139 by John Ericson at 2021-11-02T01:37:08-04:00 Separate some AC_SUBST / AC_DEFINE Eventually, the RTS configure alone will need the vast majority of AC_DEFINE, and the top-level configure will need the most AC_SUBST. By removing the "side effects" of the macros like this we make them more reusable so they can be shared between the two configures without doing too much. - - - - - 2f69d102 by John Ericson at 2021-11-02T01:37:43-04:00 Remove `includes_GHCCONSTANTS` from make build system It is dead code. - - - - - da1a8e29 by John Ericson at 2021-11-02T01:37:43-04:00 Treat generated RTS headers in a more consistent manner We can depend on all of them at once the same way. - - - - - a7e1be3d by Ryan Scott at 2021-11-02T01:38:53-04:00 Fix #20590 with another application of mkHsContextMaybe We were always converting empty GADT contexts to `Just []` in `GHC.ThToHs`, which caused the pretty-printer to always print them as `() => ...`. This is easily fixed by using the `mkHsContextMaybe` function when converting GADT contexts so that empty contexts are turned to `Nothing`. This is in the same tradition established in commit 4c87a3d1d14f9e28c8aa0f6062e9c4201f469ad7. In the process of fixing this, I discovered that the `Cxt` argument to `mkHsContextMaybe` is completely unnecessary, as we can just as well check if the `LHsContext GhcPs` argument is empty. Fixes #20590. - - - - - 39eed84c by Alan Zimmerman at 2021-11-02T21:39:32+00:00 EPA: Get rid of bare SrcSpan's in the ParsedSource The ghc-exactPrint library has had to re-introduce the relatavise phase. This is needed if you change the length of an identifier and want the layout to be preserved afterwards. It is not possible to relatavise a bare SrcSpan, so introduce `SrcAnn NoEpAnns` for them instead. Updates haddock submodule. - - - - - 9f42a6dc by ARATA Mizuki at 2021-11-03T09:19:17-04:00 hadrian: Use $bindir instead of `dirname $0` in ghci wrapper `dirname $0` doesn't work when the wrapper is called via a symbolic link. Fix #20589 - - - - - bf6f96a6 by Vladislav Zavialov at 2021-11-03T16:35:50+03:00 Generalize the type of wrapLocSndMA - - - - - 1419fb16 by Matthew Pickering at 2021-11-04T00:36:09-04:00 ci: Don't run alpine job in fast-ci - - - - - 6020905a by Takenobu Tani at 2021-11-04T09:40:42+00:00 Correct load_load_barrier for risc-v This patch corrects the instruction for load_load_barrier(). Current load_load_barrier() incorrectly uses `fence w,r`. It means a store-load barrier. See also linux-kernel's smp_rmb() implementation: https://github.com/torvalds/linux/blob/v5.14/arch/riscv/include/asm/barrier.h#L27 - - - - - 086e288c by Richard Eisenberg at 2021-11-04T13:04:44-04:00 Tiny renamings and doc updates Close #20433 - - - - - f0b920d1 by CarrieMY at 2021-11-05T05:30:13-04:00 Fix deferOutOfScopeVariables for qualified #20472 - - - - - 59dfb005 by Simon Peyton Jones at 2021-11-05T05:30:48-04:00 Remove record field from Solo Ticket #20562 revealed that Solo, which is a wired-in TyCon, had a record field that wasn't being added to the type env. Why not? Because wired-in TyCons don't have record fields. It's not hard to change that, but it's tiresome for this one use-case, and it seems easier simply to make `getSolo` into a standalone function. On the way I refactored the handling of Solo slightly, to put it into wiredInTyCons (where it belongs) rather than only in knownKeyNames - - - - - be3750a5 by Matthew Pickering at 2021-11-05T10:12:16-04:00 Allow CApi FFI calls in GHCi At some point in the past this started working. I noticed this when working on multiple home units and couldn't load GHC's dependencies into the interpreter. Fixes #7388 - - - - - d96ce59d by John Ericson at 2021-11-05T10:12:52-04:00 make: Futher systematize handling of generated headers This will make it easier to add and remove generated headers, as we will do when we add a configure script for the RTS. - - - - - 3645abac by John Ericson at 2021-11-05T20:25:32-04:00 Avoid GHC_STAGE and other include bits We should strive to make our includes in terms of the RTS as much as possible. One place there that is not possible, the llvm version, we make a new tiny header Stage numbers are somewhat arbitrary, if we simple need a newer RTS, we should say so. - - - - - 4896a6a6 by Matthew Pickering at 2021-11-05T20:26:07-04:00 Fix boolean confusion with Opt_NoLlvmMangler flag I accidently got the two branches of the if expression the wrong way around when refactoring. Fixes #20567 - - - - - d74cc01e by Ziyang Liu at 2021-11-06T07:53:06-04:00 Export `withTcPlugins` and `withHoleFitPlugins` - - - - - ecd6d142 by Sylvain Henry at 2021-11-06T07:53:42-04:00 i386: fix codegen of 64-bit comparisons - - - - - e279ea64 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Add missing Int64/Word64 constant-folding rules - - - - - 4c86df25 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Fix Int64ToInt/Word64ToWord rules on 32-bit architectures When the input literal was larger than 32-bit it would crash in a compiler with assertion enabled because it was creating an out-of-bound word-sized literal (32-bit). - - - - - 646c3e21 by Sylvain Henry at 2021-11-06T07:53:42-04:00 CI: allow perf-nofib to fail - - - - - 20956e57 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Remove target dependent CPP for Word64/Int64 (#11470) Primops types were dependent on the target word-size at *compiler* compilation time. It's an issue for multi-target as GHC may not have the correct primops types for the target. This patch fixes some primops types: if they take or return fixed 64-bit values they now always use `Int64#/Word64#`, even on 64-bit architectures (where they used `Int#/Word#` before). Users of these primops may now need to convert from Int64#/Word64# to Int#/Word# (a no-op at runtime). This is a stripped down version of !3658 which goes the all way of changing the underlying primitive types of Word64/Int64. This is left for future work. T12545 allocations increase ~4% on some CI platforms and decrease ~3% on AArch64. Metric Increase: T12545 Metric Decrease: T12545 - - - - - 2800eee2 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Make Word64 use Word64# on every architecture - - - - - be9d7862 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Fix Int64/Word64's Enum instance fusion Performance improvement: T15185(normal) run/alloc 51112.0 41032.0 -19.7% GOOD Metric Decrease: T15185 - - - - - 6f2d6a5d by Nikolay Yakimov at 2021-11-06T11:24:50-04:00 Add regression test for #20568 GHC produced broken executables with rebindable if and -fhpc if `ifThenElse` expected non-Bool condition until GHC 9.0. This adds a simple regression test. - - - - - 7045b783 by Vladislav Zavialov at 2021-11-06T11:25:25-04:00 Refactor HdkM using deriving via * No more need for InlineHdkM, mkHdkM * unHdkM is now just a record selector * Update comments - - - - - 0d8a883e by Andreas Klebinger at 2021-11-07T12:54:30-05:00 Don't undersaturate join points through eta-reduction. In #20599 I ran into an issue where the unfolding for a join point was eta-reduced removing the required lambdas. This patch adds guards that should prevent this from happening going forward. - - - - - 3d7e3d91 by Vladislav Zavialov at 2021-11-07T12:55:05-05:00 Print the Type kind qualified when ambiguous (#20627) The Type kind is printed unqualified: ghci> :set -XNoStarIsType ghci> :k (->) (->) :: Type -> Type -> Type This is the desired behavior unless the user has defined their own Type: ghci> data Type Then we want to resolve the ambiguity by qualification: ghci> :k (->) (->) :: GHC.Types.Type -> GHC.Types.Type -> GHC.Types.Type - - - - - 184f6bc6 by John Ericson at 2021-11-07T16:26:10-05:00 Factor out unregisterised and tables next to code m4 macros These will be useful for upcoming RTS configure script. - - - - - 56705da8 by Sebastian Graf at 2021-11-07T16:26:46-05:00 Pmc: Do inhabitation test for unlifted vars (#20631) Although I thought we were already set to handle unlifted datatypes correctly, it appears we weren't. #20631 showed that it's wrong to assume `vi_bot=IsNotBot` for `VarInfo`s of unlifted types from their inception if we don't follow up with an inhabitation test to see if there are any habitable constructors left. We can't trigger the test from `emptyVarInfo`, so now we instead fail early in `addBotCt` for variables of unlifted types. Fixed #20631. - - - - - 28334b47 by sheaf at 2021-11-08T13:40:05+01:00 Default kind vars in tyfams with -XNoPolyKinds We should still default kind variables in type families in the presence of -XNoPolyKinds, to avoid suggesting enabling -XPolyKinds just because the function arrow introduced kind variables, e.g. type family F (t :: Type) :: Type where F (a -> b) = b With -XNoPolyKinds, we should still default `r :: RuntimeRep` in `a :: TYPE r`. Fixes #20584 - - - - - 3f103b1a by John Ericson at 2021-11-08T19:35:12-05:00 Factor out GHC_ADJUSTORS_METHOD m4 macro - - - - - ba9fdc51 by John Ericson at 2021-11-08T19:35:12-05:00 Factor out FP_FIND_LIBFFI and use in RTS configure too - - - - - 2929850f by Sylvain Henry at 2021-11-09T10:02:06-05:00 RTS: open timerfd synchronously (#20618) - - - - - bc498fdf by Sylvain Henry at 2021-11-09T10:02:46-05:00 Bignum: expose backendName (#20495) - - - - - 79a26df1 by Sylvain Henry at 2021-11-09T10:02:46-05:00 Don't expose bignum backend in ghc --info (#20495) GHC is bignum backend agnostic and shouldn't report this information as in the future ghc-bignum will be reinstallable potentially with a different backend that GHC is unaware of. Moreover as #20495 shows the returned information may be wrong currently. - - - - - e485f4f2 by Andreas Klebinger at 2021-11-09T19:54:31-05:00 SpecConstr - Attach evaldUnfolding to known evaluated arguments. - - - - - 983a99f0 by Ryan Scott at 2021-11-09T19:55:07-05:00 deriving: infer DatatypeContexts from data constructors, not type constructor Previously, derived instances that use `deriving` clauses would infer `DatatypeContexts` by using `tyConStupidTheta`. But this sometimes causes redundant constraints to be included in the derived instance contexts, as the constraints that appear in the `tyConStupidTheta` may not actually appear in the types of the data constructors (i.e., the `dataConStupidTheta`s). For instance, in `data Show a => T a = MkT deriving Eq`, the type of `MkT` does not require `Show`, so the derived `Eq` instance should not require `Show` either. This patch makes it so with some small tweaks to `inferConstraintsStock`. Fixes #20501. - - - - - bdd7b2be by Ryan Scott at 2021-11-09T19:55:07-05:00 Flesh out Note [The stupid context] and reference it `Note [The stupid context]` in `GHC.Core.DataCon` talks about stupid contexts from `DatatypeContexts`, but prior to this commit, it was rather outdated. This commit spruces it up and references it from places where it is relevant. - - - - - 95563259 by Li-yao Xia at 2021-11-10T09:16:21-05:00 Fix rendering of Applicative law - - - - - 0f852244 by Viktor Dukhovni at 2021-11-10T09:16:58-05:00 Improve ZipList section of Traversable overview - Fix cut/paste error by adding missing `c` pattern in `Vec3` traversable instance. - Add a bit of contextual prose above the Vec2/Vec3 instance sample code. - - - - - c4cd13b8 by Richard Eisenberg at 2021-11-10T18:18:19-05:00 Fix Note [Function types] Close #19938. - - - - - dfb9913c by sheaf at 2021-11-10T18:18:59-05:00 Improvements to rank_polymorphism.rst - rename the function f4 to h1 for consistency with the naming convention - be more explicit about the difference between `Int -> (forall a. a -> a)` and `forall a. Int -> (a -> a)` - reorder the section to make it flow better Fixes #20585 - - - - - 1540f556 by sheaf at 2021-11-10T18:19:37-05:00 Clarify hs-boot file default method restrictions The user guide wrongly stated that default methods should not be included in hs-boot files. In fact, if the class is not left abstract (no methods, no superclass constraints, ...) then the defaults must be provided and match with those given in the .hs file. We add some tests for this, as there were no tests in the testsuite that gave rise to the "missing default methods" error. Fixes #20588 - - - - - 8c0aec38 by Sylvain Henry at 2021-11-10T18:20:17-05:00 Hadrian: fix building/registering of .dll libraries - - - - - 11c9a469 by Matthew Pickering at 2021-11-11T07:21:28-05:00 testsuite: Convert hole fit performance tests into proper perf tests Fixes #20621 - - - - - c2ed85cb by Matthew Pickering at 2021-11-11T07:22:03-05:00 driver: Cache the transitive dependency calculation in ModuleGraph Two reasons for this change: 1. Avoid computing the transitive dependencies when compiling each module, this can save a lot of repeated work. 2. More robust to forthcoming changes to support multiple home units. - - - - - 4230e4fb by Matthew Pickering at 2021-11-11T07:22:03-05:00 driver: Use shared transitive dependency calculation in hptModulesBelow This saves a lot of repeated work on big dependency graphs. ------------------------- Metric Decrease: MultiLayerModules T13719 ------------------------- - - - - - af653b5f by Matthew Bauer at 2021-11-11T07:22:39-05:00 Only pass -pie, -no-pie when linking Previously, these flags were passed when both compiling and linking code. However, `-pie` and `-no-pie` are link-time-only options. Usually, this does not cause issues, but when using Clang with `-Werror` set results in errors: clang: error: argument unused during compilation: '-nopie' [-Werror,-Wunused-command-line-argument] This is unused by Clang because this flag has no effect at compile time (it’s called `-nopie` internally by Clang but called `-no-pie` in GHC for compatibility with GCC). Just passing these flags at linking time resolves this. Additionally, update #15319 hack to look for `-pgml` instead. Because of the main change, the value of `-pgmc` does not matter when checking for the workaround of #15319. However, `-pgml` *does* still matter as not all `-pgml` values support `-no-pie`. To cover all potential values, we assume that no custom `-pgml` values support `-no-pie`. This means that we run the risk of not using `-no-pie` when it is otherwise necessary for in auto-hardened toolchains! This could be a problem at some point, but this workaround was already introduced in 8d008b71 and we might as well continue supporting it. Likewise, mark `-pgmc-supports-no-pie` as deprecated and create a new `-pgml-supports-no-pie`. - - - - - 7cc6ebdf by Sebastian Graf at 2021-11-11T07:23:14-05:00 Add regression test for #20598 Fixes #20598, which is mostly a duplicate of #18824 but for GHC 9.2. - - - - - 7b44c816 by Simon Jakobi at 2021-11-12T21:20:17-05:00 Turn GHC.Data.Graph.Base.Graph into a newtype - - - - - a57cc754 by John Ericson at 2021-11-12T21:20:52-05:00 Make: Do not generate ghc.* headers in stage0 GHC should get everything it needs from the RTS, which for stage0 is the "old" RTS that comes from the bootstrap compiler. - - - - - 265ead8a by Richard Eisenberg at 2021-11-12T21:21:27-05:00 Improve redundant-constraints warning Previously, we reported things wrong with f :: (Eq a, Ord a) => a -> Bool f x = x == x saying that Eq a was redundant. This is fixed now, along with some simplification in Note [Replacement vs keeping]. There's a tiny bit of extra complexity in setImplicationStatus, but it's explained in Note [Tracking redundant constraints]. Close #20602 - - - - - ca90ffa3 by Richard Eisenberg at 2021-11-12T21:21:27-05:00 Use local instances with least superclass depth See new Note [Use only the best local instance] in GHC.Tc.Solver.Interact. This commit also refactors the InstSC/OtherSC mechanism slightly. Close #20582. - - - - - dfc4093c by Vladislav Zavialov at 2021-11-12T21:22:03-05:00 Implement -Wforall-identifier (#20609) In accordance with GHC Proposal #281 "Visible forall in types of terms": For three releases before this change takes place, include a new warning -Wforall-identifier in -Wdefault. This warning will be triggered at definition sites (but not use sites) of forall as an identifier. Updates the haddock submodule. - - - - - 4143bd21 by Cheng Shao at 2021-11-12T21:22:39-05:00 hadrian: use /bin/sh in timeout wrapper /usr/bin/env doesn't work within a nix build. - - - - - 43cab5f7 by Simon Peyton Jones at 2021-11-12T21:23:15-05:00 Get the in-scope set right in simplArg This was a simple (but long standing) error in simplArg, revealed by #20639 - - - - - 578b8b48 by Ben Gamari at 2021-11-12T21:23:51-05:00 gitlab-ci: Allow draft MRs to fail linting jobs Addresses #20623 by allowing draft MRs to fail linting jobs. - - - - - 908e49fa by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - 05166660 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - e41cffb0 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - cce3a025 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - 4499db7d by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - dd1be88b by Travis Whitaker at 2021-11-12T21:24:29-05:00 mmapForLinkerMarkExecutable: do nothing when len = 0 - - - - - 4c6ace75 by John Ericson at 2021-11-12T21:25:04-05:00 Delete compiler/MachDeps.h This was accidentally added back in 28334b475a109bdeb8d53d58c48adb1690e2c9b4 after it is was no longer needed by the compiler proper in 20956e5784fe43781d156dd7ab02f0bff4ab41fb. - - - - - 490e8c75 by John Ericson at 2021-11-12T21:25:40-05:00 Generate ghcversion.h with the top-level configure This is, rather unintuitively, part of the goal of making the packages that make of the GHC distribution more freestanding. `ghcversion.h` is very simple, so we easily can move it out of the main build systems (make and Hadrian). By doing so, the RTS becomes less of a special case to those build systems as the header, already existing in the source tree, appears like any other. We could do this with the upcomming RTS configure, but it hardly matters because there is nothing platform-specific here, it is just versioning information like the other files the top-level configure can be responsible for. - - - - - bba156f3 by John Ericson at 2021-11-12T21:26:15-05:00 Remove bit about size_t in ghc-llvm-version.h This shouldn't be here. It wasn't causing a problem because this header was only used from Haskell, but still. - - - - - 0b1da2f1 by John Ericson at 2021-11-12T21:26:50-05:00 Make: Install RTS headers in `$libdir/rts/include` not `$libdir/include` Before we were violating the convention of every other package. This fixes that. It matches the changes made in d5de970dafd5876ef30601697576167f56b9c132 to the location of the files in the repo. - - - - - b040d0d4 by Sebastian Graf at 2021-11-12T21:27:26-05:00 Add regression test for #20663 - - - - - c6065292 by John Ericson at 2021-11-12T21:28:02-05:00 Make: Move remaining built RTS headers to ...build/include This allows us to clean up the rts include dirs in the package conf. - - - - - aa372972 by Ryan Scott at 2021-11-15T10:17:57-05:00 Refactoring: Consolidate some arguments with DerivInstTys Various functions in GHC.Tc.Deriv.* were passing around `TyCon`s and `[Type]`s that ultimately come from the same `DerivInstTys`. This patch moves the definition of `DerivInstTys` to `GHC.Tc.Deriv.Generate` so that all of these `TyCon` and `[Type]` arguments can be consolidated into a single `DerivInstTys`. Not only does this make the code easier to read (in my opinion), this will also be important in a subsequent commit where we need to add another field to `DerivInstTys` that will also be used from `GHC.Tc.Deriv.Generate` and friends. - - - - - 564a19af by Ryan Scott at 2021-11-15T10:17:57-05:00 Refactoring: Move DataConEnv to GHC.Core.DataCon `DataConEnv` will prove to be useful in another place besides `GHC.Core.Opt.SpecConstr` in a follow-up commit. - - - - - 3e5f0595 by Ryan Scott at 2021-11-15T10:17:57-05:00 Instantiate field types properly in stock-derived instances Previously, the `deriving` machinery was very loosey-goosey about how it used the types of data constructor fields when generating code. It would usually just consult `dataConOrigArgTys`, which returns the _uninstantiated_ field types of each data constructor. Usually, you can get away with this, but issues #20375 and #20387 revealed circumstances where this approach fails. Instead, when generated code for a stock-derived instance `C (T arg_1 ... arg_n)`, one must take care to instantiate the field types of each data constructor with `arg_1 ... arg_n`. The particulars of how this is accomplished is described in the new `Note [Instantiating field types in stock deriving]` in `GHC.Tc.Deriv.Generate`. Some highlights: * `DerivInstTys` now has a new `dit_dc_inst_arg_env :: DataConEnv [Type]` field that caches the instantiated field types of each data constructor. Whenever we need to consult the field types somewhere in `GHC.Tc.Deriv.*` we avoid using `dataConOrigArgTys` and instead look it up in `dit_dc_inst_arg_env`. * Because `DerivInstTys` now stores the instantiated field types of each constructor, some of the details of the `GHC.Tc.Deriv.Generics.mkBindsRep` function were able to be simplified. In particular, we no longer need to apply a substitution to instantiate the field types in a `Rep(1)` instance, as that is already done for us by `DerivInstTys`. We still need a substitution to implement the "wrinkle" section of `Note [Generating a correctly typed Rep instance]`, but the code is nevertheless much simpler than before. * The `tyConInstArgTys` function has been removed in favor of the new `GHC.Core.DataCon.dataConInstUnivs` function, which is really the proper tool for the job. `dataConInstUnivs` is much like `tyConInstArgTys` except that it takes a data constructor, not a type constructor, as an argument, and it adds extra universal type variables from that data constructor at the end of the returned list if need be. `dataConInstUnivs` takes care to instantiate the kinds of the universal type variables at the end, thereby avoiding a bug in `tyConInstArgTys` discovered in https://gitlab.haskell.org/ghc/ghc/-/issues/20387#note_377037. Fixes #20375. Fixes #20387. - - - - - 25d36c31 by John Ericson at 2021-11-15T10:18:32-05:00 Make: Get rid of GHC_INCLUDE_DIRS These dirs should not be included in all stages. Instead make the per-stage `BUILD_*_INCLUDE_DIR` "plural" to insert `rts/include` in the right place. - - - - - b679721a by John Ericson at 2021-11-15T10:18:32-05:00 Delete dead code knobs for building GHC itself As GHC has become target agnostic, we've left behind some now-useless logic in both build systems. - - - - - 3302f42a by Sylvain Henry at 2021-11-15T13:19:42-05:00 Fix windres invocation I've already fixed this 7 months ago in the comments of #16780 but it never got merged. Now we need this for #20657 too. - - - - - d9f54905 by Sylvain Henry at 2021-11-15T13:19:42-05:00 Hadrian: fix windows cross-build (#20657) Many small things to fix: * Hadrian: platform triple is "x86_64-w64-mingw32" and this wasn't recognized by Hadrian (note "w64" instead of "unknown") * Hadrian was using the build platform ("isWindowsHost") to detect the use of the Windows toolchain, which was wrong. We now use the "targetOs" setting. * Hadrian was doing the same thing for Darwin so we fixed both at once, even if cross-compilation to Darwin is unlikely to happen afaik (cf "osxHost" vs "osxTarget" changes) * Hadrian: libffi name was computed in two different places and one of them wasn't taking the different naming on Windows into account. * Hadrian was passing "-Irts/include" when building the stage1 compiler leading to the same error as in #18143 (which is using make). stage1's RTS is stage0's one so mustn't do this. * Hadrian: Windows linker doesn't seem to support "-zorigin" so we don't pass it (similarly to Darwin) * Hadrian: hsc2hs in cross-compilation mode uses a trick (taken from autoconf): it defines "static int test_array[SOME_EXPR]" where SOME_EXPR is a constant expression. However GCC reports an error because SOME_EXPR is supposedly not constant. This is fixed by using another method enabled with the `--via-asm` flag of hsc2hs. It has been fixed in `make` build system (5f6fcf7808b16d066ad0fb2068225b3f2e8363f7) but not in Hadrian. * Hadrian: some packages are specifically built only on Windows but they shouldn't be when building a cross-compiler (`touchy` and `ghci-wrapper`). We now correctly detect this case and disable these packages. * Base: we use `iNVALID_HANDLE_VALUE` in a few places. It fixed some hsc2hs issues before we switched to `--via-asm` (see above). I've kept these changes are they make the code nicer. * Base: `base`'s configure tries to detect if it is building for Windows but for some reason the `$host_alias` value is `x86_64-windows` in my case and it wasn't properly detected. * Base: libraries/base/include/winio_structs.h imported "Windows.h" with a leading uppercase. It doesn't work on case-sensitive systems when cross-compiling so we have to use "windows.h". * RTS: rts/win32/ThrIOManager.c was importin "rts\OSThreads.h" but this path isn't valid when cross-compiling. We replaced "\" with "/". * DeriveConstants: this tool derives the constants from the target RTS header files. However these header files define `StgAsyncIOResult` only when `mingw32_HOST_OS` is set hence it seems we have to set it explicitly. Note that deriveConstants is called more than once (why? there is only one target for now so it shouldn't) and in the second case this value is correctly defined (probably coming indirectly from the import of "rts/PosixSource.h"). A better fix would probably be to disable the unneeded first run of deriveconstants. - - - - - cc635da1 by Richard Eisenberg at 2021-11-15T13:20:18-05:00 Link to ghc-proposals repo from README A potential contributor said that they weren't aware of ghc-proposals. This might increase visibility. - - - - - a8e1a756 by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci: Refactor toolchain provision This makes it easier to invoke ci.sh on Darwin by teaching it to manage the nix business. - - - - - 1f0014a8 by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci: Fail if dynamic references are found in a static bindist Previously we called error, which just prints an error, rather than fail, which actually fails. - - - - - 85f2c0ba by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci/darwin: Move SDK path discovery into toolchain.nix Reduce a bit of duplication and a manual step when running builds manually. - - - - - 3e94b5a7 by John Ericson at 2021-11-16T03:13:10-05:00 Make: Get rid of `BUILD_.*_INCLUDE_DIRS` First, we improve some of the rules around -I include dirs, and CPP opts. Then, we just specify the RTS's include dirs normally (locally per the package and in the package conf), and then everything should work normally. The primops.txt.pp rule needs no extra include dirs at all, as it no longer bakes in a target platfom. Reverts some of the extra stage arguments I added in 05419e55cab272ed39790695f448b311f22669f7, as they are no longer needed. - - - - - 083a7583 by Ben Gamari at 2021-11-17T05:10:27-05:00 Increase type sharing Fixes #20541 by making mkTyConApp do more sharing of types. In particular, replace * BoxedRep Lifted ==> LiftedRep * BoxedRep Unlifted ==> UnliftedRep * TupleRep '[] ==> ZeroBitRep * TYPE ZeroBitRep ==> ZeroBitType In each case, the thing on the right is a type synonym for the thing on the left, declared in ghc-prim:GHC.Types. See Note [Using synonyms to compress types] in GHC.Core.Type. The synonyms for ZeroBitRep and ZeroBitType are new, but absolutely in the same spirit as the other ones. (These synonyms are mainly for internal use, though the programmer can use them too.) I also renamed GHC.Core.Ty.Rep.isVoidTy to isZeroBitTy, to be compatible with the "zero-bit" nomenclature above. See discussion on !6806. There is a tricky wrinkle: see GHC.Core.Types Note [Care using synonyms to compress types] Compiler allocation decreases by up to 0.8%. - - - - - 20a4f251 by Ben Gamari at 2021-11-17T05:11:03-05:00 hadrian: Factor out --extra-*-dirs=... pattern We repeated this idiom quite a few times. Give it a name. - - - - - 4cec6cf2 by Ben Gamari at 2021-11-17T05:11:03-05:00 hadrian: Ensure that term.h is in include search path terminfo now requires term.h but previously neither build system offered any way to add the containing directory to the include search path. Fix this in Hadrian. Also adds libnuma includes to global include search path as it was inexplicably missing earlier. - - - - - 29086749 by Sebastian Graf at 2021-11-17T05:11:38-05:00 Pmc: Don't case split on wildcard matches (#20642) Since 8.10, when formatting a pattern match warning, we'd case split on a wildcard match such as ```hs foo :: [a] -> [a] foo [] = [] foo xs = ys where (_, ys@(_:_)) = splitAt 0 xs -- Pattern match(es) are non-exhaustive -- In a pattern binding: -- Patterns not matched: -- ([], []) -- ((_:_), []) ``` But that's quite verbose and distracts from which part of the pattern was actually the inexhaustive one. We'd prefer a wildcard for the first pair component here, like it used to be in GHC 8.8. On the other hand, case splitting is pretty handy for `-XEmptyCase` to know the different constructors we could've matched on: ```hs f :: Bool -> () f x = case x of {} -- Pattern match(es) are non-exhaustive -- In a pattern binding: -- Patterns not matched: -- False -- True ``` The solution is to communicate that we want a top-level case split to `generateInhabitingPatterns` for `-XEmptyCase`, which is exactly what this patch arranges. Details in `Note [Case split inhabiting patterns]`. Fixes #20642. - - - - - c591ab1f by Sebastian Graf at 2021-11-17T05:11:38-05:00 testsuite: Refactor pmcheck all.T - - - - - 33c0c83d by Andrew Pritchard at 2021-11-17T05:12:17-05:00 Fix Haddock markup on Data.Type.Ord.OrdCond. - - - - - 7bcd91f4 by Andrew Pritchard at 2021-11-17T05:12:17-05:00 Provide in-line kind signatures for Data.Type.Ord.Compare. Haddock doesn't know how to render SAKS, so the only current way to make the documentation show the kind is to write what it should say into the type family declaration. - - - - - 16d86b97 by ARATA Mizuki at 2021-11-17T05:12:56-05:00 bitReverse functions in GHC.Word are since base-4.14.0.0, not 4.12.0.0 They were added in 33173a51c77d9960d5009576ad9b67b646dfda3c, which constitutes GHC 8.10.1 / base-4.14.0.0 - - - - - 7850142c by Morrow at 2021-11-17T11:14:37+00:00 Improve handling of import statements in GHCi (#20473) Currently in GHCi, when given a line of user input we: 1. Attempt to parse and handle it as a statement 2. Otherwise, attempt to parse and handle a single import 3. Otherwise, check if there are imports present (and if so display an error message) 4. Otherwise, attempt to parse a module and only handle the declarations This patch simplifies the process to: Attempt to parse and handle it as a statement Otherwise, attempt to parse a module and handle the imports and declarations This means that multiple imports in a multiline are now accepted, and a multiline containing both imports and declarations is now accepted (as well as when separated by semicolons). - - - - - 09d44b4c by Zubin Duggal at 2021-11-18T01:37:36-05:00 hadrian: add threadedDebug RTS way to devel compilers - - - - - 5fa45db7 by Zubin Duggal at 2021-11-18T01:37:36-05:00 testsuite: disable some tests when we don't have dynamic libraries - - - - - f8c1c549 by Matthew Pickering at 2021-11-18T01:38:11-05:00 Revert "base: Use one-shot kqueue on macOS" This reverts commit 41117d71bb58e001f6a2b6a11c9314d5b70b9182 - - - - - f55ae180 by Simon Peyton Jones at 2021-11-18T14:44:45-05:00 Add one line of comments (c.f. !5706) Ticket #19815 suggested changing coToMCo to use isReflexiveCo rather than isReflCo. But perf results weren't encouraging. This patch just adds a comment to point to the data, such as it is. - - - - - 12d023d1 by Vladislav Zavialov at 2021-11-18T14:45:20-05:00 testsuite: check for FlexibleContexts in T17563 The purpose of testsuite/tests/typecheck/should_fail/T17563.hs is to make sure we do validity checking on quantified constraints. In particular, see the following functions in GHC.Tc.Validity: * check_quant_pred * check_pred_help * check_class_pred The original bug report used a~b constraints as an example of a constraint that requires validity checking. But with GHC Proposal #371, equality constraints no longer require GADTs or TypeFamilies; instead, they require TypeOperators, which are checked earlier in the pipeline, in the renamer. Rather than simply remove this test, we change the example to use another extension: FlexibleContexts. Since we decide whether a constraint requires this extension in check_class_pred, the regression test continues to exercise the relevant code path. - - - - - 78d4bca0 by Ben Gamari at 2021-11-18T22:27:20-05:00 ghc-cabal, make: Add support for building C++ object code Co-Authored By: Matthew Pickering <matthew at well-typed.com> - - - - - a8b4961b by Ben Gamari at 2021-11-18T22:27:20-05:00 Bump Cabal submodule - - - - - 59e8a900 by Ben Gamari at 2021-11-18T22:27:20-05:00 Bump text and parsec submodules Accommodates text-2.0. Metric Decrease: T15578 - - - - - 7f7d7888 by Ben Gamari at 2021-11-18T22:27:20-05:00 ghc-cabal: Use bootstrap compiler's text package This avoids the need to build `text` without Cabal, in turn avoiding the need to reproduce the workaround for #20010 contained therein. - - - - - 048f8d96 by Ben Gamari at 2021-11-18T22:27:20-05:00 gitlab-ci: Bump MACOSX_DEPLOYMENT_TARGET It appears that Darwin's toolchain includes system headers in the dependency makefiles it generates with `-M` with older `MACOSX_DEPLOYMENT_TARGETS`. To avoid this we have bumped the deployment target for x86-64/Darwin to 10.10. - - - - - 0acbbd20 by Ben Gamari at 2021-11-18T22:27:20-05:00 testsuite: Use libc++ rather than libstdc++ in objcpp-hi It appears that libstdc++ is no longer available in recent XCode distributions. Closes #16083. - - - - - aed98dda by John Ericson at 2021-11-18T22:27:55-05:00 Hadrian: bring up to date with latest make improvements Headers should be associated with the RTS, and subject to less hacks. The most subtle issue was that the package-grained dependencies on generated files were being `need`ed before calculating Haskell deps, but not before calculating C/C++ deps. - - - - - aabff109 by Ben Gamari at 2021-11-20T05:34:27-05:00 Bump deepseq submodule to 1.4.7.0-pre Addresses #20653. - - - - - 3d6b78db by Matthew Pickering at 2021-11-20T05:35:02-05:00 Remove unused module import syntax from .bkp mode .bkp mode had this unused feature where you could write module A and it would go looking for A.hs on the file system and use that rather than provide the definition inline. This isn't use anywhere in the testsuite and the code to find the module A looks dubious. Therefore to reduce .bkp complexity I propose to remove it. Fixes #20701 - - - - - bdeea37e by Sylvain Henry at 2021-11-20T05:35:42-05:00 More support for optional home-unit This is a preliminary refactoring for #14335 (supporting plugins in cross-compilers). In many places the home-unit must be optional because there won't be one available in the plugin environment (we won't be compiling anything in this environment). Hence we replace "HomeUnit" with "Maybe HomeUnit" in a few places and we avoid the use of "hsc_home_unit" (which is partial) in some few others. - - - - - 29e03071 by Ben Gamari at 2021-11-20T05:36:18-05:00 rts: Ensure that markCAFs marks object code Previously `markCAFs` would only evacuate CAFs' indirectees. This would allow reachable object code to be unloaded by the linker as `evacuate` may never be called on the CAF itself, despite it being reachable via the `{dyn,revertible}_caf_list`s. To fix this we teach `markCAFs` to explicit call `markObjectCode`, ensuring that the linker is aware of objects reachable via the CAF lists. Fixes #20649. - - - - - b2933ea9 by Ben Gamari at 2021-11-20T05:36:54-05:00 gitlab-ci: Set HOME to plausible but still non-existent location We have been seeing numerous CI failures on aarch64/Darwin of the form: CI_COMMIT_BRANCH: CI_PROJECT_PATH: ghc/ghc error: creating directory '/nonexistent': Read-only file system Clearly *something* is attempting to create `$HOME`. A bit of sleuthing by @int-e found that the culprit is likely `nix`, although it's not clear why. For now we avoid the issue by setting `HOME` to a fresh directory in the working tree. - - - - - bc7e9f03 by Zubin Duggal at 2021-11-20T17:39:25+00:00 Use 'NonEmpty' for the fields in an 'HsProjection' (#20389) T12545 is very inconsistently affected by this change for some reason. There is a decrease in allocations on most configurations, but an increase on validate-x86_64-linux-deb9-unreg-hadrian. Accepting it as it seems unrelated to this patch. Metric Decrease: T12545 Metric Increase: T12545 - - - - - 742d8b60 by sheaf at 2021-11-20T18:13:23-05:00 Include "not more specific" info in overlap msg When instances overlap, we now include additional information about why we weren't able to select an instance: perhaps one instance overlapped another but was not strictly more specific, so we aren't able to directly choose it. Fixes #20542 - - - - - f748988b by Simon Peyton Jones at 2021-11-22T11:53:02-05:00 Better wrapper activation calculation As #20709 showed, GHC could prioritise a wrapper over a SPEC rule, which is potentially very bad. This patch fixes that problem. The fix is is described in Note [Wrapper activation], especially item 4, 4a, and Conclusion. For now, it has a temporary hack (replicating what was there before to make sure that wrappers inline no earlier than phase 2. But it should be temporary; see #19001. - - - - - f0bac29b by Simon Peyton Jones at 2021-11-22T11:53:02-05:00 Make INLINE/NOINLINE pragmas a bgi less constraining We can inline a bit earlier than the previous pragmas said. I think they dated from an era in which the InitialPhase did no inlining. I don't think this patch will have much effect, but it's a bit cleaner. - - - - - 68a3665a by Sylvain Henry at 2021-11-22T11:53:47-05:00 Hadrian: bump stackage LTS to 18.18 (GHC 8.10.7) - - - - - 680ef2c8 by Andreas Klebinger at 2021-11-23T01:07:29-05:00 CmmSink: Be more aggressive in removing no-op assignments. No-op assignments like R1 = R1 are not only wasteful. They can also inhibit other optimizations like inlining assignments that read from R1. We now check for assignments being a no-op before and after we simplify the RHS in Cmm sink which should eliminate most of these no-ops. - - - - - 1ed2aa90 by Andreas Klebinger at 2021-11-23T01:07:29-05:00 Don't include types in test output - - - - - 3ab3631f by Krzysztof Gogolewski at 2021-11-23T01:08:05-05:00 Add a warning for GADT match + NoMonoLocalBinds (#20485) Previously, it was an error to pattern match on a GADT without GADTs or TypeFamilies. This is now allowed. Instead, we check the flag MonoLocalBinds; if it is not enabled, we issue a warning, controlled by -Wgadt-mono-local-binds. Also fixes #20485: pattern synonyms are now checked too. - - - - - 9dcb2ad1 by Ben Gamari at 2021-11-23T16:09:39+00:00 gitlab-ci: Bump DOCKER_REV - - - - - 16690374 by nineonine at 2021-11-23T22:32:51-08:00 Combine STG free variable traversals (#17978) Previously we would traverse the STG AST twice looking for free variables. * Once in `annTopBindingsDeps` which considers top level and imported ids free. Its output is used to put bindings in dependency order. The pass happens in STG pipeline. * Once in `annTopBindingsFreeVars` which only considers non-top level ids free. Its output is used by the code generator to compute offsets into closures. This happens in Cmm (CodeGen) pipeline. Now these two traversal operations are merged into one - `FVs.depSortWithAnnotStgPgm`. The pass happens right at the end of STG pipeline. Some type signatures had to be updated due to slight shifts of StgPass boundaries (for example, top-level CodeGen handler now directly works with CodeGen flavoured Stg AST instead of Vanilla). Due to changed order of bindings, a few debugger type reconstruction bugs have resurfaced again (see tests break018, break021) - work item #18004 tracks this investigation. authors: simonpj, nineonine - - - - - 91c0a657 by Matthew Pickering at 2021-11-25T01:03:17-05:00 Correct retypechecking in --make mode Note [Hydrating Modules] ~~~~~~~~~~~~~~~~~~~~~~~~ What is hydrating a module? * There are two versions of a module, the ModIface is the on-disk version and the ModDetails is a fleshed-out in-memory version. * We can **hydrate** a ModIface in order to obtain a ModDetails. Hydration happens in three different places * When an interface file is initially loaded from disk, it has to be hydrated. * When a module is finished compiling, we hydrate the ModIface in order to generate the version of ModDetails which exists in memory (see Note) * When dealing with boot files and module loops (see Note [Rehydrating Modules]) Note [Rehydrating Modules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a module has a boot file then it is critical to rehydrate the modules on the path between the two. Suppose we have ("R" for "recursive"): ``` R.hs-boot: module R where data T g :: T -> T A.hs: module A( f, T, g ) where import {-# SOURCE #-} R data S = MkS T f :: T -> S = ...g... R.hs: module R where data T = T1 | T2 S g = ...f... ``` After compiling A.hs we'll have a TypeEnv in which the Id for `f` has a type type uses the AbstractTyCon T; and a TyCon for `S` that also mentions that same AbstractTyCon. (Abstract because it came from R.hs-boot; we know nothing about it.) When compiling R.hs, we build a TyCon for `T`. But that TyCon mentions `S`, and it currently has an AbstractTyCon for `T` inside it. But we want to build a fully cyclic structure, in which `S` refers to `T` and `T` refers to `S`. Solution: **rehydration**. *Before compiling `R.hs`*, rehydrate all the ModIfaces below it that depend on R.hs-boot. To rehydrate a ModIface, call `typecheckIface` to convert it to a ModDetails. It's just a de-serialisation step, no type inference, just lookups. Now `S` will be bound to a thunk that, when forced, will "see" the final binding for `T`; see [Tying the knot](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/tying-the-knot). But note that this must be done *before* compiling R.hs. When compiling R.hs, the knot-tying stuff above will ensure that `f`'s unfolding mentions the `LocalId` for `g`. But when we finish R, we carefully ensure that all those `LocalIds` are turned into completed `GlobalIds`, replete with unfoldings etc. Alas, that will not apply to the occurrences of `g` in `f`'s unfolding. And if we leave matters like that, they will stay that way, and *all* subsequent modules that import A will see a crippled unfolding for `f`. Solution: rehydrate both R and A's ModIface together, right after completing R.hs. We only need rehydrate modules that are * Below R.hs * Above R.hs-boot There might be many unrelated modules (in the home package) that don't need to be rehydrated. This dark corner is the subject of #14092. Suppose we add to our example ``` X.hs module X where import A data XT = MkX T fx = ...g... ``` If in `--make` we compile R.hs-boot, then A.hs, then X.hs, we'll get a `ModDetails` for `X` that has an AbstractTyCon for `T` in the the argument type of `MkX`. So: * Either we should delay compiling X until after R has beeen compiled. * Or we should rehydrate X after compiling R -- because it transitively depends on R.hs-boot. Ticket #20200 has exposed some issues to do with the knot-tying logic in GHC.Make, in `--make` mode. this particular issue starts [here](https://gitlab.haskell.org/ghc/ghc/-/issues/20200#note_385758). The wiki page [Tying the knot](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/tying-the-knot) is helpful. Also closely related are * #14092 * #14103 Fixes tickets #20200 #20561 - - - - - f0c5d8d3 by Matthew Pickering at 2021-11-25T01:03:17-05:00 Make T14075 more robust - - - - - 6907e9fa by Matthew Pickering at 2021-11-25T01:03:17-05:00 Revert "Convert lookupIdSubst panic back to a warning (#20200)" This reverts commit df1d808f26544cbb77d85773d672137c65fd3cc7. - - - - - baa8ffee by Greg Steuck at 2021-11-25T01:03:54-05:00 Use getExecutablePath in getBaseDir on OpenBSD While OpenBSD doesn't have a general mechanism for determining the path of the executing program image, it is reasonable to rely on argv[0] which happens as a fallback in getExecutablePath. With this change on top of T18173 we can get a bit close to fixing #18173. - - - - - e3c59191 by Christiaan Baaij at 2021-11-25T01:04:32-05:00 Ensure new Ct/evidence invariant The `ctev_pred` field of a `CtEvidence` is a just a cache for the type of the evidence. More precisely: * For Givens, `ctev_pred` = `varType ctev_evar` * For Wanteds, `ctev_pred` = `evDestType ctev_dest` This new invariant is needed because evidence can become part of a type, via `Castty ty kco`. - - - - - 3639ad8f by Christiaan Baaij at 2021-11-25T01:04:32-05:00 Compare types of recursive let-bindings in alpha-equivalence This commit fixes #20641 by checking the types of recursive let-bindings when performing alpha-equality. The `Eq (DeBruijn CoreExpr)` instance now also compares `BreakPoint`s similarly to `GHC.Core.Utils.eqTickish`, taking bound variables into account. In addition, the `Eq (DeBruijn Type)` instance now correctly compares the kinds of the types when one of them contains a Cast: the instance is modeled after `nonDetCmpTypeX`. - - - - - 7c65687e by CarrieMY at 2021-11-25T01:05:11-05:00 Enable UnboxedTuples in `genInst`, Fixes #20524 - - - - - e33412d0 by Krzysztof Gogolewski at 2021-11-25T01:05:46-05:00 Misc cleanup * Remove `getTag_RDR` (unused), `tidyKind` and `tidyOpenKind` (already available as `tidyType` and `tidyOpenType`) * Remove Note [Explicit Case Statement for Specificity]. Since 0a709dd9876e40 we require GHC 8.10 for bootstrapping. * Change the warning to `cmpAltCon` to a panic. This shouldn't happen. If it ever does, the code was wrong anyway: it shouldn't always return `LT`, but rather `LT` in one case and `GT` in the other case. * Rename `verifyLinearConstructors` to `verifyLinearFields` * Fix `Note [Local record selectors]` which was not referenced * Remove vestiges of `type +v` * Minor fixes to StaticPointers documentation, part of #15603 - - - - - bb71f7f1 by Greg Steuck at 2021-11-25T01:06:25-05:00 Reorder `sed` arguments to work with BSD sed The order was swapped in 490e8c750ea23ce8e2b7309e0d514b7d27f231bb causing the build on OpenBSD to fail with: `sed: 1: "mk/config.h": invalid command code m` - - - - - c18a51f0 by John Ericson at 2021-11-25T01:06:25-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - d530c46c by sheaf at 2021-11-25T01:07:04-05:00 Add Data.Bits changes to base 4.16 changelog Several additions since 4.15 had not been recorded in the changelog: - newtypes And, Ior, Xor and Iff, - oneBits - symbolic synonyms `.^.`, `.>>.`, `!>>.`, `.<<.` and `!<<.`. Fixes #20608. - - - - - 4d34bf15 by Matthew Pickering at 2021-11-25T01:07:40-05:00 Don't use implicit lifting when deriving Lift It isn't much more complicated to be more precise when deriving Lift so we now generate ``` data Foo = Foo Int Bool instance Lift Foo where lift (Foo a b) = [| Foo $(lift a) $(lift b) |] liftTyped (Foo a b) = [|| Foo $$(lift a) $$(lift b) |] ``` This fixes #20688 which complained about using implicit lifting in the derived code. - - - - - 8961d632 by Greg Steuck at 2021-11-25T01:08:18-05:00 Disable warnings for unused goto labels Clang on OpenBSD aborts compilation with this diagnostics: ``` % "inplace/bin/ghc-stage1" -optc-Wno-error=unused-label -optc-Wall -optc-Werror -optc-Wall -optc-Wextra -optc-Wstrict-prototypes -optc-Wmissing-prototypes -optc-Wmissing-declarations -optc-Winline -optc-Wpointer-arith -optc-Wmissing-noreturn -optc-Wnested-externs -optc-Wredundant-decls -optc-Wno-aggregate-return -optc-fno-strict-aliasing -optc-fno-common -optc-Irts/dist-install/build/./autogen -optc-Irts/include/../dist-install/build/include -optc-Irts/include/. -optc-Irts/. -optc-DCOMPILING_RTS -optc-DFS_NAMESPACE=rts -optc-Wno-unknown-pragmas -optc-O2 -optc-fomit-frame-pointer -optc-g -optc-DRtsWay=\"rts_v\" -static -O0 -H64m -Wall -fllvm-fill-undef-with-garbage -Werror -this-unit-id rts -dcmm-lint -package-env - -i -irts -irts/dist-install/build -Irts/dist-install/build -irts/dist-install/build/./autogen -Irts/dist-install/build/./autogen -Irts/include/../dist-install/build/include -Irts/include/. -Irts/. -optP-DCOMPILING_RTS -optP-DFS_NAMESPACE=rts -O2 -Wcpp-undef -Wnoncanonical-monad-instances -c rts/linker/Elf.c -o rts/dist-install/build/linker/Elf.o rts/linker/Elf.c:2169:1: error: error: unused label 'dl_iterate_phdr_fail' [-Werror,-Wunused-label] | 2169 | dl_iterate_phdr_fail: | ^ dl_iterate_phdr_fail: ^~~~~~~~~~~~~~~~~~~~~ rts/linker/Elf.c:2172:1: error: error: unused label 'dlinfo_fail' [-Werror,-Wunused-label] | 2172 | dlinfo_fail: | ^ dlinfo_fail: ^~~~~~~~~~~~ 2 errors generated. ``` - - - - - 5428b8c6 by Zubin Duggal at 2021-11-25T01:08:54-05:00 testsuite: debounce title updates - - - - - 96b3899e by Ben Gamari at 2021-11-25T01:09:29-05:00 gitlab-ci: Add release jobs for Darwin targets As noted in #20707, the validate jobs which we previously used lacked profiling support. Also clean up some variable definitions. Fixes #20707. - - - - - 52cdc2fe by Pepe Iborra at 2021-11-25T05:00:43-05:00 Monoid instance for InstalledModuleEnv - - - - - 47f36440 by Pepe Iborra at 2021-11-25T05:00:43-05:00 Drop instance Semigroup ModuleEnv There is more than one possible Semigroup and it is not needed since plusModuleEnv can be used directly - - - - - b742475a by Pepe Iborra at 2021-11-25T05:00:43-05:00 drop instance Semigroup InstalledModuleEnv Instead, introduce plusInstalledModuleEnv - - - - - b24e8d91 by Roland Senn at 2021-11-25T05:01:21-05:00 GHCi Debugger - Improve RTTI When processing the heap, use also `APClosures` to create additional type constraints. This adds more equations and therefore improves the unification process to infer the correct type of values at breakpoints. (Fix the `incr` part of #19559) - - - - - cf5279ed by Gergő Érdi at 2021-11-25T05:01:59-05:00 Use `simplify` in non-optimizing build pipeline (#20500) - - - - - c9cead1f by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add specific optimization flag for fast PAP calls (#6084, #20500) - - - - - be0a9470 by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add specific optimization flag for Cmm control flow analysis (#20500) - - - - - b52a9a3f by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add `llvmOptLevel` to `DynFlags` (#20500) - - - - - f27a63fe by sheaf at 2021-11-25T05:02:39-05:00 Allow boring class declarations in hs-boot files There are two different ways of declaring a class in an hs-boot file: - a full declaration, where everything is written as it is in the .hs file, - an abstract declaration, where class methods and superclasses are left out. However, a declaration with no methods and a trivial superclass, such as: class () => C a was erroneously considered to be an abstract declaration, because the superclass is trivial. This is remedied by a one line fix in GHC.Tc.TyCl.tcClassDecl1. This patch also further clarifies the documentation around class declarations in hs-boot files. Fixes #20661, #20588. - - - - - cafb1f99 by Ben Gamari at 2021-11-25T05:03:15-05:00 compiler: Mark GHC.Prelude as Haddock no-home This significantly improves Haddock documentation generated by nix. - - - - - bd92c9b2 by Sebastian Graf at 2021-11-25T05:03:51-05:00 hadrian: Add `collect_stats` flavour transformer This is useful for later consumption with https://gitlab.haskell.org/bgamari/ghc-utils/-/blob/master/ghc_timings.py - - - - - 774fc4d6 by Ilias Tsitsimpis at 2021-11-25T08:34:54-05:00 Link against libatomic for 64-bit atomic operations Some platforms (e.g., armel) require linking against libatomic for 64-bit atomic operations. Fixes #20549 - - - - - 20101d9c by Greg Steuck at 2021-11-25T08:35:31-05:00 Permit multiple values in config_args for validate The whitespace expansion should be permitted to pass multiple arguments to configure. - - - - - e2c48b98 by Greg Steuck at 2021-11-25T08:36:09-05:00 Kill a use of %n format specifier This format has been used as a security exploit vector for decades now. Some operating systems (OpenBSD, Android, MSVC). It is targeted for removal in C2X standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2834.htm This requires extending the debug message function to return the number of bytes written (like printf(3)), to permit %n format specifier in one in one invocation of statsPrintf() in report_summary(). Implemented by Matthias Kilian (kili<AT>outback.escape.de) - - - - - ff0c45f3 by Andrew Lelechenko at 2021-11-26T16:01:09-05:00 Rename Data.ByteArray to Data.Array.ByteArray + add Trustworthy - - - - - 9907d540 by Andrew Lelechenko at 2021-11-26T16:01:09-05:00 Rename Data.Array.ByteArray -> Data.Array.Byte - - - - - 0c8e1b4d by Kai Prott at 2021-11-26T16:01:47-05:00 Improve error message for mis-typed plugins #20671 Previously, when a plugin could not be loaded because it was incorrectly typed, the error message only printed the expected but not the actual type. This commit augments the error message such that both types are printed and the corresponding module is printed as well. - - - - - 51bcb986 by Kai Prott at 2021-11-26T16:01:47-05:00 Remove duplicate import - - - - - 1830eea7 by Kai Prott at 2021-11-26T16:01:47-05:00 Simplify printQualification - - - - - 69e62032 by Kai Prott at 2021-11-26T16:01:47-05:00 Fix plugin type to GHC.Plugins.Plugin - - - - - 0a6776a3 by Kai Prott at 2021-11-26T16:01:47-05:00 Adapt plugin test case - - - - - 7e18b304 by Kai Prott at 2021-11-26T16:01:47-05:00 Reflect type change in the haddock comment - - - - - 02372be1 by Matthew Pickering at 2021-11-26T16:02:23-05:00 Allow keywords which can be used as variables to be used with OverloadedDotSyntax There are quite a few keywords which are allowed to be used as variables. Such as "as", "dependency" etc. These weren't accepted by OverloadedDotSyntax. The fix is pretty simple, use the varid production rather than raw VARID. Fixes #20723 - - - - - 13ef345c by John Ericson at 2021-11-27T19:41:11+00:00 Factor our `FP_CAPITALIZE_YES_NO` This deduplicates converting from yes/no to YES/NO in the configure scripts while also making it safer. - - - - - 88481c94 by John Ericson at 2021-11-27T19:46:16+00:00 Fix top-level configure script so --disable-foo works - - - - - f67060c6 by John Ericson at 2021-11-27T19:47:09+00:00 Make ambient MinGW support a proper settings Get rid of `USE_INPLACE_MINGW_TOOLCHAIN` and use a settings file entry instead. The CPP setting was originally introduced in f065b6b012. - - - - - 1dc0d7af by Ben Gamari at 2021-11-29T11:02:43-05:00 linker: Introduce linker_verbose debug output This splits the -Dl RTS debug output into two distinct flags: * `+RTS -Dl` shows errors and debug output which scales with at most O(# objects) * `+RTS -DL` shows debug output which scales with O(# symbols)t - - - - - 7ea665bf by Krzysztof Gogolewski at 2021-11-29T11:03:19-05:00 TTG: replace Void/NoExtCon with DataConCantHappen There were two ways to indicate that a TTG constructor is unused in a phase: `NoExtCon` and `Void`. This unifies the code, and uses the name 'DataConCantHappen', following the discussion at MR 7041. Updates haddock submodule - - - - - 14e9cab6 by Sylvain Henry at 2021-11-29T11:04:03-05:00 Use Monoid in hptSomeThingsBelowUs It seems to have a moderate but good impact on perf tests in CI. In particular: MultiLayerModules(normal) ghc/alloc 3125771138.7 3065532240.0 -1.9% So it's likely that huge projects will benefit from this. - - - - - 22bbf449 by Anton-Latukha at 2021-11-29T20:03:52+00:00 docs/users_guide/bugs.rst: Rewording It is either "slightly" || "significantly". If it is "bogus" - then no quotes around "optimization" & overall using word "bogus" or use quotes in that way in documentation is... Instead, something like "hack" or "heuristic" can be used there. - - - - - 9345bfed by Mitchell Rosen at 2021-11-30T01:32:22-05:00 Fix caluclation of nonmoving GC elapsed time Fixes #20751 - - - - - c7613493 by PHO at 2021-12-01T03:07:32-05:00 rts/ProfHeap.c: Use setlocale() on platforms where uselocale() is not available Not all platforms have per-thread locales. NetBSD doesn't have uselocale() in particular. Using setlocale() is of course not a safe thing to do, but it would be better than no GHC at all. - - - - - 4acfa0db by Ben Gamari at 2021-12-01T03:08:07-05:00 rts: Refactor SRT representation selection The goal here is to make the SRT selection logic a bit clearer and allow configurations which we currently don't support (e.g. using a full word in the info table even when TNTC is used). - - - - - 87bd9a67 by Ben Gamari at 2021-12-01T03:08:07-05:00 gitlab-ci: Introduce no_tntc job A manual job for testing the non-tables-next-to-code configuration. - - - - - 7acb945d by Carrie Xu at 2021-12-01T03:08:46-05:00 Dump non-module specific info to file #20316 - Change the dumpPrefix to FilePath, and default to non-module - Add dot to seperate dump-file-prefix and suffix - Modify user guide to introduce how dump files are named - This commit does not affect Ghci dump file naming. See also #17500 - - - - - 7bdca2ba by Ben Gamari at 2021-12-01T03:09:21-05:00 rts/RtsSymbols: Provide a proper prototype for environ Previously we relied on Sym_NeedsProto, but this gave the symbol a type which conflicts with the definition that may be provided by unistd.h. Fixes #20577. - - - - - 91d1a773 by Ben Gamari at 2021-12-01T03:09:21-05:00 hadrian: Don't pass empty paths via -I Previously we could in some cases add empty paths to `cc`'s include file search path. See #20578. - - - - - d8d57729 by Ben Gamari at 2021-12-01T03:09:21-05:00 ghc-cabal: Manually specify -XHaskell2010 Otherwise we end up with issues like #19631 when bootstrapping using GHC 9.2 and above. Fixes #19631. - - - - - 1c0c140a by Ben Gamari at 2021-12-01T03:09:21-05:00 ghc-compact: Update cabal file Improve documentation, bump bounds and cabal-version. - - - - - 322b6b45 by Ben Gamari at 2021-12-01T03:09:21-05:00 hadrian: Document fully_static flavour transformer - - - - - 4c434c9e by Ben Gamari at 2021-12-01T03:09:21-05:00 user-guide: Fix :since: of -XCApiFFI Closes #20504. - - - - - 0833ad55 by Matthew Pickering at 2021-12-01T03:09:58-05:00 Add failing test for #20674 - - - - - c2cb5e9a by Ben Gamari at 2021-12-01T03:10:34-05:00 testsuite: Print geometric mean of stat metrics As suggested in #20733. - - - - - 59b27945 by Ben Gamari at 2021-12-01T03:11:09-05:00 users-guide: Describe requirements of DWARF unwinding As requested in #20702 - - - - - c2f6cbef by Matthew Pickering at 2021-12-01T03:11:45-05:00 Fix several quoting issues in testsuite This fixes the ./validate script on my machine. I also took the step to add some linters which would catch problems like these in future. Fixes #20506 - - - - - bffd4074 by John Ericson at 2021-12-01T03:12:21-05:00 rts.cabal.in: Move `extra-source-files` so it is valid - - - - - 86c14db5 by John Ericson at 2021-12-01T03:12:21-05:00 Switch RTS cabal file / package conf to use Rts.h not Stg.h When we give cabal a configure script, it seems to begin checking whether or not Stg.h is valid, and then gets tripped up on all the register stuff which evidentally requires obscure command line flags to go. We can side-step this by making the test header Rts.h instead, which is more normal. I was a bit sketched out making this change, as I don't know why the Cabal library would suddenly beging checking the header. But I did confirm even without my RTS configure script the header doesn't compile stand-alone, and also the Stg.h is a probably-arbitrary choice since it dates all the way back to 2002 in 2cc5b907318f97e19b28b2ad8ed9ff8c1f401dcc. - - - - - defd8d54 by John Ericson at 2021-12-01T03:12:21-05:00 Avoid raw `echo` in `FPTOOLS_SET_PLATFORM_VARS` This ensures quiet configuring works. - - - - - b53f1227 by John Ericson at 2021-12-01T03:12:21-05:00 Factor our `$dir_$distdir_PKGDATA` make variable This makes a few things cleaner. - - - - - f124f2a0 by Ben Gamari at 2021-12-01T03:12:56-05:00 rts: Annotate benign race in pthread ticker's exit test Previously TSAN would report spurious data races due to the unsynchronized access of `exited`. I would have thought that using a relaxed load on `exited` would be enough to convince TSAN that the race was intentional, but apparently not. Closes #20690. - - - - - d3c7f9be by Viktor Dukhovni at 2021-12-01T03:13:34-05:00 Use POSIX shell syntax to redirect stdout/err FreeBSD (and likely NetBSD) /bin/sh does not support '>& word' to redirect stdout + stderr. (Also the preferred syntax in bash would be '&> word' to avoid surprises when `word` is "-" or a number). Resolves: #20760 - - - - - 1724ac37 by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/x86: Don't encode large shift offsets Handle the case of a shift larger than the width of the shifted value. This is necessary since x86 applies a mask of 0x1f to the shift amount, meaning that, e.g., `shr 47, $eax` will actually shift by 47 & 0x1f == 15. See #20626. (cherry picked from commit 31370f1afe1e2f071b3569fb5ed4a115096127ca) - - - - - 5b950a7f by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm: narrow when folding signed quotients Previously the constant-folding behavior for MO_S_Quot and MO_S_Rem failed to narrow its arguments, meaning that a program like: %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) would be miscompiled. Specifically, this program should reduce as %lobits8(0x00e1::bits16) == -31 %quot(%lobits8(0x00e1::bits16), 3::bits8) == -10 %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) == 246 However, with this bug the `%lobits8(0x00e1::bits16)` would instead be treated as `+31`, resulting in the incorrect result of `75`. (cherry picked from commit 94e197e3dbb9a48991eb90a03b51ea13d39ba4cc) - - - - - 78b78ac4 by Ben Gamari at 2021-12-02T18:13:30-05:00 ncg/aarch64: Don't sign extend loads Previously we would emit the sign-extending LDS[HB] instructions for sub-word loads. However, this is wrong, as noted in #20638. - - - - - 35bbc251 by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm: Disallow shifts larger than shiftee Previously primops.txt.pp stipulated that the word-size shift primops were only defined for shift offsets in [0, word_size). However, there was no further guidance for the definition of Cmm's sub-word size shift MachOps. Here we fix this by explicitly disallowing (checked in many cases by CmmLint) shift operations where the shift offset is larger than the shiftee. This is consistent with LLVM's shift operations, avoiding the miscompilation noted in #20637. - - - - - 2f6565cf by Ben Gamari at 2021-12-02T18:13:30-05:00 testsuite: Add testcases for various machop issues There were found by the test-primops testsuite. - - - - - 7094f4fa by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/aarch64: Don't rely on register width to determine amode We might be loading, e.g., a 16- or 8-bit value, in which case the register width is not reflective of the loaded element size. - - - - - 9c65197e by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm/opt: Fold away shifts larger than shiftee width This is necessary for lint-correctness since we no longer allow such shifts in Cmm. - - - - - adc7f108 by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/aarch64: Fix handling of subword values Here we rework the handling of sub-word operations in the AArch64 backend, fixing a number of bugs and inconsistencies. In short, we now impose the invariant that all subword values are represented in registers in zero-extended form. Signed arithmetic operations are then responsible for sign-extending as necessary. Possible future work: * Use `CMP`s extended register form to avoid burning an instruction in sign-extending the second operand. * Track sign-extension state of registers to elide redundant sign extensions in blocks with frequent sub-word signed arithmetic. - - - - - e19e9e71 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Fix width of shift operations Under C's implicit widening rules, the result of an operation like (a >> b) where a::Word8 and b::Word will have type Word, yet we want Word. - - - - - ebaf7333 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Zero-extend sub-word size results As noted in Note [Zero-extending sub-word signed results] we must explicitly zero-extend the results of sub-word-sized signed operations. - - - - - 0aeaa8f3 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Always cast arguments as unsigned As noted in Note [When in doubt, cast arguments as unsigned], we must ensure that arguments have the correct signedness since some operations (e.g. `%`) have different semantics depending upon signedness. - - - - - e98dad1b by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Cast possibly-signed results as unsigned C11 rule 6.3.1.1 dictates that all small integers used in expressions be implicitly converted to `signed int`. However, Cmm semantics require that the width of the operands be preserved with zero-extension semantics. For this reason we must recast sub-word arithmetic results as unsigned. - - - - - 44c08863 by Ben Gamari at 2021-12-02T18:13:31-05:00 testsuite: Specify expected word-size of machop tests These generally expect a particular word size. - - - - - fab2579e by Ben Gamari at 2021-12-02T18:14:06-05:00 hadrian: Don't rely on realpath in bindist Makefile As noted in #19963, `realpath` is not specified by POSIX and therefore cannot be assumed to be available. Here we provide a POSIX shell implementation of `realpath`, due to Julian Ospald and others. Closes #19963. - - - - - 99eb54bd by Kamil Dworakowski at 2021-12-02T21:45:10-05:00 Make openFile more tolerant of async excs (#18832) - - - - - 0e274c39 by nineonine at 2021-12-02T21:45:49-05:00 Require all dirty_MUT_VAR callers to do explicit stg_MUT_VAR_CLEAN_info comparison (#20088) - - - - - 81082cf4 by Matthew Pickering at 2021-12-03T10:12:04-05:00 Revert "Data.List specialization to []" This reverts commit bddecda1a4c96da21e3f5211743ce5e4c78793a2. This implements the first step in the plan formulated in #20025 to improve the communication and migration strategy for the proposed changes to Data.List. Requires changing the haddock submodule to update the test output. - - - - - a9e035a4 by sheaf at 2021-12-03T10:12:42-05:00 Test-suite: fix geometric mean of empty list The geometric mean computation panicked when it was given an empty list, which happens when there are no baselines. Instead, we should simply return 1. - - - - - d72720f9 by Matthew Pickering at 2021-12-06T16:27:35+00:00 Add section to the user guide about OS memory usage - - - - - 0fe45d43 by Viktor Dukhovni at 2021-12-07T06:27:12-05:00 List-monomorphic `foldr'` While a *strict* (i.e. constant space) right-fold on lists is not possible, the default `foldr'` is optimised for structures like `Seq`, that support efficient access to the right-most elements. The original default implementation seems to have a better constant factor for lists, so we add a monomorphic implementation in GHC.List. Should this be re-exported from `Data.List`? That would be a user-visible change if both `Data.Foldable` and `Data.List` are imported unqualified... - - - - - 7d2283b9 by Ben Gamari at 2021-12-07T06:27:47-05:00 compiler: Eliminate accidental loop in GHC.SysTools.BaseDir As noted in #20757, `GHC.SysTools.BaseDir.findToolDir` previously contained an loop, which would be triggered in the case that the search failed. Closes #20757. - - - - - 8044e232 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 More specific documentation of foldr' caveats - - - - - d932e2d6 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 Use italic big-O notation in Data.Foldable - - - - - 57c9c0a2 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 Fix user-guide typo - - - - - 324772bb by Ben Gamari at 2021-12-07T06:28:59-05:00 rts/Linker: Ensure that mmap_32bit_base is updated after mapping The amount of duplicated code in `mmapForLinker` hid the fact that some codepaths would fail to update `mmap_32bit_base` (specifically, on platforms like OpenBSD where `MAP_32BIT` is not supported). Refactor the function to make the implementation more obviously correct. Closes #20734. - - - - - 5dbdf878 by Ben Gamari at 2021-12-07T06:28:59-05:00 rts: +RTS -DL should imply +RTS -Dl Otherwise the user may be surprised by the missing context provided by the latter. - - - - - 7eb56064 by sheaf at 2021-12-07T06:29:38-05:00 More permissive parsing of higher-rank type IPs The parser now accepts implicit parameters with higher-rank types, such as `foo :: (?ip :: forall a. a -> a) => ...` Before this patch, we instead insisted on parentheses like so: `foo :: (?ip :: (forall a. a -> a)) => ...` The rest of the logic surrounding implicit parameters is unchanged; in particular, even with ImpredicativeTypes, this idiom is not likely to be very useful. Fixes #20654 - - - - - 427f9c12 by sheaf at 2021-12-07T13:32:55-05:00 Re-export GHC.Types from GHC.Exts Several times in the past, it has happened that things from GHC.Types were not re-exported from GHC.Exts, forcing users to import either GHC.Types or GHC.Prim, which are subject to internal change without notice. We now re-export GHC.Types from GHC.Exts, which should avoid this happening again in the future. In particular, we now re-export `Multiplicity` and `MultMul`, which we didn't before. Fixes #20695 - - - - - 483bd04d by Sebastian Graf at 2021-12-07T13:33:31-05:00 Explicit Data.List import list in check-ppr (#20789) `check-ppr` features an import of Data.List without an import list. After 81082cf4, this breaks the local validate flavour because of the compat warning and `-Werror`. So fix that. Fixes #20789. - - - - - cc2bf8e9 by Norman Ramsey at 2021-12-07T17:34:51-05:00 generalize GHC.Cmm.Dataflow to work over any node type See #20725. The commit includes source-code changes and a test case. - - - - - 4c6985cc by Sylvain Henry at 2021-12-07T17:35:30-05:00 Perf: remove an indirection when fetching the unique mask Slight decrease but still noticeable on CI: Baseline Test Metric value New value Change ----------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 747607676.0 747458936.0 -0.0% ManyConstructors(normal) ghc/alloc 4003722296.0 4003530032.0 -0.0% MultiLayerModules(normal) ghc/alloc 3064539560.0 3063984552.0 -0.0% MultiLayerModulesRecomp(normal) ghc/alloc 894700016.0 894700624.0 +0.0% PmSeriesG(normal) ghc/alloc 48410952.0 48262496.0 -0.3% PmSeriesS(normal) ghc/alloc 61561848.0 61415768.0 -0.2% PmSeriesT(normal) ghc/alloc 90975784.0 90829360.0 -0.2% PmSeriesV(normal) ghc/alloc 60405424.0 60259008.0 -0.2% T10421(normal) ghc/alloc 113275928.0 113137168.0 -0.1% T10421a(normal) ghc/alloc 79195676.0 79050112.0 -0.2% T10547(normal) ghc/alloc 28720176.0 28710008.0 -0.0% T10858(normal) ghc/alloc 180992412.0 180857400.0 -0.1% T11195(normal) ghc/alloc 283452220.0 283293832.0 -0.1% T11276(normal) ghc/alloc 137882128.0 137745840.0 -0.1% T11303b(normal) ghc/alloc 44453956.0 44309184.0 -0.3% T11374(normal) ghc/alloc 248118668.0 247979880.0 -0.1% T11545(normal) ghc/alloc 971994728.0 971852696.0 -0.0% T11822(normal) ghc/alloc 131544864.0 131399024.0 -0.1% T12150(optasm) ghc/alloc 79336468.0 79191888.0 -0.2% T12227(normal) ghc/alloc 495064180.0 494943040.0 -0.0% T12234(optasm) ghc/alloc 57198468.0 57053568.0 -0.3% T12425(optasm) ghc/alloc 90928696.0 90793440.0 -0.1% T12545(normal) ghc/alloc 1695417772.0 1695275744.0 -0.0% T12707(normal) ghc/alloc 956258984.0 956138864.0 -0.0% T13035(normal) ghc/alloc 102279484.0 102132616.0 -0.1% T13056(optasm) ghc/alloc 367196556.0 367066408.0 -0.0% T13253(normal) ghc/alloc 334365844.0 334255264.0 -0.0% T13253-spj(normal) ghc/alloc 125474884.0 125328672.0 -0.1% T13379(normal) ghc/alloc 359185604.0 359036960.0 -0.0% T13701(normal) ghc/alloc 2403026480.0 2402677464.0 -0.0% T13719(normal) ghc/alloc 4192234752.0 4192039448.0 -0.0% T14052(ghci) ghc/alloc 2745868552.0 2747706176.0 +0.1% T14052Type(ghci) ghc/alloc 7335937964.0 7336283280.0 +0.0% T14683(normal) ghc/alloc 2992557736.0 2992436872.0 -0.0% T14697(normal) ghc/alloc 363391248.0 363222920.0 -0.0% T15164(normal) ghc/alloc 1292578008.0 1292434240.0 -0.0% T15304(normal) ghc/alloc 1279603472.0 1279465944.0 -0.0% T15630(normal) ghc/alloc 161707776.0 161602632.0 -0.1% T16190(normal) ghc/alloc 276904644.0 276555264.0 -0.1% T16577(normal) ghc/alloc 7573033016.0 7572982752.0 -0.0% T16875(normal) ghc/alloc 34937980.0 34796592.0 -0.4% T17096(normal) ghc/alloc 287436348.0 287299368.0 -0.0% T17516(normal) ghc/alloc 1714727484.0 1714617664.0 -0.0% T17836(normal) ghc/alloc 1091095748.0 1090958168.0 -0.0% T17836b(normal) ghc/alloc 52467912.0 52321296.0 -0.3% T17977(normal) ghc/alloc 44971660.0 44826480.0 -0.3% T17977b(normal) ghc/alloc 40941128.0 40793160.0 -0.4% T18140(normal) ghc/alloc 82363124.0 82213056.0 -0.2% T18223(normal) ghc/alloc 1168448128.0 1168333624.0 -0.0% T18282(normal) ghc/alloc 131577844.0 131440400.0 -0.1% T18304(normal) ghc/alloc 86988664.0 86844432.0 -0.2% T18478(normal) ghc/alloc 742992400.0 742871136.0 -0.0% T18698a(normal) ghc/alloc 337654412.0 337526792.0 -0.0% T18698b(normal) ghc/alloc 398840772.0 398716472.0 -0.0% T18923(normal) ghc/alloc 68964992.0 68818768.0 -0.2% T1969(normal) ghc/alloc 764285884.0 764156168.0 -0.0% T19695(normal) ghc/alloc 1395577984.0 1395552552.0 -0.0% T20049(normal) ghc/alloc 89159032.0 89012952.0 -0.2% T3064(normal) ghc/alloc 191194856.0 191051816.0 -0.1% T3294(normal) ghc/alloc 1604762016.0 1604656488.0 -0.0% T4801(normal) ghc/alloc 296829368.0 296687824.0 -0.0% T5030(normal) ghc/alloc 364720540.0 364580152.0 -0.0% T5321FD(normal) ghc/alloc 271090004.0 270950824.0 -0.1% T5321Fun(normal) ghc/alloc 301244320.0 301102960.0 -0.0% T5631(normal) ghc/alloc 576154548.0 576022904.0 -0.0% T5642(normal) ghc/alloc 471105876.0 470967552.0 -0.0% T5837(normal) ghc/alloc 36328620.0 36186720.0 -0.4% T6048(optasm) ghc/alloc 103125988.0 102981024.0 -0.1% T783(normal) ghc/alloc 386945556.0 386795984.0 -0.0% T9020(optasm) ghc/alloc 247835012.0 247696704.0 -0.1% T9198(normal) ghc/alloc 47556208.0 47413784.0 -0.3% T9233(normal) ghc/alloc 682210596.0 682069960.0 -0.0% T9630(normal) ghc/alloc 1429689648.0 1429581168.0 -0.0% T9675(optasm) ghc/alloc 431092812.0 430943192.0 -0.0% T9872a(normal) ghc/alloc 1705052592.0 1705042064.0 -0.0% T9872b(normal) ghc/alloc 2180406760.0 2180395784.0 -0.0% T9872c(normal) ghc/alloc 1760508464.0 1760497936.0 -0.0% T9872d(normal) ghc/alloc 501517968.0 501309464.0 -0.0% T9961(normal) ghc/alloc 354037204.0 353891576.0 -0.0% TcPlugin_RewritePerf(normal) ghc/alloc 2381708520.0 2381550824.0 -0.0% WWRec(normal) ghc/alloc 589553520.0 589407216.0 -0.0% hard_hole_fits(normal) ghc/alloc 492122188.0 492470648.0 +0.1% hie002(normal) ghc/alloc 9336434800.0 9336443496.0 +0.0% parsing001(normal) ghc/alloc 537680944.0 537659824.0 -0.0% geo. mean -0.1% - - - - - aafa5079 by Andrew Lelechenko at 2021-12-09T04:26:35-05:00 Bump bytestring submodule to 0.11.2.0 Both tests import `Data.ByteString`, so the change in allocations is more or less expected. Metric Increase: T19695 T9630 - - - - - 803eefb1 by Matthew Pickering at 2021-12-09T04:27:11-05:00 package imports: Take into account package visibility when renaming In 806e49ae the package imports refactoring code was modified to rename package imports. There was a small oversight which meant the code didn't account for module visibility. This patch fixes that oversight. In general the "lookupPackageName" function is unsafe to use as it doesn't account for package visiblity/thinning/renaming etc, there is just one use in the compiler which would be good to audit. Fixes #20779 - - - - - 52bbea0f by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 Fix typo and outdated link in Data.Foldable Amazing nobody had reported the "Foldabla" typo. :-( The Traversable docs got overhauled, leaving a stale link in Foldable to a section that got replaced. Gave the new section an anchor and updated the link. - - - - - a722859f by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 A few more typos - - - - - d6177cb5 by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 Drop O(n^2) warning on concat - - - - - 9f988525 by David Feuer at 2021-12-09T13:49:47+00:00 Improve mtimesDefault * Make 'mtimesDefault' use 'stimes' for the underlying monoid rather than the default 'stimes'. * Explain in the documentation why one might use `mtimesDefault`. - - - - - 2fca50d4 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Use same optimization pipeline regardless of `optLevel` (#20500) - - - - - 6d031922 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Add `Opt_CoreConstantFolding` to turn on constant folding (#20500) Previously, `-O1` and `-O2`, by way of their effect on the compilation pipeline, they implicitly turned on constant folding - - - - - b6f7d145 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Remove `optLevel` from `DynFlags` (closes #20500) - - - - - 724df9c3 by Ryan Scott at 2021-12-09T22:15:00-05:00 Hadrian: Allow building with GHC 9.2 A separate issue is the fact that many of `hadrian`'s modules produce `-Wincomplete-uni-patterns` warnings under 9.2, but that is probably best left to a separate patch. - - - - - 80a25502 by Matthew Pickering at 2021-12-09T22:15:35-05:00 Use file hash cache when hashing object file dependencies This fixes the immediate problem that we hash the same file multiple different times which causes quite a noticeably performance regression. In the future we can probably do better than this by storing the implementation hash in the interface file rather than dependending on hashing the object file. Related to #20604 which notes some inefficiencies with the current recompilation logic. Closes #20790 ------------------------- Metric Decrease: T14052Type ------------------------- - - - - - f573cb16 by nineonine at 2021-12-10T06:16:41-05:00 rts: use allocation helpers from RtsUtils Just a tiny cleanup inspired by the following comment: https://gitlab.haskell.org/ghc/ghc/-/issues/19437#note_334271 I was just getting familiar with rts code base so I thought might as well do this. - - - - - 16eab39b by Matthew Pickering at 2021-12-10T06:17:16-05:00 Remove confusing haddock quotes in 'readInt' documentation As pointed out in #20776, placing quotes in this way linked to the 'Integral' type class which is nothing to do with 'readInt', the text should rather just be "integral", to suggest that the argument must be an integer. Closes #20776 - - - - - b4a55419 by Ben Gamari at 2021-12-10T06:17:52-05:00 docs: Drop old release notes Closes #20786 - - - - - 8d1f30e7 by Jakob Brünker at 2021-12-11T00:55:48-05:00 Add PromotedInfixT/PromotedUInfixT to TH Previously, it was not possible to refer to a data constructor using InfixT with a dynamically bound name (i.e. a name with NameFlavour `NameS` or `NameQ`) if a type constructor of the same name exists. This commit adds promoted counterparts to InfixT and UInfixT, analogously to how PromotedT is the promoted counterpart to ConT. Closes #20773 - - - - - 785859fa by Andrew Lelechenko at 2021-12-11T00:56:26-05:00 Bump text submodule to 2.0-rc2 - - - - - 352284de by Sylvain Henry at 2021-12-11T00:57:05-05:00 Perf: remove allocation in writeBlocks and fix comment (#14309) - - - - - 40a44f68 by Douglas Wilson at 2021-12-12T09:09:30-05:00 rts: correct stats when running with +RTS -qn1 Despite the documented care having been taken, several bugs are fixed here. When run with -qn1, when a SYNC_GC_PAR is requested we will have n_gc_threads == n_capabilities && n_gc_idle_threads == (n_gc_threads - 1) In this case we now: * Don't increment par_collections * Don't increment par_balanced_copied * Don't emit debug traces for idle threads * Take the fast path in scavenge_until_all_done, wakeup_gc_threads, and shutdown_gc_threads. Some ASSERTs have also been tightened. Fixes #19685 - - - - - 6b2947d2 by Matthew Pickering at 2021-12-12T09:10:06-05:00 iserv: Remove network dependent parts of libiserv As noted in #20794 the parts of libiserv and iserv-proxy depend on network, therefore are never built nor tested during CI. Due to this iserv-proxy had bitrotted due to the bound on bytestring being out of date. Given we don't test this code it seems undesirable to distribute it. Therefore, it's removed and an external maintainer can be responsible for testing it (via head.hackage if desired). Fixes #20794 - - - - - f04d1a49 by Ben Gamari at 2021-12-12T09:10:41-05:00 gitlab-ci: Bump fedora jobs to use Fedora 33 Annoyingly, this will require downstream changes in head.hackage, which depends upon the artifact produced by this job. Prompted by !6462. - - - - - 93783e6a by Andrey Mokhov at 2021-12-12T09:11:20-05:00 Drop --configure from Hadrian docs - - - - - 31bf380f by Oleg Grenrus at 2021-12-12T12:52:18-05:00 Use HasCallStack and error in GHC.List and .NonEmpty In addition to providing stack traces, the scary HasCallStack will hopefully make people think whether they want to use these functions, i.e. act as a documentation hint that something weird might happen. A single metric increased, which doesn't visibly use any method with `HasCallStack`. ------------------------- Metric Decrease: T9630 Metric Decrease: T19695 T9630 ------------------------- - - - - - 401ddd53 by Greg Steuck at 2021-12-12T12:52:56-05:00 Respect W^X in Linker.c:preloadObjectFile on OpenBSD This fixes -fexternal-interpreter for ghci. Fixes #20814. - - - - - c43ee6b8 by Andreas Klebinger at 2021-12-14T19:24:20+01:00 GHC.Utils.Misc.only: Add doc string. This function expects a singleton list as argument but only checks this in debug builds. I've added a docstring saying so. Fixes #20797 - - - - - 9ff54ea8 by Vaibhav Sagar at 2021-12-14T20:50:08-05:00 Data.Functor.Classes: fix Ord1 instance for Down - - - - - 8a2de3c2 by Tamar Christina at 2021-12-14T20:50:47-05:00 rts: update xxhash used by the linker's hashmap - - - - - 1c8d609a by alirezaghey at 2021-12-14T20:51:25-05:00 fix ambiguity in `const` documentation fixes #20412 - - - - - a5d8d47f by Joachim Breitner at 2021-12-14T20:52:00-05:00 Ghci environment: Do not remove shadowed ids Names defined earier but shadowed need to be kept around, e.g. for type signatures: ``` ghci> data T = T ghci> let t = T ghci> data T = T ghci> :t t t :: Ghci1.T ``` and indeed they can be used: ``` ghci> let t2 = Ghci1.T :: Ghci1.T ghci> :t t2 t2 :: Ghci1.T ``` However, previously this did not happen for ids (non-types), although they are still around under the qualified name internally: ``` ghci> let t = "other t" ghci> t' <interactive>:8:1: error: • Variable not in scope: t' • Perhaps you meant one of these: ‘Ghci2.t’ (imported from Ghci2), ‘t’ (line 7), ‘t2’ (line 5) ghci> Ghci2.t <interactive>:9:1: error: • GHC internal error: ‘Ghci2.t’ is not in scope during type checking, but it passed the renamer tcl_env of environment: [] • In the expression: Ghci2.t In an equation for ‘it’: it = Ghci2.t ``` This fixes the problem by simply removing the code that tries to remove shadowed ids from the environment. Now you can refer to shadowed ids using `Ghci2.t`, just like you can do for data and type constructors. This simplifies the code, makes terms and types more similar, and also fixes #20455. Now all names ever defined in GHCi are in `ic_tythings`, which is printed by `:show bindings`. But for that commands, it seems to be more ergonomic to only list those bindings that are not shadowed. Or, even if it is not more ergonomic, it’s the current behavour. So let's restore that by filtering in `icInScopeTTs`. Of course a single `TyThing` can be associated with many names. We keep it it in the bindings if _any_ of its names are still visible unqualifiedly. It's a judgement call. This commit also turns a rather old comment into a test files. The comment is is rather stale and things are better explained elsewhere. Fixes #925. Two test cases are regressing: T14052(ghci) ghc/alloc 2749444288.0 12192109912.0 +343.4% BAD T14052Type(ghci) ghc/alloc 7365784616.0 10767078344.0 +46.2% BAD This is not unexpected; the `ic_tythings list grows` a lot more if we don’t remove shadowed Ids. I tried to alleviate it a bit with earlier MRs, but couldn’t make up for it completely. Metric Increase: T14052 T14052Type - - - - - 7c2609d8 by Cheng Shao at 2021-12-14T20:52:37-05:00 base: fix clockid_t usage when it's a pointer type in C Closes #20607. - - - - - 55cb2aa7 by MichaWiedenmann1 at 2021-12-14T20:53:16-05:00 Fixes typo in documentation of the Semigroup instance of Equivalence - - - - - 82c39f4d by Ben Gamari at 2021-12-14T20:53:51-05:00 users-guide: Fix documentation for -shared flag This flag was previously called `--mk-dll`. It was renamed to `-shared` in b562cbe381d54e08dcafa11339e9a82e781ad557 but the documentation wasn't updated to match. - - - - - 4f654071 by Ben Gamari at 2021-12-14T20:53:51-05:00 compiler: Drop `Maybe ModLocation` from T_MergeForeign This field was entirely unused. - - - - - 71ecb55b by Ben Gamari at 2021-12-14T20:53:51-05:00 compiler: Use withFile instead of bracket A minor refactoring noticed by hlint. - - - - - 5686f47b by Ben Gamari at 2021-12-14T20:53:51-05:00 ghc-bin: Add --merge-objs mode This adds a new mode, `--merge-objs`, which can be used to produce merged GHCi library objects. As future work we will rip out the object-merging logic in Hadrian and Cabal and instead use this mode. Closes #20712. - - - - - 0198bb11 by Ben Gamari at 2021-12-14T20:54:27-05:00 libiserv: Rename Lib module to IServ As proposed in #20546. - - - - - ecaec722 by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm: Remove DynFlags, add LlvmCgConfig CodeOutput: LCGConfig, add handshake initLCGConfig Add two modules: GHC.CmmToLlvm.Config -- to hold the Llvm code gen config GHC.Driver.Config.CmmToLlvm -- for initialization, other utils CmmToLlvm: remove HasDynFlags, add LlvmConfig CmmToLlvm: add lcgContext to LCGConfig CmmToLlvm.Base: DynFlags --> LCGConfig Llvm: absorb LlvmOpts into LCGConfig CmmToLlvm.Ppr: swap DynFlags --> LCGConfig CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig CmmToLlvm.Data: swap LlvmOpts --> LCGConfig CmmToLlvm: swap DynFlags --> LCGConfig CmmToLlvm: move LlvmVersion to CmmToLlvm.Config Additionally: - refactor Config and initConfig to hold LlvmVersion - push IO needed to get LlvmVersion to boundary between Cmm and LLvm code generation - remove redundant imports, this is much cleaner! CmmToLlvm.Config: store platformMisc_llvmTarget instead of all of platformMisc - - - - - 6b0fb9a0 by doyougnu at 2021-12-14T20:55:06-05:00 SysTools.Tasks Llvm.Types: remove redundant import Llvm.Types: remove redundant import SysTools.Tasks: remove redundant import - namely CmmToLlvm.Base - - - - - 80016022 by doyougnu at 2021-12-14T20:55:06-05:00 LLVM.CodeGen: use fast-string literals That is remove factorization of common strings and string building code for the LLVM code gen ops. Replace these with string literals to obey the FastString rewrite rule in GHC.Data.FastString and compute the string length at compile time - - - - - bc663f87 by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm.Config: strictify LlvmConfig field - - - - - 70f0aafe by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm: rename LCGConfig -> LlvmCgConfig CmmToLlvm: renamce lcgPlatform -> llvmCgPlatform CmmToLlvm: rename lcgContext -> llvmCgContext CmmToLlvm: rename lcgFillUndefWithGarbage CmmToLlvm: rename lcgSplitSections CmmToLlvm: lcgBmiVersion -> llvmCgBmiVersion CmmToLlvm: lcgLlvmVersion -> llvmCgLlvmVersion CmmToLlvm: lcgDoWarn -> llvmCgDoWarn CmmToLlvm: lcgLlvmConfig -> llvmCgLlvmConfig CmmToLlvm: llvmCgPlatformMisc --> llvmCgLlvmTarget - - - - - 34abbd81 by Greg Steuck at 2021-12-14T20:55:43-05:00 Add OpenBSD to llvm-targets This improves some tests that previously failed with: ghc: panic! (the 'impossible' happened) GHC version 9.3.20211211: Failed to lookup LLVM data layout Target: x86_64-unknown-openbsd Added the new generated lines to `llvm-targets` on an openbsd 7.0-current with clang 11.1.0. - - - - - 45bd6308 by Joachim Breitner at 2021-12-14T20:56:18-05:00 Test case from #19313 - - - - - f5a0b408 by Andrei Barbu at 2021-12-15T16:33:17-05:00 Plugin load order should follow the commandline order (fixes #17884) In the past the order was reversed because flags are consed onto a list. No particular behavior was documented. We now reverse the flags and document the behavior. - - - - - d13b9f20 by Cheng Shao at 2021-12-15T16:33:54-05:00 base: use `CUIntPtr` instead of `Ptr ()` as the autoconf detected Haskell type for C pointers When autoconf detects a C pointer type, we used to specify `Ptr ()` as the Haskell type. This doesn't work in some cases, e.g. in `wasi-libc`, `clockid_t` is a pointer type, but we expected `CClockId` to be an integral type, and `Ptr ()` lacks various integral type instances. - - - - - 89c1ffd6 by Cheng Shao at 2021-12-15T16:33:54-05:00 base: fix autoconf detection of C pointer types We used to attempt compiling `foo_t val; *val;` to determine if `foo_t` is a pointer type in C. This doesn't work if `foo_t` points to an incomplete type, and autoconf will detect `foo_t` as a floating point type in that case. Now we use `memset(val, 0, 0)` instead, and it works for incomplete types as well. - - - - - 6cea7311 by Cheng Shao at 2021-12-15T16:33:54-05:00 Add a note to base changelog - - - - - 3c3e5c03 by Ben Gamari at 2021-12-17T21:20:57-05:00 Regression test for renamer/typechecker performance (#20261) We use the parser generated by stack to ensure reproducibility - - - - - 5d5620bc by Krzysztof Gogolewski at 2021-12-17T21:21:32-05:00 Change isUnliftedTyCon to marshalablePrimTyCon (#20401) isUnliftedTyCon was used in three places: Ticky, Template Haskell and FFI checks. It was straightforward to remove it from Ticky and Template Haskell. It is now used in FFI only and renamed to marshalablePrimTyCon. Previously, it was fetching information from a field in PrimTyCon called is_unlifted. Instead, I've changed the code to compute liftedness based on the kind. isFFITy and legalFFITyCon are removed. They were only referred from an old comment that I removed. There were three functions to define a PrimTyCon, but the only difference was that they were setting is_unlifted to True or False. Everything is now done in mkPrimTyCon. I also added missing integer types in Ticky.hs, I think it was an oversight. Fixes #20401 - - - - - 9d77976d by Matthew Pickering at 2021-12-17T21:22:08-05:00 testsuite: Format metric results with comma separator As noted in #20763 the way the stats were printed was quite hard for a human to compare. Therefore we now insert the comma separator so that they are easier to compare at a glance. Before: ``` Baseline Test Metric value New value Change ----------------------------------------------------------------------------- Conversions(normal) run/alloc 107088.0 107088.0 +0.0% DeriveNull(normal) run/alloc 112050656.0 112050656.0 +0.0% InlineArrayAlloc(normal) run/alloc 1600040712.0 1600040712.0 +0.0% InlineByteArrayAlloc(normal) run/alloc 1440040712.0 1440040712.0 +0.0% InlineCloneArrayAlloc(normal) run/alloc 1600040872.0 1600040872.0 +0.0% MethSharing(normal) run/alloc 480097864.0 480097864.0 +0.0% T10359(normal) run/alloc 354344.0 354344.0 +0.0% ``` After ``` Baseline Test Metric value New value Change ---------------------------------------------------------------------------------- Conversions(normal) run/alloc 107,088 107,088 +0.0% DeriveNull(normal) run/alloc 112,050,656 112,050,656 +0.0% InlineArrayAlloc(normal) run/alloc 1,600,040,712 1,600,040,712 +0.0% InlineByteArrayAlloc(normal) run/alloc 1,440,040,712 1,440,040,712 +0.0% InlineCloneArrayAlloc(normal) run/alloc 1,600,040,872 1,600,040,872 +0.0% MethSharing(normal) run/alloc 480,097,864 480,097,864 +0.0% T10359(normal) run/alloc 354,344 354,344 +0.0% ``` Closes #20763 - - - - - 3f31bfe8 by Sylvain Henry at 2021-12-17T21:22:48-05:00 Perf: inline exprIsCheapX Allow specialization for the ok_app predicate. Perf improvements: Baseline Test Metric value New value Change ----------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 747317244.0 746444024.0 -0.1% ManyConstructors(normal) ghc/alloc 4005046448.0 4001548792.0 -0.1% MultiLayerModules(normal) ghc/alloc 3063361000.0 3063178472.0 -0.0% MultiLayerModulesRecomp(normal) ghc/alloc 894208428.0 894252496.0 +0.0% PmSeriesG(normal) ghc/alloc 48021692.0 47901592.0 -0.3% PmSeriesS(normal) ghc/alloc 61322504.0 61149008.0 -0.3% PmSeriesT(normal) ghc/alloc 90879364.0 90609048.0 -0.3% PmSeriesV(normal) ghc/alloc 60155376.0 59983632.0 -0.3% T10421(normal) ghc/alloc 112820720.0 112517208.0 -0.3% T10421a(normal) ghc/alloc 78783696.0 78557896.0 -0.3% T10547(normal) ghc/alloc 28331984.0 28354160.0 +0.1% T10858(normal) ghc/alloc 180715296.0 180226720.0 -0.3% T11195(normal) ghc/alloc 284139184.0 283981048.0 -0.1% T11276(normal) ghc/alloc 137830804.0 137688912.0 -0.1% T11303b(normal) ghc/alloc 44080856.0 43956152.0 -0.3% T11374(normal) ghc/alloc 249319644.0 249059288.0 -0.1% T11545(normal) ghc/alloc 971507488.0 971146136.0 -0.0% T11822(normal) ghc/alloc 131410208.0 131269664.0 -0.1% T12150(optasm) ghc/alloc 78866860.0 78762296.0 -0.1% T12227(normal) ghc/alloc 494467900.0 494138112.0 -0.1% T12234(optasm) ghc/alloc 56781044.0 56588256.0 -0.3% T12425(optasm) ghc/alloc 90462264.0 90240272.0 -0.2% T12545(normal) ghc/alloc 1694316588.0 1694128448.0 -0.0% T12707(normal) ghc/alloc 955665168.0 955005336.0 -0.1% T13035(normal) ghc/alloc 101875160.0 101713312.0 -0.2% T13056(optasm) ghc/alloc 366370168.0 365347632.0 -0.3% T13253(normal) ghc/alloc 333741472.0 332612920.0 -0.3% T13253-spj(normal) ghc/alloc 124947560.0 124427552.0 -0.4% T13379(normal) ghc/alloc 358997996.0 358879840.0 -0.0% T13701(normal) ghc/alloc 2400391456.0 2399956840.0 -0.0% T13719(normal) ghc/alloc 4193179228.0 4192476392.0 -0.0% T14052(ghci) ghc/alloc 2734741552.0 2735731808.0 +0.0% T14052Type(ghci) ghc/alloc 7323235724.0 7323042264.0 -0.0% T14683(normal) ghc/alloc 2990457260.0 2988899144.0 -0.1% T14697(normal) ghc/alloc 363606476.0 363452952.0 -0.0% T15164(normal) ghc/alloc 1291321780.0 1289491968.0 -0.1% T15304(normal) ghc/alloc 1277838020.0 1276208304.0 -0.1% T15630(normal) ghc/alloc 161074632.0 160388136.0 -0.4% T16190(normal) ghc/alloc 276567192.0 276235216.0 -0.1% T16577(normal) ghc/alloc 7564318656.0 7535598656.0 -0.4% T16875(normal) ghc/alloc 34867720.0 34752440.0 -0.3% T17096(normal) ghc/alloc 288477360.0 288156960.0 -0.1% T17516(normal) ghc/alloc 1712777224.0 1704655496.0 -0.5% T17836(normal) ghc/alloc 1092127336.0 1091709880.0 -0.0% T17836b(normal) ghc/alloc 52083516.0 51954056.0 -0.2% T17977(normal) ghc/alloc 44552228.0 44425448.0 -0.3% T17977b(normal) ghc/alloc 40540252.0 40416856.0 -0.3% T18140(normal) ghc/alloc 81908200.0 81678928.0 -0.3% T18223(normal) ghc/alloc 1166459176.0 1164418104.0 -0.2% T18282(normal) ghc/alloc 131123648.0 130740432.0 -0.3% T18304(normal) ghc/alloc 86486796.0 86223088.0 -0.3% T18478(normal) ghc/alloc 746029440.0 745619968.0 -0.1% T18698a(normal) ghc/alloc 337037580.0 336533824.0 -0.1% T18698b(normal) ghc/alloc 398324600.0 397696400.0 -0.2% T18923(normal) ghc/alloc 68496432.0 68286264.0 -0.3% T1969(normal) ghc/alloc 760424696.0 759641664.0 -0.1% T19695(normal) ghc/alloc 1421672472.0 1413682104.0 -0.6% T20049(normal) ghc/alloc 88601524.0 88336560.0 -0.3% T3064(normal) ghc/alloc 190808832.0 190659328.0 -0.1% T3294(normal) ghc/alloc 1604483120.0 1604339080.0 -0.0% T4801(normal) ghc/alloc 296501624.0 296388448.0 -0.0% T5030(normal) ghc/alloc 364336308.0 364206240.0 -0.0% T5321FD(normal) ghc/alloc 270688492.0 270386832.0 -0.1% T5321Fun(normal) ghc/alloc 300860396.0 300559200.0 -0.1% T5631(normal) ghc/alloc 575822760.0 575579160.0 -0.0% T5642(normal) ghc/alloc 470243356.0 468988784.0 -0.3% T5837(normal) ghc/alloc 35936468.0 35821360.0 -0.3% T6048(optasm) ghc/alloc 102587024.0 102222000.0 -0.4% T783(normal) ghc/alloc 386539204.0 386003344.0 -0.1% T9020(optasm) ghc/alloc 247435312.0 247324184.0 -0.0% T9198(normal) ghc/alloc 47170036.0 47054840.0 -0.2% T9233(normal) ghc/alloc 677186820.0 676550032.0 -0.1% T9630(normal) ghc/alloc 1456411516.0 1451045736.0 -0.4% T9675(optasm) ghc/alloc 427190224.0 426812568.0 -0.1% T9872a(normal) ghc/alloc 1704660040.0 1704681856.0 +0.0% T9872b(normal) ghc/alloc 2180109488.0 2180130856.0 +0.0% T9872c(normal) ghc/alloc 1760209640.0 1760231456.0 +0.0% T9872d(normal) ghc/alloc 501126052.0 500973488.0 -0.0% T9961(normal) ghc/alloc 353244688.0 353063104.0 -0.1% TcPlugin_RewritePerf(normal) ghc/alloc 2387276808.0 2387254168.0 -0.0% WWRec(normal) ghc/alloc 588651140.0 587684704.0 -0.2% hard_hole_fits(normal) ghc/alloc 492063812.0 491798360.0 -0.1% hie002(normal) ghc/alloc 9334355960.0 9334396872.0 +0.0% parsing001(normal) ghc/alloc 537410584.0 537421736.0 +0.0% geo. mean -0.2% - - - - - e04878b0 by Matthew Pickering at 2021-12-17T21:23:23-05:00 ci: Use correct metrics baseline It turns out there was already a function in the CI script to correctly set the baseline for performance tests but it was just never called. I now call it during the initialisation to set the correct baseline. I also made the make testsuite driver take into account the PERF_BASELINE_COMMIT environment variable Fixes #20811 - - - - - 1327c176 by Matthew Pickering at 2021-12-17T21:23:58-05:00 Add regression test for T20189 Closes #20189 - - - - - fc9b1755 by Matthew Pickering at 2021-12-17T21:24:33-05:00 Fix documentation formatting in Language.Haskell.TH.CodeDo Fixes #20543 - - - - - abef93f3 by Matthew Pickering at 2021-12-17T21:24:33-05:00 Expand documentation for MulArrowT constructor Fixes #20812 - - - - - 94c3ff66 by Cheng Shao at 2021-12-17T21:25:09-05:00 Binary: make withBinBuffer safe With this patch, withBinBuffer will construct a ByteString that properly captures the reference to the BinHandle internal MutableByteArray#, making it safe to convert a BinHandle to ByteString and use that ByteString outside the continuation. - - - - - a3552934 by Sebastian Graf at 2021-12-17T21:25:45-05:00 Demand: `Eq DmdType` modulo `defaultFvDmd` (#20827) Fixes #20827 by filtering out any default free variable demands (as per `defaultFvDmd`) prior to comparing the assocs of the `DmdEnv`. The details are in `Note [Demand type Equality]`. - - - - - 9529d859 by Sylvain Henry at 2021-12-17T21:26:24-05:00 Perf: avoid using (replicateM . length) when possible Extracted from !6622 - - - - - 887d8b4c by Matthew Pickering at 2021-12-17T21:26:59-05:00 testsuite: Ensure that -dcore-lint is not set for compiler performance tests This place ensures that the default -dcore-lint option is disabled by default when collect_compiler_stats is used but you can still pass -dcore-lint as an additional option (see T1969 which tests core lint performance). Fixes #20830 ------------------------- Metric Decrease: PmSeriesS PmSeriesT PmSeriesV T10858 T11195 T11276 T11374 T11822 T14052 T14052Type T17096 T17836 T17836b T18478 T18698a T18698b ------------------------- - - - - - 5ff47ff5 by Ben Gamari at 2021-12-21T01:46:00-05:00 codeGen: Introduce flag to bounds-check array accesses Here we introduce code generator support for instrument array primops with bounds checking, enabled with the `-fcheck-prim-bounds` flag. Introduced to debug #20769. - - - - - d47bb109 by Ben Gamari at 2021-12-21T01:46:00-05:00 rts: Add optional bounds checking in out-of-line primops - - - - - 8ea79a16 by Ben Gamari at 2021-12-21T01:46:00-05:00 Rename -fcatch-bottoms to -fcatch-nonexhaustive-cases As noted in #20601, the previous name was rather misleading. - - - - - 00b55bfc by Ben Gamari at 2021-12-21T01:46:00-05:00 Introduce -dlint flag As suggested in #20601, this is a short-hand for enabling the usual GHC-internal sanity checks one typically leans on when debugging runtime crashes. - - - - - 9728d6c2 by Sylvain Henry at 2021-12-21T01:46:39-05:00 Give plugins a better interface (#17957) Plugins were directly fetched from HscEnv (hsc_static_plugins and hsc_plugins). The tight coupling of plugins and of HscEnv is undesirable and it's better to store them in a new Plugins datatype and to use it in the plugins' API (e.g. withPlugins, mapPlugins...). In the process, the interactive context (used by GHCi) got proper support for different static plugins than those used for loaded modules. Bump haddock submodule - - - - - 9bc5ab64 by Greg Steuck at 2021-12-21T01:47:17-05:00 Use libc++ instead of libstdc++ on openbsd in addition to freebsd This is not entirely accurate because some openbsd architectures use gcc. Yet we don't have ghc ported to them and thus the approximation is good enough. Fixes ghcilink006 test - - - - - f92c9c0d by Greg Steuck at 2021-12-21T01:47:55-05:00 Only use -ldl conditionally to fix T3807 OpenBSD doesn't have this library and so the linker complains: ld.lld: error: unable to find library -ldl - - - - - ff657a81 by Greg Steuck at 2021-12-21T01:48:32-05:00 Mark `linkwhole` test as expected broken on OpenBSD per #20841 - - - - - 1a596d06 by doyougnu at 2021-12-22T00:12:27-05:00 Cmm: DynFlags to CmmConfig refactor add files GHC.Cmm.Config, GHC.Driver.Config.Cmm Cmm: DynFlag references --> CmmConfig Cmm.Pipeline: reorder imports, add handshake Cmm: DynFlag references --> CmmConfig Cmm.Pipeline: DynFlag references --> CmmConfig Cmm.LayoutStack: DynFlag references -> CmmConfig Cmm.Info.Build: DynFlag references -> CmmConfig Cmm.Config: use profile to retrieve platform Cmm.CLabel: unpack NCGConfig in labelDynamic Cmm.Config: reduce CmmConfig surface area Cmm.Config: add cmmDoCmmSwitchPlans field Cmm.Config: correct cmmDoCmmSwitchPlans flag The original implementation dispatches work in cmmImplementSwitchPlans in an `otherwise` branch, hence we must add a not to correctly dispatch Cmm.Config: add cmmSplitProcPoints simplify Config remove cmmBackend, and cmmPosInd Cmm.CmmToAsm: move ncgLabelDynamic to CmmToAsm Cmm.CLabel: remove cmmLabelDynamic function Cmm.Config: rename cmmOptDoLinting -> cmmDoLinting testsuite: update CountDepsAst CountDepsParser - - - - - d7cc8f19 by Matthew Pickering at 2021-12-22T00:13:02-05:00 ci: Fix master CI I made a mistake in the bash script so there were errors about "$CI_MERGE_REQUEST_DIFF_BASE_SHA" not existing. - - - - - 09b6cb45 by Alan Zimmerman at 2021-12-22T00:13:38-05:00 Fix panic trying to -ddump-parsed-ast for implicit fixity A declaration such as infixr ++++ is supplied with an implicit fixity of 9 in the parser, but uses an invalid SrcSpan to capture this. Use of this span triggers a panic. Fix the problem by not recording an exact print annotation for the non-existent fixity source. Closes #20846 - - - - - 3ed90911 by Matthew Pickering at 2021-12-22T14:47:40-05:00 testsuite: Remove reqlib modifier The reqlib modifer was supposed to indicate that a test needed a certain library in order to work. If the library happened to be installed then the test would run as normal. However, CI has never run these tests as the packages have not been installed and we don't want out tests to depend on things which might get externally broken by updating the compiler. The new strategy is to run these tests in head.hackage, where the tests have been cabalised as well as possible. Some tests couldn't be transferred into the normal style testsuite but it's better than never running any of the reqlib tests. https://gitlab.haskell.org/ghc/head.hackage/-/merge_requests/169 A few submodules also had reqlib tests and have been updated to remove it. Closes #16264 #20032 #17764 #16561 - - - - - ac3e8c52 by Matthew Pickering at 2021-12-22T14:48:16-05:00 perf ci: Start searching form the performance baseline If you specify PERF_BASELINE_COMMIT then this can fail if the specific commit you selected didn't have perf test metrics. (This can happen in CI for example if a build fails on master). Therefore instead of just reporting all tests as new, we start searching downwards from this point to try and find a good commit to report numbers from. - - - - - 9552781a by Matthew Pickering at 2021-12-22T14:48:51-05:00 Mark T16525b as fragile on windows See ticket #20852 - - - - - 13a6d85a by Andreas Klebinger at 2021-12-23T10:55:36-05:00 Make callerCC profiling mode represent entry counter flag. Fixes #20854 - - - - - 80daefce by Matthew Pickering at 2021-12-23T10:56:11-05:00 Properly filter for module visibility in resolvePackageImport This completes the fix for #20779 / !7123. Beforehand, the program worked by accident because the two versions of the library happened to be ordered properly (due to how the hashes were computed). In the real world I observed them being the other way around which meant the final lookup failed because we weren't filtering for visibility. I modified the test so that it failed (and it's fixed by this patch). - - - - - e6191d39 by Krzysztof Gogolewski at 2021-12-25T18:26:44+01:00 Fix typos - - - - - 3219610e by Greg Steuck at 2021-12-26T22:12:43-05:00 Use POSIX-compliant egrep expression to fix T8832 on OpenBSD - - - - - fd42ab5f by Matthew Pickering at 2021-12-28T09:47:53+00:00 Multiple Home Units Multiple home units allows you to load different packages which may depend on each other into one GHC session. This will allow both GHCi and HLS to support multi component projects more naturally. Public Interface ~~~~~~~~~~~~~~~~ In order to specify multiple units, the -unit @⟨filename⟩ flag is given multiple times with a response file containing the arguments for each unit. The response file contains a newline separated list of arguments. ``` ghc -unit @unitLibCore -unit @unitLib ``` where the `unitLibCore` response file contains the normal arguments that cabal would pass to `--make` mode. ``` -this-unit-id lib-core-0.1.0.0 -i -isrc LibCore.Utils LibCore.Types ``` The response file for lib, can specify a dependency on lib-core, so then modules in lib can use modules from lib-core. ``` -this-unit-id lib-0.1.0.0 -package-id lib-core-0.1.0.0 -i -isrc Lib.Parse Lib.Render ``` Then when the compiler starts in --make mode it will compile both units lib and lib-core. There is also very basic support for multiple home units in GHCi, at the moment you can start a GHCi session with multiple units but only the :reload is supported. Most commands in GHCi assume a single home unit, and so it is additional work to work out how to modify the interface to support multiple loaded home units. Options used when working with Multiple Home Units There are a few extra flags which have been introduced specifically for working with multiple home units. The flags allow a home unit to pretend it’s more like an installed package, for example, specifying the package name, module visibility and reexported modules. -working-dir ⟨dir⟩ It is common to assume that a package is compiled in the directory where its cabal file resides. Thus, all paths used in the compiler are assumed to be relative to this directory. When there are multiple home units the compiler is often not operating in the standard directory and instead where the cabal.project file is located. In this case the -working-dir option can be passed which specifies the path from the current directory to the directory the unit assumes to be it’s root, normally the directory which contains the cabal file. When the flag is passed, any relative paths used by the compiler are offset by the working directory. Notably this includes -i and -I⟨dir⟩ flags. -this-package-name ⟨name⟩ This flag papers over the awkward interaction of the PackageImports and multiple home units. When using PackageImports you can specify the name of the package in an import to disambiguate between modules which appear in multiple packages with the same name. This flag allows a home unit to be given a package name so that you can also disambiguate between multiple home units which provide modules with the same name. -hidden-module ⟨module name⟩ This flag can be supplied multiple times in order to specify which modules in a home unit should not be visible outside of the unit it belongs to. The main use of this flag is to be able to recreate the difference between an exposed and hidden module for installed packages. -reexported-module ⟨module name⟩ This flag can be supplied multiple times in order to specify which modules are not defined in a unit but should be reexported. The effect is that other units will see this module as if it was defined in this unit. The use of this flag is to be able to replicate the reexported modules feature of packages with multiple home units. Offsetting Paths in Template Haskell splices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When using Template Haskell to embed files into your program, traditionally the paths have been interpreted relative to the directory where the .cabal file resides. This causes problems for multiple home units as we are compiling many different libraries at once which have .cabal files in different directories. For this purpose we have introduced a way to query the value of the -working-dir flag to the Template Haskell API. By using this function we can implement a makeRelativeToProject function which offsets a path which is relative to the original project root by the value of -working-dir. ``` import Language.Haskell.TH.Syntax ( makeRelativeToProject ) foo = $(makeRelativeToProject "./relative/path" >>= embedFile) ``` > If you write a relative path in a Template Haskell splice you should use the makeRelativeToProject function so that your library works correctly with multiple home units. A similar function already exists in the file-embed library. The function in template-haskell implements this function in a more robust manner by honouring the -working-dir flag rather than searching the file system. Closure Property for Home Units ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For tools or libraries using the API there is one very important closure property which must be adhered to: > Any dependency which is not a home unit must not (transitively) depend on a home unit. For example, if you have three packages p, q and r, then if p depends on q which depends on r then it is illegal to load both p and r as home units but not q, because q is a dependency of the home unit p which depends on another home unit r. If you are using GHC by the command line then this property is checked, but if you are using the API then you need to check this property yourself. If you get it wrong you will probably get some very confusing errors about overlapping instances. Limitations of Multiple Home Units ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are a few limitations of the initial implementation which will be smoothed out on user demand. * Package thinning/renaming syntax is not supported * More complicated reexports/renaming are not yet supported. * It’s more common to run into existing linker bugs when loading a large number of packages in a session (for example #20674, #20689) * Backpack is not yet supported when using multiple home units. * Dependency chasing can be quite slow with a large number of modules and packages. * Loading wired-in packages as home units is currently not supported (this only really affects GHC developers attempting to load template-haskell). * Barely any normal GHCi features are supported, it would be good to support enough for ghcid to work correctly. Despite these limitations, the implementation works already for nearly all packages. It has been testing on large dependency closures, including the whole of head.hackage which is a total of 4784 modules from 452 packages. Internal Changes ~~~~~~~~~~~~~~~~ * The biggest change is that the HomePackageTable is replaced with the HomeUnitGraph. The HomeUnitGraph is a map from UnitId to HomeUnitEnv, which contains information specific to each home unit. * The HomeUnitEnv contains: - A unit state, each home unit can have different package db flags - A set of dynflags, each home unit can have different flags - A HomePackageTable * LinkNode: A new node type is added to the ModuleGraph, this is used to place the linking step into the build plan so linking can proceed in parralel with other packages being built. * New invariant: Dependencies of a ModuleGraphNode can be completely determined by looking at the value of the node. In order to achieve this, downsweep now performs a more complete job of downsweeping and then the dependenices are recorded forever in the node rather than being computed again from the ModSummary. * Some transitive module calculations are rewritten to use the ModuleGraph which is more efficient. * There is always an active home unit, which simplifies modifying a lot of the existing API code which is unit agnostic (for example, in the driver). The road may be bumpy for a little while after this change but the basics are well-tested. One small metric increase, which we accept and also submodule update to haddock which removes ExtendedModSummary. Closes #10827 ------------------------- Metric Increase: MultiLayerModules ------------------------- Co-authored-by: Fendor <power.walross at gmail.com> - - - - - 72824c63 by Richard Eisenberg at 2021-12-28T10:09:28-05:00 Skip computing superclass origins for equalities This yields a small, but measurable, performance improvement. - - - - - 8b6aafb2 by Matthew Pickering at 2021-12-29T14:09:47-05:00 Cabal: Update submodule Closes #20874 - - - - - 44a5507f by Peter Trommler at 2021-12-29T14:10:22-05:00 RTS: Fix CloneStack.c when no table next to code Function `lookupIPE` does not modify its argument. Reflect this in the type. Module `CloneStack.c` relies on this for RTS without tables next to code. Fixes #20879 - - - - - 246d2782 by sheaf at 2022-01-02T04:20:09-05:00 User's guide: newtype decls can use GADTSyntax The user's guide failed to explicitly mention that GADTSyntax can be used to declare newtypes, so we add an example and a couple of explanations. Also explains that `-XGADTs` generalises `-XExistentialQuantification`. Fixes #20848 and #20865. - - - - - f212cece by Hécate Moonlight at 2022-01-02T04:20:47-05:00 Add a source-repository stanza to rts/rts.cabal - - - - - d9e49195 by Greg Steuck at 2022-01-03T05:18:24+00:00 Replace `seq` with POSIX-standard printf(1) in ManyAlternatives test The test now passes on OpenBSD instead of generating broken source which was rejected by GHC with ManyAlternatives.hs:5:1: error: The type signature for ‘f’ lacks an accompanying binding - - - - - 80e416ae by Greg Steuck at 2022-01-03T05:18:24+00:00 Replace `seq` with POSIX-standard in PmSeriesG test - - - - - 8fa52f5c by Eric Lindblad at 2022-01-03T16:48:51-05:00 fix typo - - - - - a49f5889 by Roland Senn at 2022-01-03T16:49:29-05:00 Add regressiontest for #18045 Issue #18045 got fixed by !6971. - - - - - 7f10686e by sheaf at 2022-01-03T16:50:07-05:00 Add test for #20894 - - - - - 5111028e by sheaf at 2022-01-04T19:56:13-05:00 Check quoted TH names are in the correct namespace When quoting (using a TH single or double quote) a built-in name such as the list constructor (:), we didn't always check that the resulting 'Name' was in the correct namespace. This patch adds a check in GHC.Rename.Splice to ensure we get a Name that is in the term-level/type-level namespace, when using a single/double tick, respectively. Fixes #20884. - - - - - 1de94daa by George Thomas at 2022-01-04T19:56:51-05:00 Fix Haddock parse error in GHC.Exts.Heap.FFIClosures.hs - - - - - e59bd46a by nineonine at 2022-01-05T18:07:18+00:00 Add regression test (#13997) - - - - - c080b443 by Sylvain Henry at 2022-01-06T02:24:54-05:00 Perf: use SmallArray for primops' Ids cache (#20857) SmallArray doesn't perform bounds check (faster). Make primop tags start at 0 to avoid index arithmetic. - - - - - ec26c38b by Sylvain Henry at 2022-01-06T02:24:54-05:00 Use primOpIds cache more often (#20857) Use primOpId instead of mkPrimOpId in a few places to benefit from Id caching. I had to mess a little bit with the module hierarchy to fix cycles and to avoid adding too many new dependencies to count-deps tests. - - - - - f7fc62e2 by Greg Steuck at 2022-01-06T07:56:22-05:00 Disable T2615 on OpenBSD, close #20869 - - - - - 978ea35e by Greg Steuck at 2022-01-06T07:57:00-05:00 Change ulimit -n in openFile008 back to 1024 The test only wants 1000 descriptors, so changing the limit to double that *in the context of just this test* makes no sense. This is a manual revert of 8f7194fae23bdc6db72fc5784933f50310ce51f9. The justification given in the description doesn't instill confidence. As of HEAD, the test fails on OpenBSD where ulimit -n is hard-limited to 1024. The test suite attempts to change it to 2048, which fails. The test proceeds with the unchanged default of 512 and naturally the test program fails due to the low ulimit. The fixed test now passes. - - - - - 7b783c9d by Matthew Pickering at 2022-01-07T18:25:06-05:00 Thoughtful forcing in CoreUnfolding We noticed that the structure of CoreUnfolding could leave double the amount of CoreExprs which were retained in the situation where the template but not all the predicates were forced. This observation was then confirmed using ghc-debug: ``` (["ghc:GHC.Core:App","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 237) (["ghc:GHC.Core:App","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 1) (["ghc:GHC.Core:Case","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 12) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","BLACKHOLE"],Count 1) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 78) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","ghc-prim:GHC.Types:False","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","THUNK_1_0","THUNK_1_0"],Count 3) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","BLACKHOLE"],Count 31) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 4307) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 6) (["ghc:GHC.Core:Let","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 29) (["ghc:GHC.Core:Lit","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 1) (["ghc:GHC.Core:Tick","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 36) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","THUNK_1_0","THUNK_1_0"],Count 6) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","ghc-prim:GHC.Types:True","THUNK_1_0"],Count 2) ``` Where we can see that the first argument is forced but there are still thunks remaining which retain the old expr. For my test case (a very big module, peak of 3 000 000 core terms) this reduced peak memory usage by 1G (12G -> 11G). Fixes #20905 - - - - - f583eb8e by Joachim Breitner at 2022-01-07T18:25:41-05:00 Remove dangling references to Note [Type-checking overloaded labels] that note was removed in 4196969c53c55191e644d9eb258c14c2bc8467da - - - - - 2b6c2179 by Matthew Pickering at 2022-01-11T19:37:45-05:00 hadrian: Add bootstrap scripts for building without cabal-install These scripts are originally from the cabal-install repo with a few small tweaks. This utility allows you to build hadrian without cabal-install, which can be useful for packagers. If you are a developer then build hadrian using cabal-install. If you want to bootstrap with ghc-8.10.5 then run the ./bootstrap script with the `plan-bootstrap-8.10.5.json` file. bootstrap.py -d plan-bootstrap-8.10.5.json -w /path/to-ghc The result of the bootstrap script will be a hadrian binary in `_build/bin/hadrian`. There is a script (using nix) which can be used to generate the bootstrap plans for the range of supported GHC versions using nix. generate_bootstrap_plans Otherwise you can run the commands in ./generate_bootstrap_plans directly. Fixes #17103 - - - - - a8fb4251 by Zubin Duggal at 2022-01-11T19:37:45-05:00 hadrian: allow offline bootstrapping This patch adds the ability to fetch and store dependencies needed for boostrapping hadrian. By default the script will download the dependencies from the network but some package managers disallow network access so there are also options to build given a supplied tarball. The -s option allos you to provide the tarball bootstrap.py -d plan-bootstrap-8.10.5.json -w /path/to-ghc -s sources-tarball.tar.gz Which dependencies you need can be queried using the `list-sources` option. bootstrap.py list-sources -d plan-bootstrap-8.10.5.json This produces `fetch_plan.json` which tells you where to get each source from. You can instruct the script to create the tarball using the `fetch` option. bootstrap.py fetch -d plan-bootstrap-8.10.5.json -o sources-tarball.tar.gz Together these commands mean you can build GHC without needing cabal-install. Fixes #17103 - - - - - 02cf4bc6 by Zubin Duggal at 2022-01-11T19:37:45-05:00 hadrian: Fully implement source distributions (#19317) We use `git ls-files` to get the list of files to include in the source distribution. Also implements the `-testsuite` and `-extra-tarballs` distributions. - - - - - 85473a09 by Zubin Duggal at 2022-01-11T19:37:45-05:00 ci: test bootstrapping and use hadrian for source dists - - - - - 759f3421 by Matthew Pickering at 2022-01-11T19:38:21-05:00 ci: Nightly, run one head.hackage job with core-lint and one without This fixes serious skew in the performance numbers because the packages were build with core-lint. Fixes #20826 - - - - - 6737c8e1 by Ben Gamari at 2022-01-11T19:38:56-05:00 rts: Depend explicitly on libc As noted in #19029, currently `ghc-prim` explicitly lists `libc` in `extra-libraries`, resulting in incorrect link ordering with the `extra-libraries: pthread` in `libHSrts`. Fix this by adding an explicit dependency on `libc` to `libHSrts`. Closes #19029. - - - - - 247cd336 by Ben Gamari at 2022-01-11T19:39:32-05:00 rts: Only declare environ when necessary Previously we would unconditionally provide a declaration for `environ`, even if `<unistd.h>` already provided one. This would result in `-Werror` builds failing on some platforms. Also `#include <unistd.h>` to ensure that the declaration is visible. Fixes #20861. - - - - - b65e7274 by Greg Steuck at 2022-01-11T19:40:10-05:00 Skip T18623 on OpenBSD The bug it regresses didn't happen on this OS (no RLIMIT_AS) and the regression doesn't work (ulimit: -v: unknown option) - - - - - c6300cb3 by Greg Steuck at 2022-01-11T19:40:50-05:00 Skip T16180 on OpenBSD due to bug #14012 - - - - - addf8e54 by sheaf at 2022-01-11T19:41:28-05:00 Kind TyCons: require KindSignatures, not DataKinds Uses of a TyCon in a kind signature required users to enable DataKinds, which didn't make much sense, e.g. in type U = Type type MyMaybe (a :: U) = MyNothing | MyJust a Now the DataKinds error is restricted to data constructors; the use of kind-level type constructors is instead gated behind -XKindSignatures. This patch also adds a convenience pattern synonym for patching on both a TyCon or a TcTyCon stored in a TcTyThing, used in tcTyVar and tc_infer_id. fixes #20873 - - - - - 34d8bc24 by sheaf at 2022-01-11T19:42:07-05:00 Fix parsing & printing of unboxed sums The pretty-printing of partially applied unboxed sums was incorrect, as we incorrectly dropped the first half of the arguments, even for a partial application such as (# | #) @IntRep @DoubleRep Int# which lead to the nonsensical (# DoubleRep | Int# #). This patch also allows users to write unboxed sum type constructors such as (# | #) :: TYPE r1 -> TYPE r2 -> TYPE (SumRep '[r1,r2]). Fixes #20858 and #20859. - - - - - 49731fed by sheaf at 2022-01-11T19:42:46-05:00 TcPlugins: `newWanted` uses the provided `CtLoc` The `GHC.Tc.Plugin.newWanted` function takes a `CtLoc` as an argument, but it used to discard the location information, keeping only the `CtOrigin`. It would then retrieve the source location from the `TcM` environment using `getCtLocM`. This patch changes this so that `GHC.Tc.Plugin.newWanted` passes on the full `CtLoc`. This means that authors of type-checking plugins no longer need to manually set the `CtLoc` environment in the `TcM` monad if they want to create a new Wanted constraint with the given `CtLoc` (in particular, for setting the `SrcSpan` of an emitted constraint). This makes the `newWanted` function consistent with `newGiven`, which always used the full `CtLoc` instead of using the environment. Fixes #20895 - - - - - 23d215fc by Krzysztof Gogolewski at 2022-01-11T19:43:22-05:00 warnPprTrace: pass separately the reason This makes it more similar to pprTrace, pprPanic etc. - - - - - 833216a3 by Matthew Pickering at 2022-01-11T19:43:57-05:00 Use interactive flags when printing expressions in GHCi The documentation states that the interactive flags should be use for any interactive expressions. The interactive flags are used when typechecking these expressions but not when printing. The session flags (modified by :set) are only used when loading a module. Fixes #20909 - - - - - 19b13698 by Matthew Pickering at 2022-01-11T19:43:57-05:00 Enable :seti in a multi component repl Part of #20889 - - - - - 7ca43a3f by Matthew Pickering at 2022-01-11T19:44:33-05:00 Change assertions in Stats.c to warnings (and introduce WARN macro) ASSERT should be used in situations where something very bad will happen later on if a certain invariant doesn't hold. The idea is that IF we catch the assertion earlier then it will be easier to work out what's going on at that point rather than at some indeterminate point in the future of the program. The assertions in Stats.c do not obey this philsophy and it is quite annoying if you are running a debug build (or a ticky compiler) and one of these assertions fails right at the end of your program, before the ticky report is printed out so you don't get any profiling information. Given that nothing terrible happens if these assertions are not true, or at least the terrible thing will happen in very close proximity to the assertion failure, these assertions use the new WARN macro which prints the assertion failure to stdout but does not exit the program. Of course, it would be better to fix these metrics to not trigger the assertion in the first place but if they did fail again in the future it is frustrating to be bamboozled in this manner. Fixes #20899 - - - - - e505dbd3 by Greg Steuck at 2022-01-11T19:45:11-05:00 Remove from error the parenthesized amount of memory requested Diagnostics for outofmem test on OpenBSD includes the amount of memory that it failed to allocate. This seems like an irrelevant detail that could change over time and isn't required for determining if test passed. Typical elided text is '(requested 2148532224 bytes)' - - - - - 7911aaa9 by Greg Steuck at 2022-01-11T19:45:50-05:00 Feed /dev/null into cgrun025 The test currently times out waiting for end of stdin in getContents. The expected output indicates that nothing should come for the test to pass as written. It is unclear how the test was supposed to pass, but this looks like a sufficient hack to make it work. - - - - - ed39d15c by Greg Steuck at 2022-01-11T19:46:28-05:00 Disable keep-cafs{,-fail} tests on OpenBSD They are likely broken for the same reason as FreeBSD where the tests are already disabled. - - - - - 35bea01b by Peter Trommler at 2022-01-11T19:47:04-05:00 RTS: Remove unused file xxhash.c - - - - - c2099059 by Matthew Pickering at 2022-01-11T19:47:39-05:00 RTTI: Substitute the [rk] skolems into kinds (Fixes #10616 and #10617) Co-authored-by: Roland Senn <rsx at bluewin.ch> - - - - - 92f3e6e4 by Matthew Pickering at 2022-01-11T19:48:15-05:00 docs: MonadComprehension desugar using Alternative rather than MonadPlus Fixes #20928 - - - - - 7b0c9384 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Abstract BangOpts Avoid requiring to pass DynFlags to mkDataConRep/buildDataCon. When we load an interface file, these functions don't use the flags. This is preliminary work to decouple the loader from the type-checker for #14335. - - - - - a31ace56 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Untangled GHC.Types.Id.Make from the driver - - - - - 81a8f7a7 by Zubin Duggal at 2022-01-12T23:26:24-05:00 testsuite: Fix import on python 3.10 - - - - - 66831b94 by Ben Gamari at 2022-01-13T14:50:13-05:00 hadrian: Include bash completion script in bindist See #20802. - - - - - be33d61a by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to CPR analysis - - - - - c2a6c3eb by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to Demand analysis - - - - - 9ccc445a by Eric Lindblad at 2022-01-14T10:35:46-05:00 add NUMJOBS - - - - - 564b89ae by Eric Lindblad at 2022-01-14T10:35:46-05:00 Revert "add NUMJOBS" This reverts commit c0b854e929f82c680530e944e12fad24f9e14f8e - - - - - 2dfc268c by Eric Lindblad at 2022-01-14T10:35:46-05:00 update URLs - - - - - 1aace894 by Eric Lindblad at 2022-01-14T10:35:46-05:00 reinsert target - - - - - 52a4f5ab by Andreas Klebinger at 2022-01-14T10:36:21-05:00 Add test for #20938. - - - - - e2b60be8 by Ben Gamari at 2022-01-15T03:41:16-05:00 rts: Consolidate RtsSymbols from libc Previously (9ebda74ec5331911881d734b21fbb31c00a0a22f) `environ` was added to `RtsSymbols` to ensure that environment was correctly propagated when statically linking. However, this introduced #20577 since platforms are inconsistent in whether they provide a prototype for `environ`. I fixed this by providing a prototype but while doing so dropped symbol-table entry, presumably thinking that it was redundant due to the entry in the mingw-specific table. Here I reintroduce the symbol table entry for `environ` and move libc symbols shared by Windows and Linux into a new macro, `RTS_LIBC_SYMBOLS`, avoiding this potential confusion. - - - - - 0dc72395 by Tamar Christina at 2022-01-15T03:41:55-05:00 winio: fix heap corruption and various leaks. - - - - - 4031ef62 by Eric Lindblad at 2022-01-15T20:11:55+00:00 wikipedia link - - - - - a13aff98 by Eric Lindblad at 2022-01-17T08:25:51-05:00 ms link - - - - - f161e890 by sheaf at 2022-01-17T14:52:50+00:00 Use diagnostic infrastructure in GHC.Tc.Errors - - - - - 18c797b8 by Jens Petersen at 2022-01-18T16:12:14-05:00 hadrian BinaryDist: version ghc in ghciScriptWrapper like we do for the non-Hadrian wrapper script. Otherwise if $bindir/ghc is a different ghc version then versioned ghci will incorrectly run the other ghc version instead. (Normally this would only happen if there are parallel ghc versions installed in bindir.) All the other wrapper scripts already have versioned executablename - - - - - 310424d0 by Matthew Pickering at 2022-01-18T16:12:50-05:00 Correct type of static forms in hsExprType The simplest way to do this seemed to be to persist the whole type in the extension field from the typechecker so that the few relevant places * Desugaring can work out the return type by splitting this type rather than calling `dsExpr` (slightly more efficient). * hsExprType can just return the correct type. * Zonking has to now zonk the type as well The other option we considered was wiring in StaticPtr but that is actually quite tricky because StaticPtr refers to StaticPtrInfo which has field selectors (which we can't easily wire in). Fixes #20150 - - - - - 7ec783de by Matthew Pickering at 2022-01-18T16:12:50-05:00 Add test for using type families with static pointers Issue was reported on #13306 - - - - - 2d205154 by Sebastian Graf at 2022-01-18T16:13:25-05:00 Stricten the Strict State monad I found it weird that most of the combinators weren't actually strict. Making `pure` strict in the state should hopefully give Nested CPR an easier time to unbox the nested state. - - - - - 5a6efd21 by Ben Gamari at 2022-01-18T16:14:01-05:00 rts/winio: Fix #18382 Here we refactor WinIO's IO completion scheme, squashing a memory leak and fixing #18382. To fix #18382 we drop the special thread status introduced for IoPort blocking, BlockedOnIoCompletion, as well as drop the non-threaded RTS's special dead-lock detection logic (which is redundant to the GC's deadlock detection logic), as proposed in #20947. Previously WinIO relied on foreign import ccall "wrapper" to create an adjustor thunk which can be attached to the OVERLAPPED structure passed to the operating system. It would then use foreign import ccall "dynamic" to back out the original continuation from the adjustor. This roundtrip is significantly more expensive than the alternative, using a StablePtr. Furthermore, the implementation let the adjustor leak, meaning that every IO request would leak a page of memory. Fixes T18382. - - - - - 01254ceb by Matthew Pickering at 2022-01-18T16:14:37-05:00 Add note about heap invariant Closed #20904 - - - - - 21510698 by Sergey Vinokurov at 2022-01-18T16:15:12-05:00 Improve detection of lld linker Newer lld versions may include vendor info in --version output and thus the version string may not start with ‘LLD’. Fixes #20907 - - - - - 95e7964b by Peter Trommler at 2022-01-18T20:46:08-05:00 Fix T20638 on big-endian architectures The test reads a 16 bit value from an array of 8 bit values. Naturally, that leads to different values read on big-endian architectures than on little-endian. In this case the value read is 0x8081 on big-endian and 0x8180 on little endian. This patch changes the argument of the `and` machop to mask bit 7 which is the only bit different. The test still checks that bit 15 is zero, which was the original issue in #20638. Fixes #20906. - - - - - fd0019a0 by Eric Lindblad at 2022-01-18T20:46:48-05:00 ms and gh links - - - - - 85dc61ee by Zubin Duggal at 2022-01-18T20:47:23-05:00 ci: Fix subtlety with not taking effect because of time_it (#20898) - - - - - 592e4113 by Anselm Schüler at 2022-01-19T13:31:49-05:00 Note that ImpredicativeTypes doesn’t allow polymorphic instances See #20939 - - - - - 3b009e1a by Ben Gamari at 2022-01-19T13:32:25-05:00 base: Add CTYPE pragmas to all foreign types Fixes #15531 by ensuring that we know the corresponding C type for all marshalling wrappers. Closes #15531. - - - - - 516eeb9e by Robert Hensing at 2022-01-24T21:28:24-05:00 Add -fcompact-unwind This gives users the choice to enable __compact_unwind sections when linking. These were previously hardcoded to be removed. This can be used to solved the problem "C++ does not catch exceptions when used with Haskell-main and linked by ghc", https://gitlab.haskell.org/ghc/ghc/-/issues/11829 It does not change the default behavior, because I can not estimate the impact this would have. When Apple first introduced the compact unwind ABI, a number of open source projects have taken the easy route of disabling it, avoiding errors or even just warnings shortly after its introduction. Since then, about a decade has passed, so it seems quite possible that Apple itself, and presumably many programs with it, have successfully switched to the new format, to the point where the old __eh_frame section support is in disrepair. Perhaps we should get along with the program, but for now we can test the waters with this flag, and use it to fix packages that need it. - - - - - 5262b1e5 by Robert Hensing at 2022-01-24T21:28:24-05:00 Add test case for C++ exception handling - - - - - a5c94092 by Sebastian Graf at 2022-01-24T21:29:00-05:00 Write Note [Strict State monad] to explain what G.U.M.State.Strict does As requested by Simon after review of !7342. I also took liberty to define the `Functor` instance by hand, as the derived one subverts the invariants maintained by the pattern synonym (as already stated in `Note [The one-shot state monad trick]`). - - - - - 9b0d56d3 by Eric Lindblad at 2022-01-24T21:29:38-05:00 links - - - - - 4eac8e72 by Ben Gamari at 2022-01-24T21:30:13-05:00 ghc-heap: Drop mention of BlockedOnIOCompletion Fixes bootstrap with GHC 9.0 after 5a6efd218734dbb5c1350531680cd3f4177690f1 - - - - - 7d7b9a01 by Ryan Scott at 2022-01-24T21:30:49-05:00 Hadrian: update the index-state to allow building with GHC 9.0.2 Fixes #20984. - - - - - aa50e118 by Peter Trommler at 2022-01-24T21:31:25-05:00 testsuite: Mark test that require RTS linker - - - - - 871ce2a3 by Matthew Pickering at 2022-01-25T17:27:30-05:00 ci: Move (most) deb9 jobs to deb10 deb9 is now end-of-life so we are dropping support for producing bindists. - - - - - 9d478d51 by Ryan Scott at 2022-01-25T17:28:06-05:00 DeriveGeneric: look up datacon fixities using getDataConFixityFun Previously, `DeriveGeneric` would look up the fixity of a data constructor using `getFixityEnv`, but this is subtly incorrect for data constructors defined in external modules. This sort of situation can happen with `StandaloneDeriving`, as noticed in #20994. In fact, the same bug has occurred in the past in #9830, and while that bug was fixed for `deriving Read` and `deriving Show`, the fix was never extended to `DeriveGeneric` due to an oversight. This patch corrects that oversight. Fixes #20994. - - - - - 112e9e9e by Zubin Duggal at 2022-01-25T17:28:41-05:00 Fix Werror on alpine - - - - - 781323a3 by Matthew Pickering at 2022-01-25T17:29:17-05:00 Widen T12545 acceptance window This test has been the scourge of contributors for a long time. It has caused many failed CI runs and wasted hours debugging a test which barely does anything. The fact is does nothing is the reason for the flakiness and it's very sensitive to small changes in initialisation costs, in particular adding wired-in things can cause this test to fluctuate quite a bit. Therefore we admit defeat and just bump the threshold up to 10% to catch very large regressions but otherwise don't care what this test does. Fixes #19414 - - - - - e471a680 by sheaf at 2022-01-26T12:01:45-05:00 Levity-polymorphic arrays and mutable variables This patch makes the following types levity-polymorphic in their last argument: - Array# a, SmallArray# a, Weak# b, StablePtr# a, StableName# a - MutableArray# s a, SmallMutableArray# s a, MutVar# s a, TVar# s a, MVar# s a, IOPort# s a The corresponding primops are also made levity-polymorphic, e.g. `newArray#`, `readArray#`, `writeMutVar#`, `writeIOPort#`, etc. Additionally, exception handling functions such as `catch#`, `raise#`, `maskAsyncExceptions#`,... are made levity/representation-polymorphic. Now that Array# and MutableArray# also work with unlifted types, we can simply re-define ArrayArray# and MutableArrayArray# in terms of them. This means that ArrayArray# and MutableArrayArray# are no longer primitive types, but simply unlifted newtypes around Array# and MutableArrayArray#. This completes the implementation of the Pointer Rep proposal https://github.com/ghc-proposals/ghc-proposals/pull/203 Fixes #20911 ------------------------- Metric Increase: T12545 ------------------------- ------------------------- Metric Decrease: T12545 ------------------------- - - - - - 6e94ba54 by Andreas Klebinger at 2022-01-26T12:02:21-05:00 CorePrep: Don't try to wrap partial applications of primops in profiling ticks. This fixes #20938. - - - - - b55d7db3 by sheaf at 2022-01-26T12:03:01-05:00 Ensure that order of instances doesn't matter The insert_overlapping used in lookupInstEnv used to return different results depending on the order in which instances were processed. The problem was that we could end up discarding an overlapping instance in favour of a more specific non-overlapping instance. This is a problem because, even though we won't choose the less-specific instance for matching, it is still useful for pruning away other instances, because it has the overlapping flag set while the new instance doesn't. In insert_overlapping, we now keep a list of "guard" instances, which are instances which are less-specific that one that matches (and hence which we will discard in the end), but want to keep around solely for the purpose of eliminating other instances. Fixes #20946 - - - - - 61f62062 by sheaf at 2022-01-26T12:03:40-05:00 Remove redundant SOURCE import in FitTypes Fixes #20995 - - - - - e8405829 by sheaf at 2022-01-26T12:04:15-05:00 Fix haddock markup in GHC.Tc.Errors.Types - - - - - 590a2918 by Simon Peyton Jones at 2022-01-26T19:45:22-05:00 Make RULE matching insensitive to eta-expansion This patch fixes #19790 by making the rule matcher do on-the-fly eta reduction. See Note [Eta reduction the target] in GHC.Core.Rules I found I also had to careful about casts when matching; see Note [Casts in the target] and Note [Casts in the template] Lots more comments and Notes in the rule matcher - - - - - c61ac4d8 by Matthew Pickering at 2022-01-26T19:45:58-05:00 alwaysRerun generation of ghcconfig This file needs to match exactly what is passed as the testCompiler. Before this change the settings for the first compiler to be tested woudl be stored and not regenerated if --test-compiler changed. - - - - - b5132f86 by Matthew Pickering at 2022-01-26T19:45:58-05:00 Pass config.stage argument to testsuite - - - - - 83d3ad31 by Zubin Duggal at 2022-01-26T19:45:58-05:00 hadrian: Allow testing of the stage1 compiler (#20755) - - - - - a5924b38 by Joachim Breitner at 2022-01-26T19:46:34-05:00 Simplifier: Do the right thing if doFloatFromRhs = False If `doFloatFromRhs` is `False` then the result from `prepareBinding` should not be used. Previously it was in ways that are silly (but not completly wrong, as the simplifier would clean that up again, so no test case). This was spotted by Simon during a phone call. Fixes #20976 - - - - - ce488c2b by Simon Peyton Jones at 2022-01-26T19:47:09-05:00 Better occurrence analysis with casts This patch addresses #20988 by refactoring the way the occurrence analyser deals with lambdas. Previously it used collectBinders to split off a group of binders, and deal with them together. Now I deal with them one at a time in occAnalLam, which allows me to skip casts easily. See Note [Occurrence analysis for lambda binders] about "lambda-groups" This avoidance of splitting out a list of binders has some good consequences. Less code, more efficient, and I think, more clear. The Simplifier needed a similar change, now that lambda-groups can inlude casts. It turned out that I could simplify the code here too, in particular elminating the sm_bndrs field of StrictBind. Simpler, more efficient. Compile-time metrics improve slightly; here are the ones that are +/- 0.5% or greater: Baseline Test Metric value New value Change -------------------------------------------------------------------- T11303b(normal) ghc/alloc 40,736,702 40,543,992 -0.5% T12425(optasm) ghc/alloc 90,443,459 90,034,104 -0.5% T14683(normal) ghc/alloc 2,991,496,696 2,956,277,288 -1.2% T16875(normal) ghc/alloc 34,937,866 34,739,328 -0.6% T17977b(normal) ghc/alloc 37,908,550 37,709,096 -0.5% T20261(normal) ghc/alloc 621,154,237 618,312,480 -0.5% T3064(normal) ghc/alloc 190,832,320 189,952,312 -0.5% T3294(normal) ghc/alloc 1,604,674,178 1,604,608,264 -0.0% T5321FD(normal) ghc/alloc 270,540,489 251,888,480 -6.9% GOOD T5321Fun(normal) ghc/alloc 300,707,814 281,856,200 -6.3% GOOD WWRec(normal) ghc/alloc 588,460,916 585,536,400 -0.5% geo. mean -0.3% Metric Decrease: T5321FD T5321Fun - - - - - 4007905d by Roland Senn at 2022-01-26T19:47:47-05:00 Cleanup tests in directory ghci.debugger. Fixes #21009 * Remove wrong comment about panic in `break003.script`. * Improve test `break008`. * Add test `break028` to `all.T` * Fix wrong comments in `print019.script`, `print026.script` and `result001.script`. * Remove wrong comments from `print024.script` and `print031.script`. * Replace old module name with current name in `print035.script`. - - - - - 3577defb by Matthew Pickering at 2022-01-26T19:48:22-05:00 ci: Move source-tarball and test-bootstrap into full-build - - - - - 6e09b3cf by Matthew Pickering at 2022-01-27T02:39:35-05:00 ci: Add ENABLE_NUMA flag to explicitly turn on libnuma dependency In recent releases a libnuma dependency has snuck into our bindists because the images have started to contain libnuma. We now explicitly pass `--disable-numa` to configure unless explicitly told not to by using the `ENABLE_NUMA` environment variable. So this is tested, there is one random validate job which builds with --enable-numa so that the code in the RTS is still built. Fixes #20957 and #15444 - - - - - f4ce4186 by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Improve partial signatures As #20921 showed, with partial signatures, it is helpful to use the same algorithm (namely findInferredDiff) for * picking the constraints to retain for the /group/ in Solver.decideQuantification * picking the contraints to retain for the /individual function/ in Bind.chooseInferredQuantifiers This is still regrettably declicate, but it's a step forward. - - - - - 0573aeab by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Add an Outputable instance for RecTcChecker - - - - - f0adea14 by Ryan Scott at 2022-01-27T02:40:47-05:00 Expand type synonyms in markNominal `markNominal` is repsonsible for setting the roles of type variables that appear underneath an `AppTy` to be nominal. However, `markNominal` previously did not expand type synonyms, so in a data type like this: ```hs data M f a = MkM (f (T a)) type T a = Int ``` The `a` in `M f a` would be marked nominal, even though `T a` would simply expand to `Int`. The fix is simple: call `coreView` as appropriate in `markNominal`. This is much like the fix for #14101, but in a different spot. Fixes #20999. - - - - - 18df4013 by Simon Peyton Jones at 2022-01-27T08:22:30-05:00 Define and use restoreLclEnv This fixes #20981. See Note [restoreLclEnv vs setLclEnv] in GHC.Tc.Utils.Monad. I also use updLclEnv rather than get/set when I can, because it's then much clearer that it's an update rather than an entirely new TcLclEnv coming from who-knows-where. - - - - - 31088dd3 by David Feuer at 2022-01-27T08:23:05-05:00 Add test supplied in T20996 which uses data family result kind polymorphism David (@treeowl) writes: > Following @kcsongor, I've used ridiculous data family result kind > polymorphism in `linear-generics`, and am currently working on getting > it into `staged-gg`. If it should be removed, I'd appreciate a heads up, > and I imagine Csongor would too. > > What do I need by ridiculous polymorphic result kinds? Currently, data > families are allowed to have result kinds that end in `Type` (or maybe > `TYPE r`? I'm not sure), but not in concrete data kinds. However, they > *are* allowed to have polymorphic result kinds. This leads to things I > think most of us find at least quite *weird*. For example, I can write > > ```haskell > data family Silly :: k > data SBool :: Bool -> Type where > SFalse :: SBool False > STrue :: SBool True > SSSilly :: SBool Silly > type KnownBool b where > kb :: SBool b > instance KnownBool False where kb = SFalse > instance KnownBool True where kb = STrue > instance KnownBool Silly where kb = Silly > ``` > > Basically, every kind now has potentially infinitely many "legit" inhabitants. > > As horrible as that is, it's rather useful for GHC's current native > generics system. It's possible to use these absurdly polymorphic result > kinds to probe the structure of generic representations in a relatively > pleasant manner. It's a sort of "formal type application" reminiscent of > the notion of a formal power series (see the test case below). I suspect > a system more like `kind-generics` wouldn't need this extra probing > power, but nothing like that is natively available as yet. > > If the ridiculous result kind polymorphism is banished, we'll still be > able to do what we need as long as we have stuck type families. It's > just rather less ergonomical: a stuck type family has to be used with a > concrete marker type argument. Closes #20996 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 8fd2ac25 by Andreas Abel at 2022-01-27T18:34:54-05:00 Whitespace only - - - - - 7a854743 by Andreas Abel at 2022-01-27T18:34:54-05:00 Ctd. #18087: complete :since: info for all warnings in users guide Some warnings have been there "forever" and I could not trace back the exact genesis, so I wrote "since at least 5.04". The flag `helpful-errors` could have been added in 7.2 already. I wrote 7.4 since I have no 7.2 available and it is not recognized by 7.0. - - - - - f75411e8 by Andreas Abel at 2022-01-27T18:34:54-05:00 Re #18087 user's guide: add a note that -Wxxx used to be -fwarn-xxx The warning option syntax -W was introduced in GHC 8. The note should clarify what e.g. "since 7.6" means in connection with "-Wxxx": That "-fwarn-xxx" was introduced in 7.6.1. [ci skip] - - - - - 3cae7fde by Peter Trommler at 2022-01-27T18:35:30-05:00 testsuite: Fix AtomicPrimops test on big endian - - - - - 6cc6080c by Ben Gamari at 2022-01-27T18:36:05-05:00 users-guide: Document GHC_CHARENC environment variable As noted in #20963, this was introduced in 1b56c40578374a15b4a2593895710c68b0e2a717 but was no documentation was added at that point. Closes #20963. - - - - - ee21e2de by Ben Gamari at 2022-01-27T18:36:41-05:00 rts: Clean up RTS flags usage message Align flag descriptions and acknowledge that some flags may not be available unless the user linked with `-rtsopts` (as noted in #20961). Fixes #20961. - - - - - 7f8ce19e by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Fix getHasGivenEqs The second component is supposed to be "insoluble equalities arising from givens". But we were getting wanteds too; and that led to an outright duplication of constraints. It's not harmful, but it's not right either. I came across this when debugging something else. Easily fixed. - - - - - f9ef2d26 by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Set the TcLclEnv when solving a ForAll constraint Fix a simple omission in GHC.Tc.Solver.Canonical.solveForAll, where we ended up with the wrong TcLclEnv captured in an implication. Result: unhelpful error message (#21006) - - - - - bc6ba8ef by Sylvain Henry at 2022-01-28T12:14:41-05:00 Make most shifts branchless - - - - - 62a6d037 by Simon Peyton Jones at 2022-01-28T12:15:17-05:00 Improve boxity in deferAfterPreciseException As #20746 showed, the demand analyser behaved badly in a key I/O library (`GHC.IO.Handle.Text`), by unnessarily boxing and reboxing. This patch adjusts the subtle function deferAfterPreciseException; it's quite easy, just a bit subtle. See the new Note [deferAfterPreciseException] And this MR deals only with Problem 2 in #20746. Problem 1 is still open. - - - - - 42c47cd6 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/trace: Shrink tracing flags - - - - - cee66e71 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/EventLog: Mark various internal globals as static - - - - - 6b0cea29 by Ben Gamari at 2022-01-29T02:40:45-05:00 Propagate PythonCmd to make build system - - - - - 2e29edb7 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts: Refactor event types Previously we would build the eventTypes array at runtime during RTS initialization. However, this is completely unnecessary; it is completely static data. - - - - - bb15c347 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/eventlog: Ensure that flushCount is initialized - - - - - 268efcc9 by Matthew Pickering at 2022-01-29T02:41:21-05:00 Rework the handling of SkolemInfo The main purpose of this patch is to attach a SkolemInfo directly to each SkolemTv. This fixes the large number of bugs which have accumulated over the years where we failed to report errors due to having "no skolem info" for particular type variables. Now the origin of each type varible is stored on the type variable we can always report accurately where it cames from. Fixes #20969 #20732 #20680 #19482 #20232 #19752 #10946 #19760 #20063 #13499 #14040 The main changes of this patch are: * SkolemTv now contains a SkolemInfo field which tells us how the SkolemTv was created. Used when reporting errors. * Enforce invariants relating the SkolemInfoAnon and level of an implication (ic_info, ic_tclvl) to the SkolemInfo and level of the type variables in ic_skols. * All ic_skols are TcTyVars -- Check is currently disabled * All ic_skols are SkolemTv * The tv_lvl of the ic_skols agrees with the ic_tclvl * The ic_info agrees with the SkolInfo of the implication. These invariants are checked by a debug compiler by checkImplicationInvariants. * Completely refactor kcCheckDeclHeader_sig which kept doing my head in. Plus, it wasn't right because it wasn't skolemising the binders as it decomposed the kind signature. The new story is described in Note [kcCheckDeclHeader_sig]. The code is considerably shorter than before (roughly 240 lines turns into 150 lines). It still has the same awkward complexity around computing arity as before, but that is a language design issue. See Note [Arity inference in kcCheckDeclHeader_sig] * I added new type synonyms MonoTcTyCon and PolyTcTyCon, and used them to be clear which TcTyCons have "finished" kinds etc, and which are monomorphic. See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] * I renamed etaExpandAlgTyCon to splitTyConKind, becuase that's a better name, and it is very useful in kcCheckDeclHeader_sig, where eta-expansion isn't an issue. * Kill off the nasty `ClassScopedTvEnv` entirely. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 0a1d0944 by Ben Gamari at 2022-01-29T14:52:55-05:00 Drop SPARC NCG - - - - - 313afb3d by Ben Gamari at 2022-01-29T14:52:56-05:00 A few comment cleanups - - - - - d85a527f by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out SPARC register support - - - - - c6bede69 by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Rip out SPARC support - - - - - a67c2471 by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out remaining SPARC support - - - - - 5771b690 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop RegPair SPARC was its last and only user. - - - - - 512ed3f1 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Make RealReg a newtype Now that RegPair is gone we no longer need to pay for the additional box. - - - - - 88fea6aa by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Drop redundant #include <Arena.h> - - - - - ea2a4034 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop ncgExpandTop This was only needed for SPARC's synthetic instructions. - - - - - 88fce740 by Ben Gamari at 2022-01-29T14:54:04-05:00 rel-notes: Note dropping of SPARC support - - - - - eb956cf1 by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Force-enable caret diagnostics in T17786 Otherwise GHC realizes that it's not attached to a proper tty and will disable caret diagnostics. - - - - - d07799ab by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Make T7275 more robust against CCid changes The cost-center numbers are somewhat unstable; normalise them out. - - - - - c76c8050 by Ben Gamari at 2022-01-30T06:27:19-05:00 rts: Don't allocate closurePtrs# pointers on C stack Previously `closurePtrs#` would allocate an aray of the size of the closure being decoded on the C stack. This was ripe for overflowing the C stack overflow. This resulted in `T12492` failing on Windows. - - - - - 3af95f7a by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite/T4029: Don't depend on echo On Windows the `cmd.exe` shell may be used to execute the command, which will print `ECHO is on.` instead of a newline if you give it no argument. Avoid this by rather using `printf`. - - - - - 3531c478 by Ben Gamari at 2022-01-30T06:27:19-05:00 Use PATH_FMT instead of %s to format `pathchar *` A few %s occurrences have snuck in over the past months. - - - - - ee5c4f9d by Zubin Duggal at 2022-01-31T16:51:55+05:30 Improve migration strategy for the XDG compliance change to the GHC application directory. We want to always use the old path (~/.ghc/..) if it exists. But we never want to create the old path. This ensures that the migration can eventually be completed once older GHC versions are no longer in circulation. Fixes #20684, #20669, #20660 - - - - - 60a54a8f by doyougnu at 2022-01-31T18:46:11-05:00 StgToCmm: decouple DynFlags, add StgToCmmConfig StgToCmm: add Config, remove CgInfoDownwards StgToCmm: runC api change to take StgToCmmConfig StgToCmm: CgInfoDownad -> StgToCmmConfig StgToCmm.Monad: update getters/setters/withers StgToCmm: remove CallOpts in StgToCmm.Closure StgToCmm: remove dynflag references StgToCmm: PtrOpts removed StgToCmm: add TMap to config, Prof - dynflags StgToCmm: add omit yields to config StgToCmm.ExtCode: remove redundant import StgToCmm.Heap: remove references to dynflags StgToCmm: codeGen api change, DynFlags -> Config StgToCmm: remove dynflags in Env and StgToCmm StgToCmm.DataCon: remove dynflags references StgToCmm: remove dynflag references in DataCon StgToCmm: add backend avx flags to config StgToCmm.Prim: remove dynflag references StgToCmm.Expr: remove dynflag references StgToCmm.Bind: remove references to dynflags StgToCmm: move DoAlignSanitisation to Cmm.Type StgToCmm: remove PtrOpts in Cmm.Parser.y DynFlags: update ipInitCode api StgToCmm: Config Module is single source of truth StgToCmm: Lazy config breaks IORef deadlock testsuite: bump countdeps threshold StgToCmm.Config: strictify fields except UpdFrame Strictifying UpdFrameOffset causes the RTS build with stage1 to deadlock. Additionally, before the deadlock performance of the RTS is noticeably slower. StgToCmm.Config: add field descriptions StgToCmm: revert strictify on Module in config testsuite: update CountDeps tests StgToCmm: update comment, fix exports Specifically update comment about loopification passed into dynflags then stored into stgToCmmConfig. And remove getDynFlags from Monad.hs exports Types.Name: add pprFullName function StgToCmm.Ticky: use pprFullname, fixup ExtCode imports Cmm.Info: revert cmmGetClosureType removal StgToCmm.Bind: use pprFullName, Config update comments StgToCmm: update closureDescription api StgToCmm: SAT altHeapCheck StgToCmm: default render for Info table, ticky Use default rendering contexts for info table and ticky ticky, which should be independent of command line input. testsuite: bump count deps pprFullName: flag for ticky vs normal style output convertInfoProvMap: remove unused parameter StgToCmm.Config: add backend flags to config StgToCmm.Config: remove Backend from Config StgToCmm.Prim: refactor Backend call sites StgToCmm.Prim: remove redundant imports StgToCmm.Config: refactor vec compatibility check StgToCmm.Config: add allowQuotRem2 flag StgToCmm.Ticky: print internal names with parens StgToCmm.Bind: dispatch ppr based on externality StgToCmm: Add pprTickyname, Fix ticky naming Accidently removed the ctx for ticky SDoc output. The only relevant flag is sdocPprDebug which was accidental set to False due to using defaultSDocContext without altering the flag. StgToCmm: remove stateful fields in config fixup: config: remove redundant imports StgToCmm: move Sequel type to its own module StgToCmm: proliferate getCallMethod updated api StgToCmm.Monad: add FCodeState to Monad Api StgToCmm: add second reader monad to FCode fixup: Prim.hs: missed a merge conflict fixup: Match countDeps tests to HEAD StgToCmm.Monad: withState -> withCgState To disambiguate it from mtl withState. This withState shouldn't be returning the new state as a value. However, fixing this means tackling the knot tying in CgState and so is very difficult since it changes when the thunk of the knot is forced which either leads to deadlock or to compiler panic. - - - - - 58eccdbc by Ben Gamari at 2022-01-31T18:46:47-05:00 codeGen: Fix two buglets in -fbounds-check logic @Bodigrim noticed that the `compareByteArray#` bounds-checking logic had flipped arguments and an off-by-one. For the sake of clarity I also refactored occurrences of `cmmOffset` to rather use `cmmOffsetB`. I suspect the former should be retired. - - - - - 584f03fa by Simon Peyton Jones at 2022-01-31T18:47:23-05:00 Make typechecker trace less strict Fixes #21011 - - - - - 60ac7300 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH case pprint (fixes #20893) This patch ensures that the pretty printer formats `case` statements using braces (instead of layout) to remain consistent with the formatting of other statements (like `do`) - - - - - fdda93b0 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH LambdaCase and where clauses This patch ensures that the pretty printer formats LambdaCase and where clauses using braces (instead of layout) to remain consistent with the formatting of other statements (like `do` and `case`) - - - - - 06185102 by Ben Gamari at 2022-02-01T12:29:26-05:00 Consistently upper-case "Note [" This was achieved with git ls-tree --name-only HEAD -r | xargs sed -i -e 's/note \[/Note \[/g' - - - - - 88fba8a4 by Ben Gamari at 2022-02-01T12:29:26-05:00 Fix a few Note inconsistencies - - - - - 05548a22 by Douglas Wilson at 2022-02-02T19:26:06-05:00 rts: Address failures to inline - - - - - 074945de by Simon Peyton Jones at 2022-02-02T19:26:41-05:00 Two small improvements in the Simplifier As #20941 describes, this patch implements a couple of small fixes to the Simplifier. They make a difference principally with -O0, so few people will notice. But with -O0 they can reduce the number of Simplifer iterations. * In occurrence analysis we avoid making x = (a,b) into a loop breaker because we want to be able to inline x, or (more likely) do case-elimination. But HEAD does not treat x = let y = blah in (a,b) in the same way. We should though, because we are going to float that y=blah out of the x-binding. A one-line fix in OccurAnal. * The crucial function exprIsConApp_maybe uses getUnfoldingInRuleMatch (rightly) but the latter was deeply strange. In HEAD, if rule-rewriting was off (-O0) we only looked inside stable unfoldings. Very stupid. The patch simplifies. * I also noticed that in simplStableUnfolding we were failing to delete the DFun binders from the usage. So I added that. Practically zero perf change across the board, except that we get more compiler allocation in T3064 (which is compiled with -O0). There's a good reason: we get better code. But there are lots of other small compiler allocation decreases: Metrics: compile_time/bytes allocated --------------------- Baseline Test Metric value New value Change ----------------------------------------------------------------- PmSeriesG(normal) ghc/alloc 44,260,817 44,184,920 -0.2% PmSeriesS(normal) ghc/alloc 52,967,392 52,891,632 -0.1% PmSeriesT(normal) ghc/alloc 75,498,220 75,421,968 -0.1% PmSeriesV(normal) ghc/alloc 52,341,849 52,265,768 -0.1% T10421(normal) ghc/alloc 109,702,291 109,626,024 -0.1% T10421a(normal) ghc/alloc 76,888,308 76,809,896 -0.1% T10858(normal) ghc/alloc 125,149,038 125,073,648 -0.1% T11276(normal) ghc/alloc 94,159,364 94,081,640 -0.1% T11303b(normal) ghc/alloc 40,230,059 40,154,368 -0.2% T11822(normal) ghc/alloc 107,424,540 107,346,088 -0.1% T12150(optasm) ghc/alloc 76,486,339 76,426,152 -0.1% T12234(optasm) ghc/alloc 55,585,046 55,507,352 -0.1% T12425(optasm) ghc/alloc 88,343,288 88,265,312 -0.1% T13035(normal) ghc/alloc 98,919,768 98,845,600 -0.1% T13253-spj(normal) ghc/alloc 121,002,153 120,851,040 -0.1% T16190(normal) ghc/alloc 290,313,131 290,074,152 -0.1% T16875(normal) ghc/alloc 34,756,121 34,681,440 -0.2% T17836b(normal) ghc/alloc 45,198,100 45,120,288 -0.2% T17977(normal) ghc/alloc 39,479,952 39,404,112 -0.2% T17977b(normal) ghc/alloc 37,213,035 37,137,728 -0.2% T18140(normal) ghc/alloc 79,430,588 79,350,680 -0.1% T18282(normal) ghc/alloc 128,303,182 128,225,384 -0.1% T18304(normal) ghc/alloc 84,904,713 84,831,952 -0.1% T18923(normal) ghc/alloc 66,817,241 66,731,984 -0.1% T20049(normal) ghc/alloc 86,188,024 86,107,920 -0.1% T5837(normal) ghc/alloc 35,540,598 35,464,568 -0.2% T6048(optasm) ghc/alloc 99,812,171 99,736,032 -0.1% T9198(normal) ghc/alloc 46,380,270 46,304,984 -0.2% geo. mean -0.0% Metric Increase: T3064 - - - - - d2cce453 by Morrow at 2022-02-02T19:27:21-05:00 Fix @since annotation on Nat - - - - - 6438fed9 by Simon Peyton Jones at 2022-02-02T19:27:56-05:00 Refactor the escaping kind check for data constructors As #20929 pointed out, we were in-elegantly checking for escaping kinds in `checkValidType`, even though that check was guaranteed to succeed for type signatures -- it's part of kind-checking a type. But for /data constructors/ we kind-check the pieces separately, so we still need the check. This MR is a pure refactor, moving the test from `checkValidType` to `checkValidDataCon`. No new tests; external behaviour doesn't change. - - - - - fb05e5ac by Andreas Klebinger at 2022-02-02T19:28:31-05:00 Replace sndOfTriple with sndOf3 I also cleaned up the imports slightly while I was at it. - - - - - fbc77d3a by Matthew Pickering at 2022-02-02T19:29:07-05:00 testsuite: Honour PERF_BASELINE_COMMIT when computing allowed metric changes We now get all the commits between the PERF_BASELINE_COMMIT and HEAD and check any of them for metric changes. Fixes #20882 - - - - - 0a82ae0d by Simon Peyton Jones at 2022-02-02T23:49:58-05:00 More accurate unboxing This patch implements a fix for #20817. It ensures that * The final strictness signature for a function accurately reflects the unboxing done by the wrapper See Note [Finalising boxity for demand signatures] and Note [Finalising boxity for let-bound Ids] * A much better "layer-at-a-time" implementation of the budget for how many worker arguments we can have See Note [Worker argument budget] Generally this leads to a bit more worker/wrapper generation, because instead of aborting entirely if the budget is exceeded (and then lying about boxity), we unbox a bit. Binary sizes in increase slightly (around 1.8%) because of the increase in worker/wrapper generation. The big effects are to GHC.Ix, GHC.Show, GHC.IO.Handle.Internals. If we did a better job of dropping dead code, this effect might go away. Some nofib perf improvements: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- VSD +1.8% -0.5% 0.017 0.017 0.0% awards +1.8% -0.1% +2.3% +2.3% 0.0% banner +1.7% -0.2% +0.3% +0.3% 0.0% bspt +1.8% -0.1% +3.1% +3.1% 0.0% eliza +1.8% -0.1% +1.2% +1.2% 0.0% expert +1.7% -0.1% +9.6% +9.6% 0.0% fannkuch-redux +1.8% -0.4% -9.3% -9.3% 0.0% kahan +1.8% -0.1% +22.7% +22.7% 0.0% maillist +1.8% -0.9% +21.2% +21.6% 0.0% nucleic2 +1.7% -5.1% +7.5% +7.6% 0.0% pretty +1.8% -0.2% 0.000 0.000 0.0% reverse-complem +1.8% -2.5% +12.2% +12.2% 0.0% rfib +1.8% -0.2% +2.5% +2.5% 0.0% scc +1.8% -0.4% 0.000 0.000 0.0% simple +1.7% -1.3% +17.0% +17.0% +7.4% spectral-norm +1.8% -0.1% +6.8% +6.7% 0.0% sphere +1.7% -2.0% +13.3% +13.3% 0.0% tak +1.8% -0.2% +3.3% +3.3% 0.0% x2n1 +1.8% -0.4% +8.1% +8.1% 0.0% -------------------------------------------------------------------------------- Min +1.1% -5.1% -23.6% -23.6% 0.0% Max +1.8% +0.0% +36.2% +36.2% +7.4% Geometric Mean +1.7% -0.1% +6.8% +6.8% +0.1% Compiler allocations in CI have a geometric mean of +0.1%; many small decreases but there are three bigger increases (7%), all because we do more worker/wrapper than before, so there is simply more code to compile. That's OK. Perf benchmarks in perf/should_run improve in allocation by a geo mean of -0.2%, which is good. None get worse. T12996 improves by -5.8% Metric Decrease: T12996 Metric Increase: T18282 T18923 T9630 - - - - - d1ef6288 by Peter Trommler at 2022-02-02T23:50:34-05:00 Cmm: fix equality of expressions Compare expressions and types when comparing `CmmLoad`s. Fixes #21016 - - - - - e59446c6 by Peter Trommler at 2022-02-02T23:50:34-05:00 Check type first then expression - - - - - b0e1ef4a by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add failing test for #20791 The test produces different output on static vs dynamic GHC builds. - - - - - cae1fb17 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Frontend01 passes with static GHC - - - - - e343526b by Matthew Pickering at 2022-02-03T14:44:17-05:00 Don't initialise plugins when there are no pipelines to run - - - - - abac45fc by Matthew Pickering at 2022-02-03T14:44:17-05:00 Mark prog003 as expected_broken on static way #20704 - - - - - 13300dfd by Matthew Pickering at 2022-02-03T14:44:17-05:00 Filter out -rtsopts in T16219 to make static/dynamic ways agree - - - - - d89439f2 by Matthew Pickering at 2022-02-03T14:44:17-05:00 T13168: Filter out rtsopts for consistency between dynamic and static ways - - - - - 00180cdf by Matthew Pickering at 2022-02-03T14:44:17-05:00 Accept new output for T14335 test This test was previously not run due to #20960 - - - - - 1accdcff by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add flushes to plugin tests which print to stdout Due to #20791 you need to explicitly flush as otherwise the output from these tests doesn't make it to stdout. - - - - - d820f2e8 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Remove ghc_plugin_way Using ghc_plugin_way had the unintended effect of meaning certain tests weren't run at all when ghc_dynamic=true, if you delete this modifier then the tests work in both the static and dynamic cases. - - - - - aa5ef340 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Unbreak T13168 on windows Fixes #14276 - - - - - 84ab0153 by Matthew Pickering at 2022-02-03T14:44:53-05:00 Rewrite CallerCC parser using ReadP This allows us to remove the dependency on parsec and hence transitively on text. Also added some simple unit tests for the parser and fixed two small issues in the documentation. Fixes #21033 - - - - - 4e6780bb by Matthew Pickering at 2022-02-03T14:45:28-05:00 ci: Add debian 11 jobs (validate/release/nightly) Fixes #21002 - - - - - eddaa591 by Ben Gamari at 2022-02-04T10:01:59-05:00 compiler: Introduce and use RoughMap for instance environments Here we introduce a new data structure, RoughMap, inspired by the previous `RoughTc` matching mechanism for checking instance matches. This allows [Fam]InstEnv to be implemented as a trie indexed by these RoughTc signatures, reducing the complexity of instance lookup and FamInstEnv merging (done during the family instance conflict test) from O(n) to O(log n). The critical performance improvement currently realised by this patch is in instance matching. In particular the RoughMap mechanism allows us to discount many potential instances which will never match for constraints involving type variables (see Note [Matching a RoughMap]). In realistic code bases matchInstEnv was accounting for 50% of typechecker time due to redundant work checking instances when simplifying instance contexts when deriving instances. With this patch the cost is significantly reduced. The larger constants in InstEnv creation do mean that a few small tests regress in allocations slightly. However, the runtime of T19703 is reduced by a factor of 4. Moreover, the compilation time of the Cabal library is slightly improved. A couple of test cases are included which demonstrate significant improvements in compile time with this patch. This unfortunately does not fix the testcase provided in #19703 but does fix #20933 ------------------------- Metric Decrease: T12425 Metric Increase: T13719 T9872a T9872d hard_hole_fits ------------------------- Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 62d670eb by Matthew Pickering at 2022-02-04T10:02:35-05:00 testsuite: Run testsuite dependency calculation before GHC is built The main motivation for this patch is to allow tests to be added to the testsuite which test things about the source tree without needing to build GHC. In particular the notes linter can easily start failing and by integrating it into the testsuite the process of observing these changes is caught by normal validation procedures rather than having to run the linter specially. With this patch I can run ``` ./hadrian/build test --flavour=devel2 --only="uniques" ``` In a clean tree to run the checkUniques linter without having to build GHC. Fixes #21029 - - - - - 4bd52410 by Hécate Moonlight at 2022-02-04T16:14:10-05:00 Add the Ix class to Foreign C integral types Related CLC proposal is here: https://github.com/haskell/core-libraries-committee/issues/30 - - - - - de6d7692 by Ben Gamari at 2022-02-04T16:14:47-05:00 Drop dead code - - - - - b79206f1 by Ben Gamari at 2022-02-04T16:14:47-05:00 Add comments - - - - - 58d7faac by Ben Gamari at 2022-02-04T16:14:47-05:00 cmm: Introduce cmmLoadBWord and cmmLoadGCWord - - - - - 7217156c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment in CmmLoad - - - - - 99ea5f2c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment to CmmStore - - - - - 606b59a5 by Ben Gamari at 2022-02-04T16:14:47-05:00 Fix array primop alignment - - - - - 1cf9616a by Ben Gamari at 2022-02-04T16:14:47-05:00 llvmGen: Handle unaligned loads/stores This allows us to produce valid code for indexWord8ArrayAs*# on platforms that lack unaligned memory access. - - - - - 8c18feba by Ben Gamari at 2022-02-04T16:14:47-05:00 primops: Fix documentation of setByteArray# Previously the documentation was subtly incorrect regarding the bounds of the operation. Fix this and add a test asserting that a zero-length operation is in fact a no-op. - - - - - 88480e55 by nineonine at 2022-02-04T20:35:45-05:00 Fix unsound behavior of unlifted datatypes in ghci (#20194) Previously, directly calling a function that pattern matches on an unlifted data type which has at least two constructors in GHCi resulted in a segfault. This happened due to unaccounted return frame info table pointer. The fix is to pop the above mentioned frame info table pointer when unlifted things are returned. See Note [Popping return frame for unlifted things] authors: bgamari, nineonine - - - - - a5c7068c by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add Outputable instance for Messages c.f. #20980 - - - - - bf495f72 by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add a missing restoreLclEnv The commit commit 18df4013f6eaee0e1de8ebd533f7e96c4ee0ff04 Date: Sat Jan 22 01:12:30 2022 +0000 Define and use restoreLclEnv omitted to change one setLclEnv to restoreLclEnv, namely the one in GHC.Tc.Errors.warnRedundantConstraints. This new commit fixes the omission. - - - - - 6af8e71e by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Improve errors for non-existent labels This patch fixes #17469, by improving matters when you use non-existent field names in a record construction: data T = MkT { x :: Int } f v = MkT { y = 3 } The check is now made in the renamer, in GHC.Rename.Env.lookupRecFieldOcc. That in turn led to a spurious error in T9975a, which is fixed by making GHC.Rename.Names.extendGlobalRdrEnvRn fail fast if it finds duplicate bindings. See Note [Fail fast on duplicate definitions] in that module for more details. This patch was originated and worked on by Alex D (@nineonine) - - - - - 299acff0 by nineonine at 2022-02-05T19:21:49-05:00 Exit with failure when -e fails (fixes #18411 #9916 #17560) - - - - - 549292eb by Matthew Pickering at 2022-02-05T19:22:25-05:00 Make implication tidying agree with Note [Tidying multiple names at once] Note [Tidying multiple names at once] indicates that if multiple variables have the same name then we shouldn't prioritise one of them and instead rename them all to a1, a2, a3... etc This patch implements that change, some error message changes as expected. Closes #20932 - - - - - 2e9248b7 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Accept any address within 4GB of program text Previously m32 would assume that the program image was located near the start of the address space and therefore assume that it wanted pages in the bottom 4GB of address space. Instead we now check whether they are within 4GB of whereever the program is loaded. This is necessary on Windows, which now tends to place the image in high memory. The eventual goal is to use m32 to allocate memory for linker sections on Windows. - - - - - 86589b89 by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts: Generalize mmapForLinkerMarkExecutable Renamed to mprotectForLinker and allowed setting of arbitrary protection modes. - - - - - 88ef270a by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Add consistency-checking infrastructure This adds logic, enabled in the `-debug` RTS for checking the internal consistency of the m32 allocator. This area has always made me a bit nervous so this should help me sleep better at night in exchange for very little overhead. - - - - - 2d6f0b17 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Free large objects back to the free page pool Not entirely convinced that this is worth doing. - - - - - e96f50be by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Increase size of free page pool to 256 pages - - - - - fc083b48 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts: Dump memory map on memory mapping failures Fixes #20992. - - - - - 633296bc by Ben Gamari at 2022-02-06T01:43:56-05:00 Fix macro redefinition warnings for PRINTF * Move `PRINTF` macro from `Stats.h` to `Stats.c` as it's only needed in the latter. * Undefine `PRINTF` at the end of `Messages.h` to avoid leaking it. - - - - - 37d435d2 by John Ericson at 2022-02-06T01:44:32-05:00 Purge DynFlags from GHC.Stg Also derive some more instances. GHC doesn't need them, but downstream consumers may need to e.g. put stuff in maps. - - - - - 886baa34 by Peter Trommler at 2022-02-06T10:58:18+01:00 RTS: Fix cabal specification In 35bea01b xxhash.c was removed. Remove the extra-source-files stanza referring to it. - - - - - 27581d77 by nineonine at 2022-02-06T20:50:44-05:00 hadrian: remove redundant import - - - - - 4ff19981 by John Ericson at 2022-02-07T11:04:43-05:00 GHC.HsToCore.Coverage: No more HscEnv, less DynFlags Progress towards #20730 - - - - - b09389a6 by John Ericson at 2022-02-07T11:04:43-05:00 Create `CoverageConfig` As requested by @mpickering to collect the information we project from `HscEnv` - - - - - ff867c46 by Greg Steuck at 2022-02-07T11:05:24-05:00 Avoid using removed utils/checkUniques in validate Asked the question: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7460/diffs#4061f4d17546e239dd10d78c6b48668c2a288e02_1_0 - - - - - a9355e84 by sheaf at 2022-02-08T05:27:25-05:00 Allow HasField in quantified constraints We perform validity checking on user-written HasField instances, for example to disallow: data Foo a = Foo { fld :: Int } instance HasField "fld" (Foo a) Bool However, these checks were also being made on quantified constraints, e.g. data Bar where Bar :: (forall a. HasField s (Foo a) Int) => Proxy s -> Bar This patch simply skips validity checking for quantified constraints, in line with what we already do for equality constraints such as Coercible. Fixes #20989 - - - - - 6d77d3d8 by sheaf at 2022-02-08T05:28:05-05:00 Relax TyEq:N: allow out-of-scope newtype DataCon The 'bad_newtype' assertion in GHC.Tc.Solver.Canonical.canEqCanLHSFinish failed to account for the possibility that the newtype constructor might not be in scope, in which case we don't provide any guarantees about canonicalising away a newtype on the RHS of a representational equality. Fixes #21010 - - - - - a893d2f3 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Remove linter dependency on lint-submods - - - - - 457a5b9c by Ben Gamari at 2022-02-08T05:28:42-05:00 notes-util: initial commit - - - - - 1a943859 by Ben Gamari at 2022-02-08T05:28:42-05:00 gitlab-ci: Add lint-notes job - - - - - bc5cbce6 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add notes linter to testsuite - - - - - 38c6e301 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Fix some notes - - - - - c3aac0f8 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add suggestion mode to notes-util - - - - - 5dd29aea by Cale Gibbard at 2022-02-08T05:29:18-05:00 `hscSimpleIface` drop fingerprint param and ret `hscSimpleIface` does not depend on or modify the `Maybe Fingerprint` it is given, only passes it through, so get rid of the extraneous passing. Perhaps the intent was that there would be an iface fingerprint check of some sort? but this was never done. If/when we we want to do that, we can add it back then. - - - - - 4bcbd731 by Cale Gibbard at 2022-02-08T05:29:54-05:00 Document `hscIncrementalFrontend` and flip bool - - - - - b713db1e by John Ericson at 2022-02-08T05:30:29-05:00 StgToCmm: Get rid of GHC.Driver.Session imports `DynFlags` is gone, but let's move a few trivial things around to get rid of its module too. - - - - - f115c382 by Gleb Popov at 2022-02-08T05:31:05-05:00 Fix build on recent FreeBSD. Recent FreeBSD versions gained the sched_getaffinity function, which made two mutually exclusive #ifdef blocks to be enabled. - - - - - 3320ab40 by Ben Gamari at 2022-02-08T10:42:04-05:00 rts/MemoryMap: Use mach_-prefixed type names There appears to be some inconsistency in system-call type naming across Darwin toolchains. Specifically: * the `address` argument to `mach_vm_region` apparently wants to be a `mach_vm_address_t *`, not a `vm_address_t *` * the `vmsize` argument to `mach_vm_region` wants to be a `mach_vm_size_t`, not a `vm_size_t` - - - - - b33f0cfa by Richard Eisenberg at 2022-02-08T10:42:41-05:00 Document that reifyRoles includes kind parameters Close #21056 - - - - - bd493ed6 by PHO at 2022-02-08T10:43:19-05:00 Don't try to build stage1 with -eventlog if stage0 doesn't provide it Like -threaded, stage0 isn't guaranteed to have an event-logging RTS. - - - - - 03c2de0f by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Use absolute paths for config.libdir Fixes #21052 - - - - - ef294525 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Clean up old/redundant predicates - - - - - a39ed908 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Add missing dependency on ghcconfig - - - - - a172be07 by PHO at 2022-02-09T03:56:59-05:00 Implement System.Environment.getExecutablePath for NetBSD and also use it from GHC.BaseDir.getBaseDir - - - - - 62fa126d by PHO at 2022-02-09T03:57:37-05:00 Fix a portability issue in m4/find_llvm_prog.m4 `test A == B' is a Bash extension, which doesn't work on platforms where /bin/sh is not Bash. - - - - - fd9981e3 by Ryan Scott at 2022-02-09T03:58:13-05:00 Look through untyped TH splices in tcInferAppHead_maybe Previously, surrounding a head expression with a TH splice would defeat `tcInferAppHead_maybe`, preventing some expressions from typechecking that used to typecheck in previous GHC versions (see #21038 for examples). This is simple enough to fix: just look through `HsSpliceE`s in `tcInferAppHead_maybe`. I've added some additional prose to `Note [Application chains and heads]` in `GHC.Tc.Gen.App` to accompany this change. Fixes #21038. - - - - - 00975981 by sheaf at 2022-02-09T03:58:53-05:00 Add test for #21037 This program was rejected by GHC 9.2, but is accepted on newer versions of GHC. This patch adds a regression test. Closes #21037 - - - - - fad0b2b0 by Ben Gamari at 2022-02-09T08:29:46-05:00 Rename -merge-objs flag to --merge-objs For consistency with --make and friends. - - - - - 1dbe5b2a by Matthew Pickering at 2022-02-09T08:30:22-05:00 driver: Filter out our own boot module in hptSomeThingsBelow hptSomeThingsBelow would return a list of modules which contain the .hs-boot file for a particular module. This caused some problems because we would try and find the module in the HPT (but it's not there when we're compiling the module itself). Fixes #21058 - - - - - 2b1cced1 by Sylvain Henry at 2022-02-09T20:42:23-05:00 NCG: minor code factorization - - - - - e01ffec2 by Sylvain Henry at 2022-02-09T20:42:23-05:00 ByteCode: avoid out-of-bound read Cf https://gitlab.haskell.org/ghc/ghc/-/issues/18431#note_287139 - - - - - 53c26e79 by Ziyang Liu at 2022-02-09T20:43:02-05:00 Include ru_name in toHsRule message See #18147 - - - - - 3df06922 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Rename MemoryMap.[ch] -> ReportMemoryMap.[ch] - - - - - e219ac82 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Move mmapForLinker and friends to linker/MMap.c They are not particularly related to linking. - - - - - 30e205ca by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker: Drop dead IA64 code - - - - - 4d3a306d by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker/MMap: Use MemoryAccess in mmapForLinker - - - - - 1db4f1fe by Ben Gamari at 2022-02-09T20:43:39-05:00 linker: Don't use MAP_FIXED As noted in #21057, we really shouldn't be using MAP_FIXED. I would much rather have the process crash with a "failed to map" error than randomly overwrite existing mappings. Closes #21057. - - - - - 1eeae25c by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/mmap: Refactor mmapForLinker Here we try to separate the policy decisions of where to place mappings from the mechanism of creating the mappings. This makes things significantly easier to follow. - - - - - ac2d18a7 by sheaf at 2022-02-09T20:44:18-05:00 Add some perf tests for coercions This patch adds some performance tests for programs that create large coercions. This is useful because the existing test coverage is not very representative of real-world situations. In particular, this adds a test involving an extensible records library, a common pain-point for users. - - - - - 48f25715 by Andreas Klebinger at 2022-02-10T04:35:35-05:00 Add late cost centre support This allows cost centres to be inserted after the core optimization pipeline has run. - - - - - 0ff70427 by Andreas Klebinger at 2022-02-10T04:36:11-05:00 Docs:Mention that safe calls don't keep their arguments alive. - - - - - 1d3ed168 by Ben Gamari at 2022-02-10T04:36:46-05:00 PEi386: Drop Windows Vista fallback in addLibrarySearchPath We no longer support Windows Vista. - - - - - 2a6f2681 by Ben Gamari at 2022-02-10T04:36:46-05:00 linker/PEi386: Make addLibrarySearchPath long-path aware Previously `addLibrarySearchPath` failed to normalise the added path to UNC form before passing it to `AddDllDirectory`. Consequently, the call was subject to the MAX_PATH restriction, leading to the failure of `test-defaulting-plugin-fail`, among others. Happily, this also nicely simplifies the implementation. Closes #21059. - - - - - 2a47ee9c by Daniel Gröber at 2022-02-10T19:18:58-05:00 ghc-boot: Simplify writePackageDb permissions handling Commit ef8a3fbf1 ("ghc-boot: Fix metadata handling of writeFileAtomic") introduced a somewhat over-engineered fix for #14017 by trying to preserve the current permissions if the target file already exists. The problem in the issue is simply that the package db cache file should be world readable but isn't if umask is too restrictive. In fact the previous fix only handles part of this problem. If the file isn't already there in a readable configuration it wont make it so which isn't really ideal either. Rather than all that we now simply always force all the read access bits to allow access while leaving the owner at the system default as it's just not our business to mess with it. - - - - - a1d97968 by Ben Gamari at 2022-02-10T19:19:34-05:00 Bump Cabal submodule Adapts GHC to the factoring-out of `Cabal-syntax`. Fixes #20991. Metric Decrease: haddock.Cabal - - - - - 89cf8caa by Morrow at 2022-02-10T19:20:13-05:00 Add metadata to integer-gmp.cabal - - - - - c995b7e7 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of EVENT_IPE This leads to corrupted eventlogs because the size of EVENT_IPE is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 59ba8fb3 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of MEM_RETURN This leads to corrupted eventlogs because the size of EVENT_MEM_RETURN is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 19413d09 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Delete misleading comment in gen_event_types.py Not all events start with CapNo and there's not logic I could see which adds this to the length. - - - - - e06f49c0 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix size of TICKY_COUNTER_BEGIN_SAMPLE - - - - - 2f99255b by Matthew Pickering at 2022-02-10T19:21:24-05:00 Fix copy-pasto in prof-late-ccs docs - - - - - 19deb002 by Matthew Pickering at 2022-02-10T19:21:59-05:00 Refine tcSemigroupWarnings to work in ghc-prim ghc-prim doesn't depend on base so can't have any Monoid or Semigroup instances. However, attempting to load these definitions ran into issues when the interface for `GHC.Base` did exist as that would try and load the interface for `GHC.Types` (which is the module we are trying to compile and has no interface). The fix is to just not do this check when we are compiling a module in ghc-prim. Fixes #21069 - - - - - 34dec6b7 by sheaf at 2022-02-11T17:55:34-05:00 Decrease the size of the LargeRecord test This test was taking too long to run, so this patch makes it smaller. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 9cab90d9 by Matthew Pickering at 2022-02-11T22:27:19-05:00 Make sure all platforms have a release job The release bindists are currently a mixture of validate and release builds. This is bad because the validate builds don't have profiling libraries. The fix is to make sure there is a release job for each platform we want to produce a release for.t Fixes #21066 - - - - - 4bce3575 by Matthew Pickering at 2022-02-11T22:27:54-05:00 testsuite: Make sure all tests trigger ghc rebuild I made a mistake when implementing #21029 which meant that certain tests didn't trigger a GHC recompilation. By adding the `test:ghc` target to the default settings all tests will now depend on this target unless explicitly opting out via the no_deps modifier. - - - - - 90a26f8b by Sylvain Henry at 2022-02-11T22:28:34-05:00 Fix documentation about Word64Rep/Int64Rep (#16964) - - - - - 0e93023e by Andreas Klebinger at 2022-02-12T13:59:41+00:00 Tag inference work. This does three major things: * Enforce the invariant that all strict fields must contain tagged pointers. * Try to predict the tag on bindings in order to omit tag checks. * Allows functions to pass arguments unlifted (call-by-value). The former is "simply" achieved by wrapping any constructor allocations with a case which will evaluate the respective strict bindings. The prediction is done by a new data flow analysis based on the STG representation of a program. This also helps us to avoid generating redudant cases for the above invariant. StrictWorkers are created by W/W directly and SpecConstr indirectly. See the Note [Strict Worker Ids] Other minor changes: * Add StgUtil module containing a few functions needed by, but not specific to the tag analysis. ------------------------- Metric Decrease: T12545 T18698b T18140 T18923 LargeRecord Metric Increase: LargeRecord ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T15164 T18282 T18304 T18698a T1969 T20049 T3294 T4801 T5321FD T5321Fun T783 T9233 T9675 T9961 T19695 WWRec ------------------------- - - - - - 744f8a11 by Greg Steuck at 2022-02-12T17:13:55-05:00 Only check the exit code in derefnull & divbyzero tests on OpenBSD - - - - - eeead9fc by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/Adjustor: Ensure that allocateExecPage succeeded Previously we failed to handle the case that `allocateExecPage` failed. - - - - - afdfaff0 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Drop DEC Alpha adjustor implementation The last Alpha chip was produced in 2004. - - - - - 191dfd2d by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/adjustor: Split Windows path out of NativeAmd64 - - - - - be591e27 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Initial commit of AdjustorPool - - - - - d6d48b16 by Ben Gamari at 2022-02-13T03:26:14-05:00 Introduce initAdjustors - - - - - eab37902 by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64: Use AdjustorPool - - - - - 974e73af by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64Mingw: Use AdjustorPool - - - - - 95fab83f by Ben Gamari at 2022-02-13T03:26:14-05:00 configure: Fix result reporting of adjustors method check - - - - - ef5cf55d by nikshalark at 2022-02-13T03:26:16-05:00 (#21044) Documented arithmetic functions in base. Didn't get it right the ninth time. Now everything's formatted correctly. - - - - - acb482cc by Takenobu Tani at 2022-02-16T05:27:17-05:00 Relax load_load_barrier for aarch64 This patch relaxes the instruction for load_load_barrier(). Current load_load_barrier() implements full-barrier with `dmb sy`. It's too strong to order load-load instructions. We can relax it by using `dmb ld`. If current load_load_barrier() is used for full-barriers (load/store - load/store barrier), this patch is not suitable. See also linux-kernel's smp_rmb() implementation: https://github.com/torvalds/linux/blob/v5.14/arch/arm64/include/asm/barrier.h#L90 Hopefully, it's better to use `dmb ishld` rather than `dmb ld` to improve performance. However, I can't validate effects on a real many-core Arm machine. - - - - - 84eaa26f by Oleg Grenrus at 2022-02-16T05:27:56-05:00 Add test for #20562 - - - - - 2c28620d by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: remove struct StgRetry, it is never used - - - - - 74bf9bb5 by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: document some closure types - - - - - 316312ec by nineonine at 2022-02-16T05:29:08-05:00 ghci: fix -ddump-stg-cg (#21052) The pre-codegen Stg AST dump was not available in ghci because it was performed in 'doCodeGen'. This was now moved to 'coreToStg' area. - - - - - a6411d74 by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: mention -fprof-late-ccs in the release notes And note which compiler version it was added in. - - - - - 4127e86d by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: fix release notes formatting - - - - - 4e6c8019 by Matthew Pickering at 2022-02-17T05:25:28-05:00 Always define __GLASGOW_HASKELL_PATCHLEVEL1/2__ macros As #21076 reports if you are using `-Wcpp-undef` then you get warnings when using the `MIN_VERSION_GLASGOW_HASKELL` macro because __GLASGOW_HASKELL_PATCHLEVEL2__ is very rarely explicitliy set (as version numbers are not 4 components long). This macro was introduced in 3549c952b535803270872adaf87262f2df0295a4 and it seems the bug has existed ever since. Fixes #21076 - - - - - 67dd5724 by Ben Gamari at 2022-02-17T05:26:03-05:00 rts/AdjustorPool: Silence unused function warning bitmap_get is only used in the DEBUG RTS configuration. Fixes #21079. - - - - - 4b04f7e1 by Zubin Duggal at 2022-02-20T13:56:15-05:00 Track object file dependencies for TH accurately (#20604) `hscCompileCoreExprHook` is changed to return a list of `Module`s required by a splice. These modules are accumulated in the TcGblEnv (tcg_th_needed_mods). Dependencies on the object files of these modules are recording in the interface. The data structures in `LoaderState` are replaced with more efficient versions to keep track of all the information required. The MultiLayerModulesTH_Make allocations increase slightly but runtime is faster. Fixes #20604 ------------------------- Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - 92ab3ff2 by sheaf at 2022-02-20T13:56:55-05:00 Use diagnostics for "missing signature" errors This patch makes the "missing signature" errors from "GHC.Rename.Names" use the diagnostic infrastructure. This encompasses missing type signatures for top-level bindings and pattern synonyms, as well as missing kind signatures for type constructors. This patch also renames TcReportMsg to TcSolverReportMsg, and adds a few convenience functions to compute whether such a TcSolverReportMsg is an expected/actual message. - - - - - 845284a5 by sheaf at 2022-02-20T13:57:34-05:00 Generically: remove redundant Semigroup constraint This patch removes a redundant Semigroup constraint on the Monoid instance for Generically. This constraint can cause trouble when one wants to derive a Monoid instance via Generically through a type that doesn't itself have a Semigroup instance, for example: data Point2D a = Point2D !a !a newtype Vector2D a = Vector2D { tip :: Point2D a } deriving ( Semigroup, Monoid ) via Generically ( Point2D ( Sum a ) ) In this case, we should not require there to be an instance Semigroup ( Point2D ( Sum a ) ) as all we need is an instance for the generic representation of Point2D ( Sum a ), i.e. Semigroup ( Rep ( Point2D ( Sum a) ) () ). - - - - - 6b468f7f by Ben Gamari at 2022-02-20T13:58:10-05:00 Bump time submodule to 1.12.1 - - - - - 2f0ceecc by Zubin Duggal at 2022-02-20T19:06:19+00:00 hadrian: detect if 'main' is not a haskell file and add it to appropriate list of sources - - - - - 7ce1b694 by Zubin Duggal at 2022-02-21T11:18:58+00:00 Reinstallable GHC This patch allows ghc and its dependencies to be built using a normal invocation of cabal-install. Each componenent which relied on generated files or additional configuration now has a Setup.hs file. There are also various fixes to the cabal files to satisfy cabal-install. There is a new hadrian command which will build a stage2 compiler and then a stage3 compiler by using cabal. ``` ./hadrian/build build-cabal ``` There is also a new CI job which tests running this command. For the 9.4 release we will upload all the dependent executables to hackage and then end users will be free to build GHC and GHC executables via cabal. There are still some unresolved questions about how to ensure soundness when loading plugins into a reinstalled GHC (#20742) which will be tighted up in due course. Fixes #19896 - - - - - 78fbc3a3 by Matthew Pickering at 2022-02-21T15:14:28-05:00 hadrian: Enable late-ccs when building profiled_ghc - - - - - 2b890c89 by Matthew Pickering at 2022-02-22T15:59:33-05:00 testsuite: Don't print names of all fragile tests on all runs This information about fragile tests is pretty useless but annoying on CI where you have to scroll up a long way to see the actual issues. - - - - - 0b36801f by sheaf at 2022-02-22T16:00:14-05:00 Forbid standalone instances for built-in classes `check_special_inst_head` includes logic that disallows hand-written instances for built-in classes such as Typeable, KnownNat and KnownSymbol. However, it also allowed standalone deriving declarations. This was because we do want to allow standalone deriving instances with Typeable as they are harmless, but we certainly don't want to allow instances for e.g. KnownNat. This patch ensures that we don't allow derived instances for KnownNat, KnownSymbol (and also KnownChar, which was previously omitted entirely). Fixes #21087 - - - - - ace66dec by Krzysztof Gogolewski at 2022-02-22T16:30:59-05:00 Remove -Wunticked-promoted-constructors from -Wall Update manual; explain ticks as optional disambiguation rather than the preferred default. This is a part of #20531. - - - - - 558c7d55 by Hugo at 2022-02-22T16:31:01-05:00 docs: fix error in annotation guide code snippet - - - - - a599abba by Richard Eisenberg at 2022-02-23T08:16:07-05:00 Kill derived constraints Co-authored by: Sam Derbyshire Previously, GHC had three flavours of constraint: Wanted, Given, and Derived. This removes Derived constraints. Though serving a number of purposes, the most important role of Derived constraints was to enable better error messages. This job has been taken over by the new RewriterSets, as explained in Note [Wanteds rewrite wanteds] in GHC.Tc.Types.Constraint. Other knock-on effects: - Various new Notes as I learned about under-described bits of GHC - A reshuffling around the AST for implicit-parameter bindings, with better integration with TTG. - Various improvements around fundeps. These were caused by the fact that, previously, fundep constraints were all Derived, and Derived constraints would get dropped. Thus, an unsolved Derived didn't stop compilation. Without Derived, this is no longer possible, and so we have to be considerably more careful around fundeps. - A nice little refactoring in GHC.Tc.Errors to center the work on a new datatype called ErrorItem. Constraints are converted into ErrorItems at the start of processing, and this allows for a little preprocessing before the main classification. - This commit also cleans up the behavior in generalisation around functional dependencies. Now, if a variable is determined by functional dependencies, it will not be quantified. This change is user facing, but it should trim down GHC's strange behavior around fundeps. - Previously, reportWanteds did quite a bit of work, even on an empty WantedConstraints. This commit adds a fast path. - Now, GHC will unconditionally re-simplify constraints during quantification. See Note [Unconditionally resimplify constraints when quantifying], in GHC.Tc.Solver. Close #18398. Close #18406. Solve the fundep-related non-confluence in #18851. Close #19131. Close #19137. Close #20922. Close #20668. Close #19665. ------------------------- Metric Decrease: LargeRecord T9872b T9872b_defer T9872d TcPlugin_RewritePerf ------------------------- - - - - - 2ed22ba1 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Introduce predicate for when to enable source notes (needSourceNotes) There were situations where we were using debugLevel == 0 as a proxy for whether to retain source notes but -finfo-table-map also enables and needs source notes so we should act consistently in both cases. Ticket #20847 - - - - - 37deb893 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Use SrcSpan from the binder as initial source estimate There are some situations where we end up with no source notes in useful positions in an expression. In this case we currently fail to provide any source information about where an expression came from. This patch improves the initial estimate by using the position from the top-binder as the guess for the location of the whole inner expression. It provides quite a course estimate but it's better than nothing. Ticket #20847 - - - - - 59b7f764 by Cheng Shao at 2022-02-23T08:17:24-05:00 Don't emit foreign exports initialiser code for empty CAF list - - - - - c7f32f76 by John Ericson at 2022-02-23T13:58:36-05:00 Prepare rechecking logic for new type in a few ways Combine `MustCompile and `NeedsCompile` into a single case. `CompileReason` is put inside to destinguish the two. This makes a number of things easier. `Semigroup RecompileRequired` is no longer used, to make sure we skip doing work where possible. `recompThen` is very similar, but helps remember. `checkList` is rewritten with `recompThen`. - - - - - e60d8df8 by John Ericson at 2022-02-23T13:58:36-05:00 Introduce `MaybeValidated` type to remove invalid states The old return type `(RecompRequired, Maybe _)`, was confusing because it was inhabited by values like `(UpToDate, Nothing)` that made no sense. The new type ensures: - you must provide a value if it is up to date. - you must provide a reason if you don't provide a value. it is used as the return value of: - `checkOldIface` - `checkByteCode` - `checkObjects` - - - - - f07b13e3 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor X86 codegen Preliminary work done to make working on #5444 easier. Mostly make make control-flow easier to follow: * renamed genCCall into genForeignCall * split genForeignCall into the part dispatching on PrimTarget (genPrim) and the one really generating code for a C call (cf ForeignTarget and genCCall) * made genPrim/genSimplePrim only dispatch on MachOp: each MachOp now has its own code generation function. * out-of-line primops are not handled in a partial `outOfLineCmmOp` anymore but in the code generation functions directly. Helper functions have been introduced (e.g. genLibCCall) for code sharing. * the latter two bullets make code generated for primops that are only sometimes out-of-line (e.g. Pdep or Memcpy) and the logic to select between inline/out-of-line much more localized * avoided passing is32bit as an argument as we can easily get it from NatM state when we really need it * changed genCCall type to avoid it being partial (it can't handle PrimTarget) * globally removed 12 calls to `panic` thanks to better control flow and types ("parse, don't validate" ftw!). - - - - - 6fa7591e by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor the way registers are handled * add getLocalRegReg to avoid allocating a CmmLocal just to call getRegisterReg * 64-bit registers: in the general case we must always use the virtual higher part of the register, so we might as well always return it with the lower part. The only exception is to implement 64-bit to 32-bit conversions. We now have to explicitly discard the higher part when matching on Reg64/RegCode64 datatypes instead of explicitly fetching the higher part from the lower part: much safer default. - - - - - bc8de322 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: inline some 64-bit primops on x86/32-bit (#5444) Several 64-bit operation were implemented with FFI calls on 32-bit architectures but we can easily implement them with inline assembly code. Also remove unused hs_int64ToWord64 and hs_word64ToInt64 C functions. - - - - - 7b7c6b95 by Matthew Pickering at 2022-02-23T14:00:00-05:00 Simplify/correct implementation of getModuleInfo - - - - - 6215b04c by Matthew Pickering at 2022-02-23T14:00:00-05:00 Remove mg_boot field from ModuleGraph It was unused in the compiler so I have removed it to streamline ModuleGraph. - - - - - 818ff2ef by Matthew Pickering at 2022-02-23T14:00:01-05:00 driver: Remove needsTemplateHaskellOrQQ from ModuleGraph The idea of the needsTemplateHaskellOrQQ query is to check if any of the modules in a module graph need Template Haskell then enable -dynamic-too if necessary. This is quite imprecise though as it will enable -dynamic-too for all modules in the module graph even if only one module uses template haskell, with multiple home units, this is obviously even worse. With -fno-code we already have similar logic to enable code generation just for the modules which are dependeded on my TemplateHaskell modules so we use the same code path to decide whether to enable -dynamic-too rather than using this big hammer. This is part of the larger overall goal of moving as much statically known configuration into the downsweep as possible in order to have fully decided the build plan and all the options before starting to build anything. I also included a fix to #21095, a long standing bug with with the logic which is supposed to enable the external interpreter if we don't have the internal interpreter. Fixes #20696 #21095 - - - - - b6670af6 by Matthew Pickering at 2022-02-23T14:00:40-05:00 testsuite: Normalise output of ghci011 and T7627 The outputs of these tests vary on the order interface files are loaded so we normalise the output to correct for these inconsequential differences. Fixes #21121 - - - - - 9ed3bc6e by Peter Trommler at 2022-02-23T14:01:16-05:00 testsuite: Fix ipeMap test Pointers to closures must be untagged before use. Produce closures of different types so we get different info tables. Fixes #21112 - - - - - 7d426148 by Ziyang Liu at 2022-02-24T04:53:34-05:00 Allow `return` in more cases in ApplicativeDo The doc says that the last statement of an ado-block can be one of `return E`, `return $ E`, `pure E` and `pure $ E`. But `return` is not accepted in a few cases such as: ```haskell -- The ado-block only has one statement x :: F () x = do return () -- The ado-block only has let-statements besides the `return` y :: F () y = do let a = True return () ``` These currently require `Monad` instances. This MR fixes it. Normally `return` is accepted as the last statement because it is stripped in constructing an `ApplicativeStmt`, but this cannot be done in the above cases, so instead we replace `return` by `pure`. A similar but different issue (when the ado-block contains `BindStmt` or `BodyStmt`, the second last statement cannot be `LetStmt`, even if the last statement uses `pure`) is fixed in !6786. - - - - - a5ea7867 by John Ericson at 2022-02-24T20:23:49-05:00 Clarify laws of TestEquality It is unclear what `TestEquality` is for. There are 3 possible choices. Assuming ```haskell data Tag a where TagInt1 :: Tag Int TagInt2 :: Tag Int ``` Weakest -- type param equality semi-decidable --------------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params may or may not be not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Nothing -- oopsie is allowed testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` This option is better demonstrated with a different type: ```haskell data Tag' a where TagInt1 :: Tag Int TagInt2 :: Tag a ``` ```haskell instance TestEquality Tag' where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Nothing -- can't be sure testEquality TagInt2 TagInt1 = Nothing -- can't be sure testEquality TagInt2 TagInt2 = Nothing -- can't be sure ``` Weaker -- type param equality decidable --------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params are not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` Strong -- Like `Eq` ------------------- `Just Refl` means the type params are equal, and the values are equal according to `Eq`. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl testEquality _ _ = Nothing ``` Strongest -- unique value concrete type --------------------------------------- `Just Refl` means the type params are equal, and the values are equal, and the class assume if the type params are equal the values must also be equal. In other words, the type is a singleton type when the type parameter is a closed term. ```haskell -- instance TestEquality -- invalid instance because two variants for `Int` ``` ------ The discussion in https://github.com/haskell/core-libraries-committee/issues/21 has decided on the "Weaker" option (confusingly formerly called the "Weakest" option). So that is what is implemented. - - - - - 06c18990 by Zubin Duggal at 2022-02-24T20:24:25-05:00 TH: fix pretty printing of GADTs with multiple constuctors (#20842) - - - - - 6555b68c by Matthew Pickering at 2022-02-24T20:25:06-05:00 Move linters into the tree This MR moves the GHC linters into the tree, so that they can be run directly using Hadrian. * Query all files tracked by Git instead of using changed files, so that we can run the exact same linting step locally and in a merge request. * Only check that the changelogs don't contain TBA when RELEASE=YES. * Add hadrian/lint script, which runs all the linting steps. * Ensure the hlint job exits with a failure if hlint is not installed (otherwise we were ignoring the failure). Given that hlint doesn't seem to be available in CI at the moment, I've temporarily allowed failure in the hlint job. * Run all linting tests in CI using hadrian. - - - - - b99646ed by Matthew Pickering at 2022-02-24T20:25:06-05:00 Add rule for generating HsBaseConfig.h If you are running the `lint:{base/compiler}` command locally then this improves the responsiveness because we don't re-run configure everytime if the header file already exists. - - - - - d0deaaf4 by Matthew Pickering at 2022-02-24T20:25:06-05:00 Suggestions due to hlint It turns out this job hasn't been running for quite a while (perhaps ever) so there are quite a few failures when running the linter locally. - - - - - 70bafefb by nineonine at 2022-02-24T20:25:42-05:00 ghci: show helpful error message when loading module with SIMD vector operations (#20214) Previously, when trying to load module with SIMD vector operations, ghci would panic in 'GHC.StgToByteCode.findPushSeq'. Now, a more helpful message is displayed. - - - - - 8ed3d5fd by Matthew Pickering at 2022-02-25T10:24:12+00:00 Remove test-bootstrap and cabal-reinstall jobs from fast-ci [skip ci] - - - - - 8387dfbe by Mario Blažević at 2022-02-25T21:09:41-05:00 template-haskell: Fix two prettyprinter issues Fix two issues regarding printing numeric literals. Fixing #20454. - - - - - 4ad8ce0b by sheaf at 2022-02-25T21:10:22-05:00 GHCi: don't normalise partially instantiated types This patch skips performing type normalisation when we haven't fully instantiated the type. That is, in tcRnExpr (used only for :type in GHCi), skip normalisation if the result type responds True to isSigmaTy. Fixes #20974 - - - - - f35aca4d by Ben Gamari at 2022-02-25T21:10:57-05:00 rts/adjustor: Always place adjustor templates in data section @nrnrnr points out that on his machine ld.lld rejects text relocations. Generalize the Darwin text-relocation avoidance logic to account for this. - - - - - cddb040a by Andreas Klebinger at 2022-02-25T21:11:33-05:00 Ticky: Gate tag-inference dummy ticky-counters behind a flag. Tag inference included a way to collect stats about avoided tag-checks. This was dony by emitting "dummy" ticky entries with counts corresponding to predicted/unpredicated tag checks. This behaviour for ticky is now gated behind -fticky-tag-checks. I also documented ticky-LNE in the process. - - - - - 948bf2d0 by Ben Gamari at 2022-02-25T21:12:09-05:00 Fix comment reference to T4818 - - - - - 9c3edeb8 by Ben Gamari at 2022-02-25T21:12:09-05:00 simplCore: Correctly extend in-scope set in rule matching Note [Matching lets] in GHC.Core.Rules claims the following: > We use GHC.Core.Subst.substBind to freshen the binding, using an > in-scope set that is the original in-scope variables plus the > rs_bndrs (currently floated let-bindings). However, previously the implementation didn't actually do extend the in-scope set with rs_bndrs. This appears to be a regression which was introduced by 4ff4d434e9a90623afce00b43e2a5a1ccbdb4c05. Moreover, the originally reasoning was subtly wrong: we must rather use the in-scope set from rv_lcl, extended with rs_bndrs, not that of `rv_fltR` Fixes #21122. - - - - - 7f9f49c3 by sheaf at 2022-02-25T21:12:47-05:00 Derive some stock instances for OverridingBool This patch adds some derived instances to `GHC.Data.Bool.OverridingBool`. It also changes the order of the constructors, so that the derived `Ord` instance matches the behaviour for `Maybe Bool`. Fixes #20326 - - - - - 140438a8 by nineonine at 2022-02-25T21:13:23-05:00 Add test for #19271 - - - - - ac9f4606 by sheaf at 2022-02-25T21:14:04-05:00 Allow qualified names in COMPLETE pragmas The parser didn't allow qualified constructor names to appear in COMPLETE pragmas. This patch fixes that. Fixes #20551 - - - - - 677c6c91 by Sylvain Henry at 2022-02-25T21:14:44-05:00 Testsuite: remove arch conditional in T8832 Taken from !3658 - - - - - ad04953b by Sylvain Henry at 2022-02-25T21:15:23-05:00 Allow hscGenHardCode to not return CgInfos This is a minor change in preparation for the JS backend: CgInfos aren't mandatory and the JS backend won't return them. - - - - - 929c280f by Sylvain Henry at 2022-02-25T21:15:24-05:00 Derive Enum instances for CCallConv and Safety This is used by the JS backend for serialization. - - - - - 75e4e090 by Sebastian Graf at 2022-02-25T21:15:59-05:00 base: Improve documentation of `throwIO` (#19854) Now it takes a better account of precise vs. imprecise exception semantics. Fixes #19854. - - - - - 61a203ba by Matthew Pickering at 2022-02-26T02:06:51-05:00 Make typechecking unfoldings from interfaces lazier The old logic was unecessarily strict in loading unfoldings because when reading the unfolding we would case on the result of attempting to load the template before commiting to which type of unfolding we were producing. Hence trying to inspect any of the information about an unfolding would force the template to be loaded. This also removes a potentially hard to discover bug where if the template failed to be typechecked for some reason then we would just not return an unfolding. Instead we now panic so these bad situations which should never arise can be identified. - - - - - 2be74460 by Matthew Pickering at 2022-02-26T02:06:51-05:00 Use a more up-to-date snapshot of the current rules in the simplifier As the prescient (now deleted) note warns in simplifyPgmIO we have to be a bit careful about when we gather rules from the EPS so that we get the rules for imported bindings. ``` -- Get any new rules, and extend the rule base -- See Note [Overall plumbing for rules] in GHC.Core.Rules -- We need to do this regularly, because simplification can -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings ``` Given the previous commit, the loading of unfoldings is now even more delayed so we need to be more careful to read the EPS rule base closer to the point where we decide to try rules. Without this fix GHC performance regressed by a noticeably amount because the `zip` rule was not brought into scope eagerly enough which led to a further series of unfortunate events in the simplifer which tipped `substTyWithCoVars` over the edge of the size threshold, stopped it being inlined and increased allocations by 10% in some cases. Furthermore, this change is noticeably in the testsuite as it changes T19790 so that the `length` rules from GHC.List fires earlier. ------------------------- Metric Increase: T9961 ------------------------- - - - - - b8046195 by Matthew Pickering at 2022-02-26T02:06:52-05:00 Improve efficiency of extending a RuleEnv with a new RuleBase Essentially we apply the identity: > lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) > = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 The latter being more efficient as we don't construct an intermediate map. This is now quite important as each time we try and apply rules we need to combine the current EPS RuleBase with the HPT and ModGuts rule bases. - - - - - 033e9f0f by sheaf at 2022-02-26T02:07:30-05:00 Error on anon wildcards in tcAnonWildCardOcc The code in tcAnonWildCardOcc assumed that it could never encounter anonymous wildcards in illegal positions, because the renamer would have ruled them out. However, it's possible to sneak past the checks in the renamer by using Template Haskell. It isn't possible to simply pass on additional information when renaming Template Haskell brackets, because we don't know in advance in what context the bracket will be spliced in (see test case T15433b). So we accept that we might encounter these bogus wildcards in the typechecker and throw the appropriate error. This patch also migrates the error messages for illegal wildcards in types to use the diagnostic infrastructure. Fixes #15433 - - - - - 32d8fe3a by sheaf at 2022-02-26T14:15:33+01:00 Core Lint: ensure primops can be eta-expanded This patch adds a check to Core Lint, checkCanEtaExpand, which ensures that primops and other wired-in functions with no binding such as unsafeCoerce#, oneShot, rightSection... can always be eta-expanded, by checking that the remaining argument types have a fixed RuntimeRep. Two subtleties came up: - the notion of arity in Core looks through newtypes, so we may need to unwrap newtypes in this check, - we want to avoid calling hasNoBinding on something whose unfolding we are in the process of linting, as this would cause a loop; to avoid this we add some information to the Core Lint environment that holds this information. Fixes #20480 - - - - - 0a80b436 by Peter Trommler at 2022-02-26T17:21:59-05:00 testsuite: Require LLVM for T15155l - - - - - 38cb920e by Oleg Grenrus at 2022-02-28T07:14:04-05:00 Add Monoid a => Monoid (STM a) instance - - - - - d734ef8f by Hécate Moonlight at 2022-02-28T07:14:42-05:00 Make modules in base stable. fix #18963 - - - - - fbf005e9 by Sven Tennie at 2022-02-28T19:16:01-05:00 Fix some hlint issues in ghc-heap This does not fix all hlint issues as the criticised index and length expressions seem to be fine in context. - - - - - adfddf7d by Matthew Pickering at 2022-02-28T19:16:36-05:00 hadrian: Suggest to the user to run ./configure if missing a setting If a setting is missing from the configuration file it's likely the user needs to reconfigure. Fixes #20476 - - - - - 4f0208e5 by Andreas Klebinger at 2022-02-28T19:17:12-05:00 CLabel cleanup: Remove these smart constructors for these reasons: * mkLocalClosureTableLabel : Does the same as the non-local variant. * mkLocalClosureLabel : Does the same as the non-local variant. * mkLocalInfoTableLabel : Decide if we make a local label based on the name and just use mkInfoTableLabel everywhere. - - - - - 065419af by Matthew Pickering at 2022-02-28T19:17:47-05:00 linking: Don't pass --hash-size and --reduce-memory-overhead to ld These flags were added to help with the high linking cost of the old split-objs mode. Now we are using split-sections these flags appear to make no difference to memory usage or time taken to link. I tested various configurations linking together the ghc library with -split-sections enabled. | linker | time (s) | | ------ | ------ | | gold | 0.95 | | ld | 1.6 | | ld (hash-size = 31, reduce-memory-overheads) | 1.6 | | ldd | 0.47 | Fixes #20967 - - - - - 3e65ef05 by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix typo in docstring for Overlap - - - - - 80f9133e by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix docstring for Bytes It seems like a commented out section of code was accidentally included in the docstring for a field. - - - - - 54774268 by Matthew Pickering at 2022-03-01T16:23:10-05:00 Fix longstanding issue with moduleGraphNodes - no hs-boot files case In the case when we tell moduleGraphNodes to drop hs-boot files the idea is to collapse hs-boot files into their hs file nodes. In the old code * nodeDependencies changed edges from IsBoot to NonBoot * moduleGraphNodes just dropped boot file nodes The net result is that any dependencies of the hs-boot files themselves were dropped. The correct thing to do is * nodeDependencies changes edges from IsBoot to NonBoot * moduleGraphNodes merges dependencies of IsBoot and NonBoot nodes. The result is a properly quotiented dependency graph which contains no hs-boot files nor hs-boot file edges. Why this didn't cause endless issues when compiling with boot files, we will never know. - - - - - c84dc506 by Matthew Pickering at 2022-03-01T16:23:10-05:00 driver: Properly add an edge between a .hs and its hs-boot file As noted in #21071 we were missing adding this edge so there were situations where the .hs file would get compiled before the .hs-boot file which leads to issues with -j. I fixed this properly by adding the edge in downsweep so the definition of nodeDependencies can be simplified to avoid adding this dummy edge in. There are plenty of tests which seem to have these redundant boot files anyway so no new test. #21094 tracks the more general issue of identifying redundant hs-boot and SOURCE imports. - - - - - 7aeb6d29 by sheaf at 2022-03-01T16:23:51-05:00 Core Lint: collect args through floatable ticks We were not looking through floatable ticks when collecting arguments in Core Lint, which caused `checkCanEtaExpand` to fail on something like: ```haskell reallyUnsafePtrEquality = \ @a -> (src<loc> reallyUnsafePtrEquality#) @Lifted @a @Lifted @a ``` We fix this by using `collectArgsTicks tickishFloatable` instead of `collectArgs`, to be consistent with the behaviour of eta expansion outlined in Note [Eta expansion and source notes] in GHC.Core.Opt.Arity. Fixes #21152. - - - - - 75caafaa by Matthew Pickering at 2022-03-02T01:14:59-05:00 Ticky profiling improvements. This adds a number of changes to ticky-ticky profiling. When an executable is profiled with IPE profiling it's now possible to associate id-related ticky counters to their source location. This works by emitting the info table address as part of the counter which can be looked up in the IPE table. Add a `-ticky-ap-thunk` flag. This flag prevents the use of some standard thunks which are precompiled into the RTS. This means reduced cache locality and increased code size. But it allows better attribution of execution cost to specific source locations instead of simple attributing it to the standard thunk. ticky-ticky now uses the `arg` field to emit additional information about counters in json format. When ticky-ticky is used in combination with the eventlog eventlog2html can be used to generate a html table from the eventlog similar to the old text output for ticky-ticky. - - - - - aeea6bd5 by doyougnu at 2022-03-02T01:15:39-05:00 StgToCmm.cgTopBinding: no isNCG, use binBlobThresh This is a one line change. It is a fixup from MR!7325, was pointed out in review of MR!7442, specifically: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7442#note_406581 The change removes isNCG check from cgTopBinding. Instead it changes the type of binBlobThresh in DynFlags from Word to Maybe Word, where a Just 0 or a Nothing indicates an infinite threshold and thus the disable CmmFileEmbed case in the original check. This improves the cohesion of the module because more NCG related Backend stuff is moved into, and checked in, StgToCmm.Config. Note, that the meaning of a Just 0 or a Nothing in binBlobThresh is indicated in a comment next to its field in GHC.StgToCmm.Config. DynFlags: binBlobThresh: Word -> Maybe Word StgToCmm.Config: binBlobThesh add not ncg check DynFlags.binBlob: move Just 0 check to dflags init StgToCmm.binBlob: only check isNCG, Just 0 check to dflags StgToCmm.Config: strictify binBlobThresh - - - - - b27b2af3 by sheaf at 2022-03-02T14:08:36-05:00 Introduce ConcreteTv metavariables This patch introduces a new kind of metavariable, by adding the constructor `ConcreteTv` to `MetaInfo`. A metavariable with `ConcreteTv` `MetaInfo`, henceforth a concrete metavariable, can only be unified with a type that is concrete (that is, a type that answers `True` to `GHC.Core.Type.isConcrete`). This solves the problem of dangling metavariables in `Concrete#` constraints: instead of emitting `Concrete# ty`, which contains a secret existential metavariable, we simply emit a primitive equality constraint `ty ~# concrete_tv` where `concrete_tv` is a fresh concrete metavariable. This means we can avoid all the complexity of canonicalising `Concrete#` constraints, as we can just re-use the existing machinery for `~#`. To finish things up, this patch then removes the `Concrete#` special predicate, and instead introduces the special predicate `IsRefl#` which enforces that a coercion is reflexive. Such a constraint is needed because the canonicaliser is quite happy to rewrite an equality constraint such as `ty ~# concrete_tv`, but such a rewriting is not handled by the rest of the compiler currently, as we need to make use of the resulting coercion, as outlined in the FixedRuntimeRep plan. The big upside of this approach (on top of simplifying the code) is that we can now selectively implement PHASE 2 of FixedRuntimeRep, by changing individual calls of `hasFixedRuntimeRep_MustBeRefl` to `hasFixedRuntimeRep` and making use of the obtained coercion. - - - - - 81b7c436 by Matthew Pickering at 2022-03-02T14:09:13-05:00 Make -dannot-lint not panic on let bound type variables After certain simplifier passes we end up with let bound type variables which are immediately inlined in the next pass. The core diff utility implemented by -dannot-lint failed to take these into account and paniced. Progress towards #20965 - - - - - f596c91a by sheaf at 2022-03-02T14:09:51-05:00 Improve out-of-order inferred type variables Don't instantiate type variables for :type in `GHC.Tc.Gen.App.tcInstFun`, to avoid inconsistently instantianting `r1` but not `r2` in the type forall {r1} (a :: TYPE r1) {r2} (b :: TYPE r2). ... This fixes #21088. This patch also changes the primop pretty-printer to ensure that we put all the inferred type variables first. For example, the type of reallyUnsafePtrEquality# is now forall {l :: Levity} {k :: Levity} (a :: TYPE (BoxedRep l)) (b :: TYPE (BoxedRep k)). a -> b -> Int# This means we avoid running into issue #21088 entirely with the types of primops. Users can still write a type signature where the inferred type variables don't come first, however. This change to primops had a knock-on consequence, revealing that we were sometimes performing eta reduction on keepAlive#. This patch updates tryEtaReduce to avoid eta reducing functions with no binding, bringing it in line with tryEtaReducePrep, and thus fixing #21090. - - - - - 1617fed3 by Richard Eisenberg at 2022-03-02T14:10:28-05:00 Make inert_cycle_breakers into a stack. Close #20231. - - - - - c8652a0a by Richard Eisenberg at 2022-03-02T14:11:03-05:00 Make Constraint not *apart* from Type. More details in Note [coreView vs tcView] Close #21092. - - - - - 91a10cb0 by doyougnu at 2022-03-02T14:11:43-05:00 GenStgAlt 3-tuple synonym --> Record type This commit alters GenStgAlt from a type synonym to a Record with field accessors. In pursuit of #21078, this is not a required change but cleans up several areas for nicer code in the upcoming js-backend, and in GHC itself. GenStgAlt: 3-tuple -> record Stg.Utils: GenStgAlt 3-tuple -> record Stg.Stats: StgAlt 3-tuple --> record Stg.InferTags.Rewrite: StgAlt 3-tuple -> record Stg.FVs: GenStgAlt 3-tuple -> record Stg.CSE: GenStgAlt 3-tuple -> record Stg.InferTags: GenStgAlt 3-tuple --> record Stg.Debug: GenStgAlt 3-tuple --> record Stg.Lift.Analysis: GenStgAlt 3-tuple --> record Stg.Lift: GenStgAlt 3-tuple --> record ByteCode.Instr: GenStgAlt 3-tuple --> record Stg.Syntax: add GenStgAlt helper functions Stg.Unarise: GenStgAlt 3-tuple --> record Stg.BcPrep: GenStgAlt 3-tuple --> record CoreToStg: GenStgAlt 3-tuple --> record StgToCmm.Expr: GenStgAlt 3-tuple --> record StgToCmm.Bind: GenStgAlt 3-tuple --> record StgToByteCode: GenStgAlt 3-tuple --> record Stg.Lint: GenStgAlt 3-tuple --> record Stg.Syntax: strictify GenStgAlt GenStgAlt: add haddock, some cleanup fixup: remove calls to pure, single ViewPattern StgToByteCode: use case over viewpatterns - - - - - 73864f00 by Matthew Pickering at 2022-03-02T14:12:19-05:00 base: Remove default method from bitraversable The default instance leads to an infinite loop. bisequenceA is defined in terms of bisquence which is defined in terms of bitraverse. ``` bitraverse f g = (defn of bitraverse) bisequenceA . bimap f g = (defn of bisequenceA) bitraverse id id . bimap f g = (defn of bitraverse) ... ``` Any instances defined without an explicitly implementation are currently broken, therefore removing it will alert users to an issue in their code. CLC issue: https://github.com/haskell/core-libraries-committee/issues/47 Fixes #20329 #18901 - - - - - 9579bf35 by Matthew Pickering at 2022-03-02T14:12:54-05:00 ci: Add check to CI to ensure compiler uses correct BIGNUM_BACKEND - - - - - c48a7c3a by Sylvain Henry at 2022-03-03T07:37:12-05:00 Use Word64# primops in Word64 Num instance Taken froù!3658 - - - - - ce65d0cc by Matthew Pickering at 2022-03-03T07:37:48-05:00 hadrian: Correctly set whether we have a debug compiler when running tests For example, running the `slow-validate` flavour would incorrectly run the T16135 test which would fail with an assertion error, despite the fact that is should be skipped when we have a debug compiler. - - - - - e0c3e757 by Matthew Pickering at 2022-03-03T13:48:41-05:00 docs: Add note to unsafeCoerce function that you might want to use coerce [skip ci] Fixes #15429 - - - - - 559d4cf3 by Matthew Pickering at 2022-03-03T13:49:17-05:00 docs: Add note to RULES documentation about locally bound variables [skip ci] Fixes #20100 - - - - - c534b3dd by Matthew Pickering at 2022-03-03T13:49:53-05:00 Replace ad-hoc CPP with constant from GHC.Utils.Constant Fixes #21154 - - - - - de56cc7e by Krzysztof Gogolewski at 2022-03-04T12:44:26-05:00 Update documentation of LiberalTypeSynonyms We no longer require LiberalTypeSynonyms to use 'forall' or an unboxed tuple in a synonym. I also removed that kind checking before expanding synonyms "could be changed". This was true when type synonyms were thought of macros, but with the extensions such as SAKS or matchability I don't see it changing. - - - - - c0a39259 by Simon Jakobi at 2022-03-04T12:45:01-05:00 base: Mark GHC.Bits not-home for haddock Most (all) of the exports are re-exported from the preferable Data.Bits. - - - - - 3570eda5 by Sylvain Henry at 2022-03-04T12:45:42-05:00 Fix comments about Int64/Word64 primops - - - - - 6f84ee33 by Artem Pelenitsyn at 2022-03-05T01:06:47-05:00 remove MonadFail instances of ST CLC proposal: https://github.com/haskell/core-libraries-committee/issues/33 The instances had `fail` implemented in terms of `error`, whereas the idea of the `MonadFail` class is that the `fail` method should be implemented in terms of the monad itself. - - - - - 584cd5ae by sheaf at 2022-03-05T01:07:25-05:00 Don't allow Float#/Double# literal patterns This patch does the following two things: 1. Fix the check in Core Lint to properly throw an error when it comes across Float#/Double# literal patterns. The check was incorrect before, because it expected the type to be Float/Double instead of Float#/Double#. 2. Add an error in the parser when the user writes a floating-point literal pattern such as `case x of { 2.0## -> ... }`. Fixes #21115 - - - - - 706deee0 by Greg Steuck at 2022-03-05T17:44:10-08:00 Make T20214 terminate promptly be setting input to /dev/null It was hanging and timing out on OpenBSD before. - - - - - 14e90098 by Simon Peyton Jones at 2022-03-07T14:05:41-05:00 Always generalise top-level bindings Fix #21023 by always generalising top-level binding; change the documentation of -XMonoLocalBinds to match. - - - - - c9c31c3c by Matthew Pickering at 2022-03-07T14:06:16-05:00 hadrian: Add little flavour transformer to build stage2 with assertions This can be useful to build a `perf+assertions` build or even better `default+no_profiled_libs+omit_pragmas+assertions`. - - - - - 89c14a6c by Matthew Pickering at 2022-03-07T14:06:16-05:00 ci: Convert all deb10 make jobs into hadrian jobs This is the first step in converting all the CI configs to use hadrian rather than make. (#21129) The metrics increase due to hadrian using --hyperlinked-source for haddock builds. (See #21156) ------------------------- Metric Increase: haddock.Cabal haddock.base haddock.compiler ------------------------- - - - - - 7bfae2ee by Matthew Pickering at 2022-03-07T14:06:16-05:00 Replace use of BIN_DIST_PREP_TAR_COMP with BIN_DIST_NAME And adds a check to make sure we are not accidently settings BIN_DIST_PREP_TAR_COMP when using hadrian. - - - - - 5b35ca58 by Matthew Pickering at 2022-03-07T14:06:16-05:00 Fix gen_contents_index logic for hadrian bindist - - - - - 273bc133 by Krzysztof Gogolewski at 2022-03-07T14:06:52-05:00 Fix reporting constraints in pprTcSolverReportMsg 'no_instance_msg' and 'no_deduce_msg' were omitting the first wanted. - - - - - 5874a30a by Simon Jakobi at 2022-03-07T14:07:28-05:00 Improve setBit for Natural Previously the default definition was used, which involved allocating intermediate Natural values. Fixes #21173. - - - - - 7a02aeb8 by Matthew Pickering at 2022-03-07T14:08:03-05:00 Remove leftover trace in testsuite - - - - - 6ce6c250 by Andreas Klebinger at 2022-03-07T23:48:56-05:00 Expand and improve the Note [Strict Worker Ids]. I've added an explicit mention of the invariants surrounding those. As well as adding more direct cross references to the Strict Field Invariant. - - - - - d0f892fe by Ryan Scott at 2022-03-07T23:49:32-05:00 Delete GenericKind_ in favor of GenericKind_DC When deriving a `Generic1` instance, we need to know what the last type variable of a data type is. Previously, there were two mechanisms to determine this information: * `GenericKind_`, where `Gen1_` stored the last type variable of a data type constructor (i.e., the `tyConTyVars`). * `GenericKind_DC`, where `Gen1_DC` stored the last universally quantified type variable in a data constructor (i.e., the `dataConUnivTyVars`). These had different use cases, as `GenericKind_` was used for generating `Rep(1)` instances, while `GenericKind_DC` was used for generating `from(1)` and `to(1)` implementations. This was already a bit confusing, but things went from confusing to outright wrong after !6976. This is because after !6976, the `deriving` machinery stopped using `tyConTyVars` in favor of `dataConUnivTyVars`. Well, everywhere with the sole exception of `GenericKind_`, which still continued to use `tyConTyVars`. This lead to disaster when deriving a `Generic1` instance for a GADT family instance, as the `tyConTyVars` do not match the `dataConUnivTyVars`. (See #21185.) The fix is to stop using `GenericKind_` and replace it with `GenericKind_DC`. For the most part, this proves relatively straightforward. Some highlights: * The `forgetArgVar` function was deleted entirely, as it no longer proved necessary after `GenericKind_`'s demise. * The substitution that maps from the last type variable to `Any` (see `Note [Generating a correctly typed Rep instance]`) had to be moved from `tc_mkRepTy` to `tc_mkRepFamInsts`, as `tc_mkRepTy` no longer has access to the last type variable. Fixes #21185. - - - - - a60ddffd by Matthew Pickering at 2022-03-08T22:51:37+00:00 Move bootstrap and cabal-reinstall test jobs to nightly CI is creaking under the pressure of too many jobs so attempt to reduce the strain by removing a couple of jobs. - - - - - 7abe3288 by Matthew Pickering at 2022-03-09T10:24:15+00:00 Add 10 minute timeout to linters job - - - - - 3cf75ede by Matthew Pickering at 2022-03-09T10:24:16+00:00 Revert "hadrian: Correctly set whether we have a debug compiler when running tests" Needing the arguments for "GHC/Utils/Constant.hs" implies a dependency on the previous stage compiler. Whilst we work out how to get around this I will just revert this commit (as it only affects running the testsuite in debug way). This reverts commit ce65d0cceda4a028f30deafa3c39d40a250acc6a. - - - - - 18b9ba56 by Matthew Pickering at 2022-03-09T11:07:23+00:00 ci: Fix save_cache function Each interation of saving the cache would copy the whole `cabal` store into a subfolder in the CACHE_DIR rather than copying the contents of the cabal store into the cache dir. This resulted in a cache which looked like: ``` /builds/ghc/ghc/cabal-cache/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/ ``` So it would get one layer deeper every CI run and take longer and longer to compress. - - - - - bc684dfb by Ben Gamari at 2022-03-10T03:20:07-05:00 mr-template: Mention timeframe for review - - - - - 7f5f4ede by Vladislav Zavialov at 2022-03-10T03:20:43-05:00 Bump submodules: containers, exceptions GHC Proposal #371 requires TypeOperators to use type equality a~b. This submodule update pulls in the appropriate forward-compatibility changes in 'libraries/containers' and 'libraries/exceptions' - - - - - 8532b8a9 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Add an inline pragma to lookupVarEnv The containers bump reduced the size of the Data.IntMap.Internal.lookup function so that it no longer experienced W/W. This means that the size of lookupVarEnv increased over the inlining threshold and it wasn't inlined into the hot code path in substTyVar. See containers#821, #21159 and !7638 for some more explanation. ------------------------- Metric Decrease: LargeRecord T12227 T13386 T15703 T18223 T5030 T8095 T9872a T9872b T9872c TcPlugin_RewritePerf ------------------------- - - - - - 844cf1e1 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Normalise output of T10970 test The output of this test changes each time the containers submodule version updates. It's easier to apply the version normaliser so that the test checks that there is a version number, but not which one it is. - - - - - 24b6af26 by Ryan Scott at 2022-03-11T19:56:28-05:00 Refactor tcDeriving to generate tyfam insts before any bindings Previously, there was an awful hack in `genInst` (now called `genInstBinds` after this patch) where we had to return a continutation rather than directly returning the bindings for a derived instance. This was done for staging purposes, as we had to first infer the instance contexts for derived instances and then feed these contexts into the continuations to ensure the generated instance bindings had accurate instance contexts. `Note [Staging of tcDeriving]` in `GHC.Tc.Deriving` described this confusing state of affairs. The root cause of this confusing design was the fact that `genInst` was trying to generate instance bindings and associated type family instances for derived instances simultaneously. This really isn't possible, however: as `Note [Staging of tcDeriving]` explains, one needs to have access to the associated type family instances before one can properly infer the instance contexts for derived instances. The use of continuation-returning style was an attempt to circumvent this dependency, but it did so in an awkward way. This patch detangles this awkwardness by splitting up `genInst` into two functions: `genFamInsts` (for associated type family instances) and `genInstBinds` (for instance bindings). Now, the `tcDeriving` function calls `genFamInsts` and brings all the family instances into scope before calling `genInstBinds`. This removes the need for the awkward continuation-returning style seen in the previous version of `genInst`, making the code easier to understand. There are some knock-on changes as well: 1. `hasStockDeriving` now needs to return two separate functions: one that describes how to generate family instances for a stock-derived instance, and another that describes how to generate the instance bindings. I factored out this pattern into a new `StockGenFns` data type. 2. While documenting `StockGenFns`, I realized that there was some inconsistency regarding which `StockGenFns` functions needed which arguments. In particular, the function in `GHC.Tc.Deriv.Generics` which generates `Rep(1)` instances did not take a `SrcSpan` like other `gen_*` functions did, and it included an extra `[Type]` argument that was entirely redundant. As a consequence, I refactored the code in `GHC.Tc.Deriv.Generics` to more closely resemble other `gen_*` functions. A happy result of all this is that all `StockGenFns` functions now take exactly the same arguments, which makes everything more uniform. This is purely a refactoring that should not have any effect on user-observable behavior. The new design paves the way for an eventual fix for #20719. - - - - - 62caaa9b by Ben Gamari at 2022-03-11T19:57:03-05:00 gitlab-ci: Use the linters image in hlint job As the `hlint` executable is only available in the linters image. Fixes #21146. - - - - - 4abd7eb0 by Matthew Pickering at 2022-03-11T19:57:38-05:00 Remove partOfGhci check in the loader This special logic has been part of GHC ever since template haskell was introduced in 9af77fa423926fbda946b31e174173d0ec5ebac8. It's hard to believe in any case that this special logic pays its way at all. Given * The list is out-of-date, which has potential to lead to miscompilation when using "editline", which was removed in 2010 (46aed8a4). * The performance benefit seems negligable as each load only happens once anyway and packages specified by package flags are preloaded into the linker state at the start of compilation. Therefore we just remove this logic. Fixes #19791 - - - - - c40cbaa2 by Andreas Klebinger at 2022-03-11T19:58:14-05:00 Improve -dtag-inference-checks checks. FUN closures don't get tagged when evaluated. So no point in checking their tags. - - - - - ab00d23b by Simon Jakobi at 2022-03-11T19:58:49-05:00 Improve clearBit and complementBit for Natural Also optimize bigNatComplementBit#. Fixes #21175, #21181, #21194. - - - - - a6d8facb by Sebastian Graf at 2022-03-11T19:59:24-05:00 gitignore all (build) directories headed by _ - - - - - 524795fe by Sebastian Graf at 2022-03-11T19:59:24-05:00 Demand: Document why we need three additional equations of multSubDmd - - - - - 6bdcd557 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make 64-bit word splitting for 32-bit targets respect target endianness This used to been broken for little-endian targets. - - - - - 9e67c69e by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix Double# literal payload for 32-bit targets Contrary to the legacy comment, the splitting didn't happen and we ended up with a single StgWord64 literal in the output code! Let's just do the splitting here. - - - - - 1eee2e28 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: use __builtin versions of memcpyish functions to fix type mismatch Our memcpyish primop's type signatures doesn't match the C type signatures. It's not a problem for typical archs, since their C ABI permits dropping the result, but it doesn't work for wasm. The previous logic would cast the memcpyish function pointer to an incorrect type and perform an indirect call, which results in a runtime trap on wasm. The most straightforward fix is: don't emit EFF_ for memcpyish functions. Since we don't want to include extra headers in .hc to bring in their prototypes, we can just use the __builtin versions. - - - - - 9d8d4837 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: emit __builtin_unreachable() when CmmSwitch doesn't contain fallback case Otherwise the C compiler may complain "warning: non-void function does not return a value in all control paths [-Wreturn-type]". - - - - - 27da5540 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make floatToWord32/doubleToWord64 faster Use castFloatToWord32/castDoubleToWord64 in base to perform the reinterpret cast. - - - - - c98e8332 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix -Wunused-value warning in ASSIGN_BaseReg When ASSIGN_BaseReg is a no-op, we shouldn't generate any C code, otherwise C compiler complains a bunch of -Wunused-value warnings when doing unregisterised codegen. - - - - - 5932247c by Ben Gamari at 2022-03-11T20:00:36-05:00 users guide: Eliminate spurious \spxentry mentions We were failing to pass the style file to `makeindex`, as is done by the mklatex configuration generated by Sphinx. Fixes #20913. - - - - - e40cf4ef by Simon Jakobi at 2022-03-11T20:01:11-05:00 ghc-bignum: Tweak integerOr The result of ORing two BigNats is always greater or equal to the larger of the two. Therefore it is safe to skip the magnitude checks of integerFromBigNat#. - - - - - cf081476 by Vladislav Zavialov at 2022-03-12T07:02:40-05:00 checkUnboxedLitPat: use non-fatal addError This enables GHC to report more parse errors in a single pass. - - - - - 7fe07143 by Andreas Klebinger at 2022-03-12T07:03:16-05:00 Rename -fprof-late-ccs to -fprof-late - - - - - 88a94541 by Sylvain Henry at 2022-03-12T07:03:56-05:00 Hadrian: avoid useless allocations in trackArgument Cf ticky report before the change: Entries Alloc Alloc'd Non-void Arguments STG Name -------------------------------------------------------------------------------- 696987 29044128 0 1 L main:Target.trackArgument_go5{v r24kY} (fun) - - - - - 2509d676 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: avoid allocating in stageString (#19209) - - - - - c062fac0 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: remove useless imports Added for no reason in 7ce1b694f7be7fbf6e2d7b7eb0639e61fbe358c6 - - - - - c82fb934 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: avoid allocations in WayUnit's Read instance (#19209) - - - - - ed04aed2 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: use IntSet Binary instance for Way (#19209) - - - - - ad835531 by Simon Peyton Jones at 2022-03-13T18:12:12-04:00 Fix bug in weak loop-breakers in OccurAnal Note [Weak loop breakers] explains why we need to track variables free in RHS of rules. But we need to do this for /inactive/ rules as well as active ones, unlike the rhs_fv_env stuff. So we now have two fields in node Details, one for free vars of active rules, and one for free vars of all rules. This was shown up by #20820, which is now fixed. - - - - - 76b94b72 by Sebastian Graf at 2022-03-13T18:12:48-04:00 Worker/wrapper: Preserve float barriers (#21150) Issue #21150 shows that worker/wrapper allocated a worker function for a function with multiple calls that said "called at most once" when the first argument was absent. That's bad! This patch makes it so that WW preserves at least one non-one-shot value lambda (see `Note [Preserving float barriers]`) by passing around `void#` in place of absent arguments. Fixes #21150. Since the fix is pretty similar to `Note [Protecting the last value argument]`, I put the logic in `mkWorkerArgs`. There I realised (#21204) that `-ffun-to-thunk` is basically useless with `-ffull-laziness`, so I deprecated the flag, simplified and split into `needsVoidWorkerArg`/`addVoidWorkerArg`. SpecConstr is another client of that API. Fixes #21204. Metric Decrease: T14683 - - - - - 97db789e by romes at 2022-03-14T11:36:39-04:00 Fix up Note [Bind free vars] Move GHC-specific comments from Language.Haskell.Syntax.Binds to GHC.Hs.Binds It looks like the Note was deleted but there were actually two copies of it. L.H.S.B no longer references it, and GHC.Hs.Binds keeps an updated copy. (See #19252) There are other duplicated notes -- they will be fixed in the next commit - - - - - 135888dd by romes at 2022-03-14T11:36:39-04:00 TTG Pull AbsBinds and ABExport out of the main AST AbsBinds and ABExport both depended on the typechecker, and were thus removed from the main AST Expr. CollectPass now has a new function `collectXXHsBindsLR` used for the new HsBinds extension point Bumped haddock submodule to work with AST changes. The removed Notes from Language.Haskell.Syntax.Binds were duplicated (and not referenced) and the copies in GHC.Hs.Binds are kept (and referenced there). (See #19252) - - - - - 106413f0 by sheaf at 2022-03-14T11:37:21-04:00 Add two coercion optimisation perf tests - - - - - 8eadea67 by sheaf at 2022-03-14T15:08:24-04:00 Fix isLiftedType_maybe and handle fallout As #20837 pointed out, `isLiftedType_maybe` returned `Just False` in many situations where it should return `Nothing`, because it didn't take into account type families or type variables. In this patch, we fix this issue. We rename `isLiftedType_maybe` to `typeLevity_maybe`, which now returns a `Levity` instead of a boolean. We now return `Nothing` for types with kinds of the form `TYPE (F a1 ... an)` for a type family `F`, as well as `TYPE (BoxedRep l)` where `l` is a type variable. This fix caused several other problems, as other parts of the compiler were relying on `isLiftedType_maybe` returning a `Just` value, and were now panicking after the above fix. There were two main situations in which panics occurred: 1. Issues involving the let/app invariant. To uphold that invariant, we need to know whether something is lifted or not. If we get an answer of `Nothing` from `isLiftedType_maybe`, then we don't know what to do. As this invariant isn't particularly invariant, we can change the affected functions to not panic, e.g. by behaving the same in the `Just False` case and in the `Nothing` case (meaning: no observable change in behaviour compared to before). 2. Typechecking of data (/newtype) constructor patterns. Some programs involving patterns with unknown representations were accepted, such as T20363. Now that we are stricter, this caused further issues, culminating in Core Lint errors. However, the behaviour was incorrect the whole time; the incorrectness only being revealed by this change, not triggered by it. This patch fixes this by overhauling where the representation polymorphism involving pattern matching are done. Instead of doing it in `tcMatches`, we instead ensure that the `matchExpected` functions such as `matchExpectedFunTys`, `matchActualFunTySigma`, `matchActualFunTysRho` allow return argument pattern types which have a fixed RuntimeRep (as defined in Note [Fixed RuntimeRep]). This ensures that the pattern matching code only ever handles types with a known runtime representation. One exception was that patterns with an unknown representation type could sneak in via `tcConPat`, which points to a missing representation-polymorphism check, which this patch now adds. This means that we now reject the program in #20363, at least until we implement PHASE 2 of FixedRuntimeRep (allowing type families in RuntimeRep positions). The aforementioned refactoring, in which checks have been moved to `matchExpected` functions, is a first step in implementing PHASE 2 for patterns. Fixes #20837 - - - - - 8ff32124 by Sebastian Graf at 2022-03-14T15:09:01-04:00 DmdAnal: Don't unbox recursive data types (#11545) As `Note [Demand analysis for recursive data constructors]` describes, we now refrain from unboxing recursive data type arguments, for two reasons: 1. Relating to run/alloc perf: Similar to `Note [CPR for recursive data constructors]`, it seldomly improves run/alloc performance if we just unbox a finite number of layers of a potentially huge data structure. 2. Relating to ghc/alloc perf: Inductive definitions on single-product recursive data types like the one in T11545 will (diverge, and) have very deep demand signatures before any other abortion mechanism in Demand analysis is triggered. That leads to great and unnecessary churn on Demand analysis when ultimately we will never make use of any nested strictness information anyway. Conclusion: Discard nested demand and boxity information on such recursive types with the help of `Note [Detecting recursive data constructors]`. I also implemented `GHC.Types.Unique.MemoFun.memoiseUniqueFun` in order to avoid the overhead of repeated calls to `GHC.Core.Opt.WorkWrap.Utils.isRecDataCon`. It's nice and simple and guards against some smaller regressions in T9233 and T16577. ghc/alloc performance-wise, this patch is a very clear win: Test Metric value New value Change --------------------------------------------------------------------------------------- LargeRecord(normal) ghc/alloc 6,141,071,720 6,099,871,216 -0.7% MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,740,973,040 2,705,146,640 -1.3% T11545(normal) ghc/alloc 945,475,492 85,768,928 -90.9% GOOD T13056(optasm) ghc/alloc 370,245,880 326,980,632 -11.7% GOOD T18304(normal) ghc/alloc 90,933,944 76,998,064 -15.3% GOOD T9872a(normal) ghc/alloc 1,800,576,840 1,792,348,760 -0.5% T9872b(normal) ghc/alloc 2,086,492,432 2,073,991,848 -0.6% T9872c(normal) ghc/alloc 1,750,491,240 1,737,797,832 -0.7% TcPlugin_RewritePerf(normal) ghc/alloc 2,286,813,400 2,270,957,896 -0.7% geo. mean -2.9% No noteworthy change in run/alloc either. NoFib results show slight wins, too: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- constraints -1.9% -1.4% fasta -3.6% -2.7% reverse-complem -0.3% -0.9% treejoin -0.0% -0.3% -------------------------------------------------------------------------------- Min -3.6% -2.7% Max +0.1% +0.1% Geometric Mean -0.1% -0.1% Metric Decrease: T11545 T13056 T18304 - - - - - ab618309 by Vladislav Zavialov at 2022-03-15T18:34:38+03:00 Export (~) from Data.Type.Equality (#18862) * Users can define their own (~) type operator * Haddock can display documentation for the built-in (~) * New transitional warnings implemented: -Wtype-equality-out-of-scope -Wtype-equality-requires-operators Updates the haddock submodule. - - - - - 577135bf by Aaron Allen at 2022-03-16T02:27:48-04:00 Convert Diagnostics in GHC.Tc.Gen.Foreign Converts all uses of 'TcRnUnknownMessage' to proper diagnostics. - - - - - c1fed9da by Aaron Allen at 2022-03-16T02:27:48-04:00 Suggest FFI extensions as hints (#20116) - Use extension suggestion hints instead of suggesting extensions in the error message body for several FFI errors. - Adds a test case for `TcRnForeignImportPrimExtNotSet` - - - - - a33d1045 by Zubin Duggal at 2022-03-16T02:28:24-04:00 TH: allow negative patterns in quotes (#20711) We still don't allow negative overloaded patterns. Earler all negative patterns were treated as negative overloaded patterns. Now, we expliclty check the extension field to see if the pattern is actually a negative overloaded pattern - - - - - 1575c4a5 by Sebastian Graf at 2022-03-16T02:29:03-04:00 Demand: Let `Boxed` win in `lubBoxity` (#21119) Previously, we let `Unboxed` win in `lubBoxity`, which is unsoundly optimistic in terms ob Boxity analysis. "Unsoundly" in the sense that we sometimes unbox parameters that we better shouldn't unbox. Examples are #18907 and T19871.absent. Until now, we thought that this hack pulled its weight becuase it worked around some shortcomings of the phase separation between Boxity analysis and CPR analysis. But it is a gross hack which caused regressions itself that needed all kinds of fixes and workarounds. See for example #20767. It became impossible to work with in !7599, so I want to remove it. For example, at the moment, `lubDmd B dmd` will not unbox `dmd`, but `lubDmd A dmd` will. Given that `B` is supposed to be the bottom element of the lattice, it's hardly justifiable to get a better demand when `lub`bing with `A`. The consequence of letting `Boxed` win in `lubBoxity` is that we *would* regress #2387, #16040 and parts of #5075 and T19871.sumIO, until Boxity and CPR are able to communicate better. Fortunately, that is not the case since I could tweak the other source of optimism in Boxity analysis that is described in `Note [Unboxed demand on function bodies returning small products]` so that we *recursively* assume unboxed demands on function bodies returning small products. See the updated Note. `Note [Boxity for bottoming functions]` describes why we need bottoming functions to have signatures that say that they deeply unbox their arguments. In so doing, I had to tweak `finaliseArgBoxities` so that it will never unbox recursive data constructors. This is in line with our handling of them in CPR. I updated `Note [Which types are unboxed?]` to reflect that. In turn we fix #21119, #20767, #18907, T19871.absent and get a much simpler implementation (at least to think about). We can also drop the very ad-hoc definition of `deferAfterPreciseException` and its Note in favor of the simple, intuitive definition we used to have. Metric Decrease: T16875 T18223 T18698a T18698b hard_hole_fits Metric Increase: LargeRecord MultiComponentModulesRecomp T15703 T8095 T9872d Out of all the regresions, only the one in T9872d doesn't vanish in a perf build, where the compiler is bootstrapped with -O2 and thus SpecConstr. Reason for regressions: * T9872d is due to `ty_co_subst` taking its `LiftingContext` boxed. That is because the context is passed to a function argument, for example in `liftCoSubstTyVarBndrUsing`. * In T15703, LargeRecord and T8095, we get a bit more allocations in `expand_syn` and `piResultTys`, because a `TCvSubst` isn't unboxed. In both cases that guards against reboxing in some code paths. * The same is true for MultiComponentModulesRecomp, where we get less unboxing in `GHC.Unit.Finder.$wfindInstalledHomeModule`. In a perf build, allocations actually *improve* by over 4%! Results on NoFib: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- awards -0.4% +0.3% cacheprof -0.3% +2.4% fft -1.5% -5.1% fibheaps +1.2% +0.8% fluid -0.3% -0.1% ida +0.4% +0.9% k-nucleotide +0.4% -0.1% last-piece +10.5% +13.9% lift -4.4% +3.5% mandel2 -99.7% -99.8% mate -0.4% +3.6% parser -1.0% +0.1% puzzle -11.6% +6.5% reverse-complem -3.0% +2.0% scs -0.5% +0.1% sphere -0.4% -0.2% wave4main -8.2% -0.3% -------------------------------------------------------------------------------- Summary excludes mandel2 because of excessive bias Min -11.6% -5.1% Max +10.5% +13.9% Geometric Mean -0.2% +0.3% -------------------------------------------------------------------------------- Not bad for a bug fix. The regression in `last-piece` could become a win if SpecConstr would work on non-recursive functions. The regression in `fibheaps` is due to `Note [Reboxed crud for bottoming calls]`, e.g., #21128. - - - - - bb779b90 by sheaf at 2022-03-16T02:29:42-04:00 Add a regression test for #21130 This problem was due to a bug in cloneWanted, which was incorrectly creating a coercion hole to hold an evidence variable. This bug was introduced by 8bb52d91 and fixed in 81740ce8. Fixes #21130 - - - - - 0f0e2394 by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Initial Windows C++ exception unwinding support - - - - - 36d20d4d by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Fix ADDR32NB relocations on Windows - - - - - 8a516527 by Tamar Christina at 2022-03-17T10:16:37-04:00 testsuite: properly escape string paths - - - - - 1a0dd008 by sheaf at 2022-03-17T10:17:13-04:00 Hadrian: account for change in late-ccs flag The late cost centre flag was renamed from -fprof-late-ccs to -fprof-late in 7fe07143, but this change hadn't been propagated to Hadrian. - - - - - 8561c1af by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor HsBracket - - - - - 19163397 by romes at 2022-03-18T05:10:58-04:00 Type-checking untyped brackets When HsExpr GhcTc, the HsBracket constructor should hold a HsBracket GhcRn, rather than an HsBracket GhcTc. We make use of the HsBracket p extension constructor (XBracket (XXBracket p)) to hold an HsBracket GhcRn when the pass is GhcTc See !4782 https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - 310890a5 by romes at 2022-03-18T05:10:58-04:00 Separate constructors for typed and untyped brackets Split HsBracket into HsTypedBracket and HsUntypedBracket. Unfortunately, we still cannot get rid of instance XXTypedBracket GhcTc = HsTypedBracket GhcRn despite no longer requiring it for typechecking, but rather because the TH desugarer works on GhcRn rather than GhcTc (See GHC.HsToCore.Quote) - - - - - 4a2567f5 by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor bracket for desugaring during tc When desugaring a bracket we want to desugar /renamed/ rather than /typechecked/ code; So in (HsExpr GhcTc) tree, we must have a (HsExpr GhcRn) for the quotation itself. This commit reworks the TTG refactor on typed and untyped brackets by storing the /renamed/ code in the bracket field extension rather than in the constructor extension in `HsQuote` (previously called `HsUntypedBracket`) See Note [The life cycle of a TH quotation] and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - b056adc8 by romes at 2022-03-18T05:10:58-04:00 TTG: Make HsQuote GhcTc isomorphic to NoExtField An untyped bracket `HsQuote p` can never be constructed with `p ~ GhcTc`. This is because we don't typecheck `HsQuote` at all. That's OK, because we also never use `HsQuote GhcTc`. To enforce this at the type level we make `HsQuote GhcTc` isomorphic to `NoExtField` and impossible to construct otherwise, by using TTG field extensions to make all constructors, except for `XQuote` (which takes `NoExtField`), unconstructable, with `DataConCantHappen` This is explained more in detail in Note [The life cycle of a TH quotation] Related discussion: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - ac3b2e7d by romes at 2022-03-18T05:10:58-04:00 TTG: TH brackets finishing touches Rewrite the critical notes and fix outdated ones, use `HsQuote GhcRn` (in `HsBracketTc`) for desugaring regardless of the bracket being typed or untyped, remove unused `EpAnn` from `Hs*Bracket GhcRn`, zonkExpr factor out common brackets code, ppr_expr factor out common brackets code, and fix tests, to finish MR https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782. ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - d147428a by Ben Gamari at 2022-03-18T05:11:35-04:00 codeGen: Fix signedness of jump table indexing Previously while constructing the jump table index we would zero-extend the discriminant before subtracting the start of the jump-table. This goes subtly wrong in the case of a sub-word, signed discriminant, as described in the included Note. Fix this in both the PPC and X86 NCGs. Fixes #21186. - - - - - 435a3d5d by Ben Gamari at 2022-03-18T05:11:35-04:00 testsuite: Add test for #21186 - - - - - e9d8de93 by Zubin Duggal at 2022-03-19T07:35:49-04:00 TH: Fix pretty printing of newtypes with operators and GADT syntax (#20868) The pretty printer for regular data types already accounted for these, and had some duplication with the newtype pretty printer. Factoring the logic out into a common function and using it for both newtypes and data declarations is enough to fix the bug. - - - - - 244da9eb by sheaf at 2022-03-19T07:36:24-04:00 List GHC.Event.Internal in base.cabal on Windows GHC.Event.Internal was not listed in base.cabal on Windows. This caused undefined reference errors. This patch adds it back, by moving it out of the OS-specific logic in base.cabal. Fixes #21245. - - - - - d1c03719 by Andreas Klebinger at 2022-03-19T07:37:00-04:00 Compact regions: Maintain tags properly Fixes #21251 - - - - - d45bb701 by romes at 2022-03-19T07:37:36-04:00 Remove dead code HsDoRn - - - - - c842611f by nineonine at 2022-03-20T21:16:06-04:00 Revamp derived Eq instance code generation (#17240) This patch improves code generation for derived Eq instances. The idea is to use 'dataToTag' to evaluate both arguments. This allows to 'short-circuit' when tags do not match. Unfortunately, inner evals are still present when we branch on tags. This is due to the way 'dataToTag#' primop evaluates its argument in the code generator. #21207 was created to explore further optimizations. Metric Decrease: LargeRecord - - - - - 52ffd38c by Sylvain Henry at 2022-03-20T21:16:46-04:00 Avoid some SOURCE imports - - - - - b91798be by Zubin Duggal at 2022-03-23T13:39:39-04:00 hi haddock: Lex and store haddock docs in interface files Names appearing in Haddock docstrings are lexed and renamed like any other names appearing in the AST. We currently rename names irrespective of the namespace, so both type and constructor names corresponding to an identifier will appear in the docstring. Haddock will select a given name as the link destination based on its own heuristics. This patch also restricts the limitation of `-haddock` being incompatible with `Opt_KeepRawTokenStream`. The export and documenation structure is now computed in GHC and serialised in .hi files. This can be used by haddock to directly generate doc pages without reparsing or renaming the source. At the moment the operation of haddock is not modified, that's left to a future patch. Updates the haddock submodule with the minimum changes needed. - - - - - 78db231f by Cheng Shao at 2022-03-23T13:40:17-04:00 configure: bump LlvmMaxVersion to 14 LLVM 13.0.0 is released in Oct 2021, and latest head validates against LLVM 13 just fine if LlvmMaxVersion is bumped. - - - - - b06e5dd8 by Adam Sandberg Ericsson at 2022-03-23T13:40:54-04:00 docs: clarify the eventlog format documentation a little bit - - - - - 4dc62498 by Matthew Pickering at 2022-03-23T13:41:31-04:00 Fix behaviour of -Wunused-packages in ghci Ticket #21110 points out that -Wunused-packages behaves a bit unusually in GHCi. Now we define the semantics for -Wunused-packages in interactive mode as follows: * If you use -Wunused-packages on an initial load then the warning is reported. * If you explicitly set -Wunused-packages on the command line then the warning is displayed (until it is disabled) * If you then subsequently modify the set of available targets by using :load or :cd (:cd unloads everything) then the warning is (silently) turned off. This means that every :r the warning is printed if it's turned on (but you did ask for it). Fixes #21110 - - - - - fed05347 by Ben Gamari at 2022-03-23T13:42:07-04:00 rts/adjustor: Place adjustor templates in data section on all OSs In !7604 we started placing adjustor templates in the data section on Linux as some toolchains there reject relocations in the text section. However, it turns out that OpenBSD also exhibits this restriction. Fix this by *always* placing adjustor templates in the data section. Fixes #21155. - - - - - db32bb8c by Zubin Duggal at 2022-03-23T13:42:44-04:00 Improve error message when warning about unsupported LLVM version (#20958) Change the wording to make it clear that the upper bound is non-inclusive. - - - - - f214349a by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Untag function field in scavenge_PAP_payload Previously we failed to untag the function closure when scavenging the payload of a PAP, resulting in an invalid closure pointer being passed to scavenge_large_bitmap and consequently #21254. Fix this. Fixes #21254 - - - - - e6d0e287 by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Don't mark object code in markCAFs unless necessary Previously `markCAFs` would call `markObjectCode` even in non-major GCs. This is problematic since `prepareUnloadCheck` is not called in such GCs, meaning that the section index has not been updated. Fixes #21254 - - - - - 1a7cf096 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Avoid redundant imports of GHC.Driver.Session Remove GHC.Driver.Session imports that weren't considered as redundant because of the reexport of PlatformConstants. Also remove this reexport as modules using this datatype should import GHC.Platform instead. - - - - - e3f60577 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Reverse dependency between StgToCmm and Runtime.Heap.Layout - - - - - e6585ca1 by Sylvain Henry at 2022-03-23T13:44:46-04:00 Define filterOut with filter filter has fusion rules that filterOut lacks - - - - - c58d008c by Ryan Scott at 2022-03-24T06:10:43-04:00 Fix and simplify DeriveAnyClass's context inference using SubTypePredSpec As explained in `Note [Gathering and simplifying constraints for DeriveAnyClass]` in `GHC.Tc.Deriv.Infer`, `DeriveAnyClass` infers instance contexts by emitting implication constraints. Previously, these implication constraints were constructed by hand. This is a terribly trick thing to get right, as it involves a delicate interplay of skolemisation, metavariable instantiation, and `TcLevel` bumping. Despite much effort, we discovered in #20719 that the implementation was subtly incorrect, leading to valid programs being rejected. While we could scrutinize the code that manually constructs implication constraints and repair it, there is a better, less error-prone way to do things. After all, the heart of `DeriveAnyClass` is generating code which fills in each class method with defaults, e.g., `foo = $gdm_foo`. Typechecking this sort of code is tantamount to calling `tcSubTypeSigma`, as we much ensure that the type of `$gdm_foo` is a subtype of (i.e., more polymorphic than) the type of `foo`. As an added bonus, `tcSubTypeSigma` is a battle-tested function that handles skolemisation, metvariable instantiation, `TcLevel` bumping, and all other means of tricky bookkeeping correctly. With this insight, the solution to the problems uncovered in #20719 is simple: use `tcSubTypeSigma` to check if `$gdm_foo`'s type is a subtype of `foo`'s type. As a side effect, `tcSubTypeSigma` will emit exactly the implication constraint that we were attempting to construct by hand previously. Moreover, it does so correctly, fixing #20719 as a consequence. This patch implements the solution thusly: * The `PredSpec` data type (previously named `PredOrigin`) is now split into `SimplePredSpec`, which directly stores a `PredType`, and `SubTypePredSpec`, which stores the actual and expected types in a subtype check. `SubTypePredSpec` is only used for `DeriveAnyClass`; all other deriving strategies use `SimplePredSpec`. * Because `tcSubTypeSigma` manages the finer details of type variable instantiation and constraint solving under the hood, there is no longer any need to delicately split apart the method type signatures in `inferConstraintsAnyclass`. This greatly simplifies the implementation of `inferConstraintsAnyclass` and obviates the need to store skolems, metavariables, or given constraints in a `ThetaSpec` (previously named `ThetaOrigin`). As a bonus, this means that `ThetaSpec` now simply becomes a synonym for a list of `PredSpec`s, which is conceptually much simpler than it was before. * In `simplifyDeriv`, each `SubTypePredSpec` results in a call to `tcSubTypeSigma`. This is only performed for its side effect of emitting an implication constraint, which is fed to the rest of the constraint solving machinery in `simplifyDeriv`. I have updated `Note [Gathering and simplifying constraints for DeriveAnyClass]` to explain this in more detail. To make the changes in `simplifyDeriv` more manageable, I also performed some auxiliary refactoring: * Previously, every iteration of `simplifyDeriv` was skolemising the type variables at the start, simplifying, and then performing a reverse substitution at the end to un-skolemise the type variables. This is not necessary, however, since we can just as well skolemise once at the beginning of the `deriving` pipeline and zonk the `TcTyVar`s after `simplifyDeriv` is finished. This patch does just that, having been made possible by prior work in !7613. I have updated `Note [Overlap and deriving]` in `GHC.Tc.Deriv.Infer` to explain this, and I have also left comments on the relevant data structures (e.g., `DerivEnv` and `DerivSpec`) to explain when things might be `TcTyVar`s or `TyVar`s. * All of the aforementioned cleanup allowed me to remove an ad hoc deriving-related in `checkImplicationInvariants`, as all of the skolems in a `tcSubTypeSigma`–produced implication constraint should now be `TcTyVar` at the time the implication is created. * Since `simplifyDeriv` now needs a `SkolemInfo` and `UserTypeCtxt`, I have added `ds_skol_info` and `ds_user_ctxt` fields to `DerivSpec` to store these. Similarly, I have also added a `denv_skol_info` field to `DerivEnv`, which ultimately gets used to initialize the `ds_skol_info` in a `DerivSpec`. Fixes #20719. - - - - - 21680fb0 by Sebastian Graf at 2022-03-24T06:11:19-04:00 WorkWrap: Handle partial FUN apps in `isRecDataCon` (#21265) Partial FUN apps like `(->) Bool` aren't detected by `splitFunTy_maybe`. A silly oversight that is easily fixed by replacing `splitFunTy_maybe` with a guard in the `splitTyConApp_maybe` case. But fortunately, Simon nudged me into rewriting the whole `isRecDataCon` function in a way that makes it much shorter and hence clearer which DataCons are actually considered as recursive. Fixes #21265. - - - - - a2937e2b by Matthew Pickering at 2022-03-24T17:13:22-04:00 Add test for T21035 This test checks that you are allowed to explicitly supply object files for dependencies even if you haven't got the shared object for that library yet. Fixes #21035 - - - - - 1756d547 by Matthew Pickering at 2022-03-24T17:13:58-04:00 Add check to ensure we are not building validate jobs for releases - - - - - 99623358 by Matthew Pickering at 2022-03-24T17:13:58-04:00 hadrian: Correct generation of hsc2hs wrapper If you inspect the inside of a wrapper script for hsc2hs you will see that the cflag and lflag values are concatenated incorrectly. ``` HSC2HS_EXTRA="--cflag=-U__i686--lflag=-fuse-ld=gold" ``` It should instead be ``` HSC2HS_EXTRA="--cflag=-U__i686 --lflag=-fuse-ld=gold" ``` Fixes #21221 - - - - - fefd4e31 by Matthew Pickering at 2022-03-24T17:13:59-04:00 testsuite: Remove library dependenices from T21119 These dependencies would affect the demand signature depending on various rules and so on. Fixes #21271 - - - - - 5ff690b8 by Matthew Pickering at 2022-03-24T17:13:59-04:00 ci: Generate jobs for all normal builds and use hadrian for all builds This commit introduces a new script (.gitlab/gen_ci.hs) which generates a yaml file (.gitlab/jobs.yaml) which contains explicit descriptions for all the jobs we want to run. The jobs are separated into three categories: * validate - jobs run on every MR * nightly - jobs run once per day on the master branch * release - jobs for producing release artifacts The generation script is a Haskell program which includes a DSL for specifying the different jobs. The hope is that it's easier to reason about the different jobs and how the variables are merged together rather than the unclear and opaque yaml syntax. The goal is to fix issues like #21190 once and for all.. The `.gitlab/jobs.yaml` can be generated by running the `.gitlab/generate_jobs` script. You have to do this manually. Another consequence of this patch is that we use hadrian for all the validate, nightly and release builds on all platforms. - - - - - 1d673aa2 by Christiaan Baaij at 2022-03-25T11:35:49-04:00 Add the OPAQUE pragma A new pragma, `OPAQUE`, that ensures that every call of a named function annotated with an `OPAQUE` pragma remains a call of that named function, not some name-mangled variant. Implements GHC proposal 0415: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0415-opaque-pragma.rst This commit also updates the haddock submodule to handle the newly introduced lexer tokens corresponding to the OPAQUE pragma. - - - - - 83f5841b by Andrew Lelechenko at 2022-03-25T11:36:31-04:00 Add instance Lift ByteArray - - - - - 7cc1184a by Matthew Pickering at 2022-03-25T11:37:07-04:00 Make -ddump-rn-ast and -ddump-tc-ast work in GHCi Fixes #17830 - - - - - 940feaf3 by Sylvain Henry at 2022-03-25T11:37:47-04:00 Modularize Tidy (#17957) - Factorize Tidy options into TidyOpts datatype. Initialize it in GHC.Driver.Config.Tidy - Same thing for StaticPtrOpts - Perform lookups of unpackCString[Utf8]# once in initStaticPtrOpts instead of for every use of mkStringExprWithFS - - - - - 25101813 by Takenobu Tani at 2022-03-28T01:16:02-04:00 users-guide: Correct markdown for profiling This patch corrects some markdown. [skip ci] - - - - - c832ae93 by Matthew Pickering at 2022-03-28T01:16:38-04:00 hadrian: Flag cabal flag handling This patch basically deletes some ad-hoc handling of Cabal Flags and replaces it with a correct query of the LocalBuildInfo. The flags in the local build info can be modified by users by passing hadrian options For example (!4331) ``` *.genapply.cabal.configure.opts += --flags=unregisterised ``` And all the flags specified by the `Cabal Flags` builder were already passed to configure properly using `--flags`. - - - - - a9f3a5c6 by Ben Gamari at 2022-03-28T01:16:38-04:00 Disable text's dependency on simdutf by default Unfortunately we are simply not currently in a good position to robustly ship binary distributions which link against C++ code like simdutf. Fixes #20724. - - - - - eff86e8a by Richard Eisenberg at 2022-03-28T01:17:14-04:00 Add Red Herring to Note [What might equal later?] Close #21208. - - - - - 12653be9 by jberryman at 2022-03-28T01:17:55-04:00 Document typed splices inhibiting unused bind detection (#16524) - - - - - 4aeade15 by Adam Sandberg Ericsson at 2022-03-28T01:18:31-04:00 users-guide: group ticky-ticky profiling under one heading - - - - - cc59648a by Sylvain Henry at 2022-03-28T01:19:12-04:00 Hadrian: allow testsuite to run with cross-compilers (#21292) - - - - - 89cb1315 by Matthew Pickering at 2022-03-28T01:19:48-04:00 hadrian: Add show target to bindist makefile Some build systems use "make show" to query facts about the bindist, for example: ``` make show VALUE=ProjectVersion > version ``` to determine the ProjectVersion - - - - - 8229885c by Alan Zimmerman at 2022-03-28T19:23:28-04:00 EPA: let stmt with semicolon has wrong anchor The code let ;x =1 Captures the semicolon annotation, but did not widen the anchor in the ValBinds. Fix that. Closes #20247 - - - - - 2c12627c by Ryan Scott at 2022-03-28T19:24:04-04:00 Consistently attach SrcSpans to sub-expressions in TH splices Before, `GHC.ThToHs` was very inconsistent about where various sub-expressions would get the same `SrcSpan` from the original TH splice location or just a generic `noLoc` `SrcSpan`. I have ripped out all uses of `noLoc` in favor of the former instead, and I have added a `Note [Source locations within TH splices]` to officially enshrine this design choice. Fixes #21299. - - - - - 789add55 by Zubin Duggal at 2022-03-29T13:07:22-04:00 Fix all invalid haddock comments in the compiler Fixes #20935 and #20924 - - - - - 967dad03 by Zubin Duggal at 2022-03-29T13:07:22-04:00 hadrian: Build lib:GHC with -haddock and -Winvalid-haddock (#21273) - - - - - ad09a5f7 by sheaf at 2022-03-29T13:08:05-04:00 Hadrian: make DDEBUG separate from debugged RTS This patchs separates whether -DDEBUG is enabled (i.e. whether debug assertions are enabled) from whether we are using the debugged RTS (i.e. GhcDebugged = YES). This means that we properly skip tests which have been marked with `when(compiler_debugged(), skip)`. Fixes #21113, #21153 and #21234 - - - - - 840a6811 by Matthew Pickering at 2022-03-29T13:08:42-04:00 RTS: Zero gc_cpu_start and gc_cpu_end after accounting When passed a combination of `-N` and `-qn` options the cpu time for garbage collection was being vastly overcounted because the counters were not being zeroed appropiately. When -qn1 is passed, only 1 of the N avaiable GC threads is chosen to perform work, the rest are idle. At the end of the GC period, stat_endGC traverses all the GC threads and adds up the elapsed time from each of them. For threads which didn't participate in this GC, the value of the cpu time should be zero, but before this patch, the counters were not zeroed and hence we would count the same elapsed time on many subsequent iterations (until the thread participated in a GC again). The most direct way to zero these fields is to do so immediately after the value is added into the global counter, after which point they are never used again. We also tried another approach where we would zero the counter in yieldCapability but there are some (undiagnosed) siations where a capbility would not pass through yieldCapability before the GC ended and the same double counting problem would occur. Fixes #21082 - - - - - dda46e2d by Matthew Pickering at 2022-03-29T13:09:18-04:00 Add test for T21306 Fixes #21306 - - - - - f07c7766 by Jakob Brünker at 2022-03-30T03:10:33-04:00 Give parsing plugins access to errors Previously, when the parser produced non-fatal errors (i.e. it produced errors but the 'PState' is 'POk'), compilation would be aborted before the 'parsedResultAction' of any plugin was invoked. This commit changes that, so that such that 'parsedResultAction' gets collections of warnings and errors as argument, and must return them after potentially modifying them. Closes #20803 - - - - - e5dfde75 by Ben Gamari at 2022-03-30T03:11:10-04:00 Fix reference to Note [FunBind vs PatBind] This Note was renamed in 2535a6716202253df74d8190b028f85cc6d21b72 yet this occurrence was not updated. - - - - - 21894a63 by Krzysztof Gogolewski at 2022-03-30T03:11:45-04:00 Refactor: make primtypes independent of PrimReps Previously, 'pcPrimTyCon', the function used to define a primitive type, was taking a PrimRep, only to convert it to a RuntimeRep. Now it takes a RuntimeRep directly. Moved primRepToRuntimeRep to GHC.Types.RepType. It is now located next to its inverse function runtimeRepPrimRep. Now GHC.Builtin.Types.Prim no longer mentions PrimRep, and GHC.Types.RepType no longer imports GHC.Builtin.Types.Prim. Removed unused functions `primRepsToRuntimeRep` and `mkTupleRep`. Removed Note [PrimRep and kindPrimRep] - it was never referenced, didn't belong to Types.Prim, and Note [Getting from RuntimeRep to PrimRep] is more comprehensive. - - - - - 43da2963 by Matthew Pickering at 2022-03-30T09:55:49+01:00 Fix mention of non-existent "rehydrateIface" function [skip ci] Fixes #21303 - - - - - 6793a20f by gershomb at 2022-04-01T10:33:46+01:00 Remove wrong claim about naturality law. This docs change removes a longstanding confusion in the Traversable docs. The docs say "(The naturality law is implied by parametricity and thus so is the purity law [1, p15].)". However if one reads the reference a different "natural" law is implied by parametricity. The naturality law given as a law here is imposed. Further, the reference gives examples which violate both laws -- so they cannot be implied by parametricity. This PR just removes the wrong claim. - - - - - 5beeff46 by Ben Gamari at 2022-04-01T10:34:39+01:00 Refactor handling of global initializers GHC uses global initializers for a number of things including cost-center registration, info-table provenance registration, and setup of foreign exports. Previously, the global initializer arrays which referenced these initializers would live in the object file of the C stub, which would then be merged into the main object file of the module. Unfortunately, this approach is no longer tenable with the move to Clang/LLVM on Windows (see #21019). Specifically, lld's PE backend does not support object merging (that is, the -r flag). Instead we are now rather packaging a module's object files into a static library. However, this is problematic in the case of initializers as there are no references to the C stub object in the archive, meaning that the linker may drop the object from the final link. This patch refactors our handling of global initializers to instead place initializer arrays within the object file of the module to which they belong. We do this by introducing a Cmm data declaration containing the initializer array in the module's Cmm stream. While the initializer functions themselves remain in separate C stub objects, the reference from the module's object ensures that they are not dropped from the final link. In service of #21068. - - - - - 3e6fe71b by Matthew Pickering at 2022-04-01T10:35:41+01:00 Fix remaining issues in eventlog types (gen_event_types.py) * The size of End concurrent mark phase looks wrong and, it used to be 4 and now it's 0. * The size of Task create is wrong, used to be 18 and now 14. * The event ticky-ticky entry counter begin sample has the wrong name * The event ticky-ticky entry counter being sample has the wrong size, was 0 now 32. Closes #21070 - - - - - 7847f47a by Ben Gamari at 2022-04-01T10:35:41+01:00 users-guide: Fix a few small issues in eventlog format descriptions The CONC_MARK_END event description didn't mention its payload. Clarify the meaning of the CREATE_TASK's payload. - - - - - acfd5a4c by Matthew Pickering at 2022-04-01T10:35:53+01:00 ci: Regenerate jobs.yaml It seems I forgot to update this to reflect the current state of gen_ci.hs - - - - - a952dd80 by Matthew Pickering at 2022-04-01T10:35:59+01:00 ci: Attempt to fix windows cache issues It appears that running the script directly does nothing (no info is printed about saving the cache). - - - - - fb65e6e3 by Adrian Ratiu at 2022-04-01T10:49:52+01:00 fp_prog_ar.m4: take AR var into consideration In ChromeOS and Gentoo we want the ability to use LLVM ar instead of GNU ar even though both are installed, thus we pass (for eg) AR=llvm-ar to configure. Unfortunately GNU ar always gets picked regardless of the AR setting because the check does not consider the AR var when setting fp_prog_ar, hence this fix. - - - - - 1daaefdf by Greg Steuck at 2022-04-01T10:50:16+01:00 T13366 requires c++ & c++abi libraries on OpenBSD Fixes this failure: =====> 1 of 1 [0, 0, 0] T13366(normal) 1 of 1 [0, 0, 0] Compile failed (exit code 1) errors were: <no location info>: error: user specified .o/.so/.DLL could not be loaded (File not found) Whilst trying to load: (dynamic) stdc++ Additional directories searched: (none) *** unexpected failure for T13366(normal) - - - - - 18e6c85b by Jakob Bruenker at 2022-04-01T10:54:28+01:00 new datatypes for parsedResultAction Previously, the warnings and errors were given and returned as a tuple (Messages PsWarnings, Messages PsErrors). Now, it's just PsMessages. This, together with the HsParsedModule the parser plugin gets and returns, has been wrapped up as ParsedResult. - - - - - 9727e592 by Morrow at 2022-04-01T10:55:12+01:00 Clarify that runghc interprets the input program - - - - - f589dea3 by sheaf at 2022-04-01T10:59:58+01:00 Unify RuntimeRep arguments in ty_co_match The `ty_co_match` function ignored the implicit RuntimeRep coercions that occur in a `FunCo`. Even though a comment explained that this should be fine, #21205 showed that it could result in discarding a RuntimeRep coercion, and thus discarding an important cast entirely. With this patch, we first match the kinds in `ty_co_match`. Fixes #21205 ------------------------- Metric Increase: T12227 T18223 ------------------------- - - - - - 6f4dc372 by Andreas Klebinger at 2022-04-01T11:01:35+01:00 Export MutableByteArray from Data.Array.Byte This implements CLC proposal #49 - - - - - 5df9f5e7 by ARATA Mizuki at 2022-04-01T11:02:35+01:00 Add test cases for #20640 Closes #20640 - - - - - 8334ff9e by Krzysztof Gogolewski at 2022-04-01T11:03:16+01:00 Minor cleanup - Remove unused functions exprToCoercion_maybe, applyTypeToArg, typeMonoPrimRep_maybe, runtimeRepMonoPrimRep_maybe. - Replace orValid with a simpler check - Use splitAtList in applyTysX - Remove calls to extra_clean in the testsuite; it does not do anything. Metric Decrease: T18223 - - - - - b2785cfc by Eric Lindblad at 2022-04-01T11:04:07+01:00 hadrian typos - - - - - 418e6fab by Eric Lindblad at 2022-04-01T11:04:12+01:00 two typos - - - - - dd7c7c99 by Phil de Joux at 2022-04-01T11:04:56+01:00 Add tests and docs on plugin args and order. - - - - - 3e209a62 by MaxHearnden at 2022-04-01T11:05:19+01:00 Change may not to might not - - - - - b84380d3 by Matthew Pickering at 2022-04-01T11:07:27+01:00 hadrian: Remove linters-common from bindist Zubin observed that the bindists contains the utility library linters-common. There are two options: 1. Make sure only the right files are added into the bindist.. a bit tricky due to the non-trivial structure of the lib directory. 2. Remove the bad files once they get copied in.. a bit easier So I went for option 2 but we perhaps should go for option 1 in the future. Fixes #21203 - - - - - ba9904c1 by Zubin Duggal at 2022-04-01T11:07:31+01:00 hadrian: allow testing linters with out of tree compilers - - - - - 26547759 by Matthew Pickering at 2022-04-01T11:07:35+01:00 hadrian: Introduce CheckProgram datatype to replace a 7-tuple - - - - - df65d732 by Jakob Bruenker at 2022-04-01T11:08:28+01:00 Fix panic when pretty printing HsCmdLam When pretty printing a HsCmdLam with more than one argument, GHC panicked because of a missing case. This fixes that. Closes #21300 - - - - - ad6cd165 by John Ericson at 2022-04-01T11:10:06+01:00 hadrian: Remove vestigial -this-unit-id support check This has been dead code since 400ead81e80f66ad7b1260b11b2a92f25ccc3e5a. - - - - - 8ca7ab81 by Matthew Pickering at 2022-04-01T11:10:23+01:00 hadrian: Fix race involving empty package databases There was a small chance of a race occuring between the small window of 1. The first package (.conf) file get written into the database 2. hadrian calling "ghc-pkg recache" to refresh the package.conf file In this window the package database would contain rts.conf but not a package.cache file, and therefore if ghc was invoked it would error because it was missing. To solve this we call "ghc-pkg recache" at when the database is created by shake by writing the stamp file into the database folder. This also creates the package.cache file and so avoids the possibility of this race. - - - - - cc4ec64b by Matthew Pickering at 2022-04-01T11:11:05+01:00 hadrian: Add assertion that in/out tree args are the same There have been a few instances where this calculation was incorrect, so we add a non-terminal assertion when now checks they the two computations indeed compute the same thing. Fixes #21285 - - - - - 691508d8 by Matthew Pickering at 2022-04-01T11:13:10+01:00 hlint: Ignore suggestions in generated HaddockLex file With the make build system this file ends up in the compiler/ subdirectory so is linted. With hadrian, the file ends up in _build so it's not linted. Fixes #21313 - - - - - f8f152e7 by Krzysztof Gogolewski at 2022-04-01T11:14:08+01:00 Change GHC.Prim to GHC.Exts in docs and tests Users are supposed to import GHC.Exts rather than GHC.Prim. Part of #18749. - - - - - f8fc6d2e by Matthew Pickering at 2022-04-01T11:15:24+01:00 driver: Improve -Wunused-packages error message (and simplify implementation) In the past I improved the part of -Wunused-packages which found which packages were used. Now I improve the part which detects which ones were specified. The key innovation is to use the explicitUnits field from UnitState which has the result of resolving the package flags, so we don't need to mess about with the flag arguments from DynFlags anymore. The output now always includes the package name and version (and the flag which exposed it). ``` The following packages were specified via -package or -package-id flags, but were not needed for compilation: - bytestring-0.11.2.0 (exposed by flag -package bytestring) - ghc-9.3 (exposed by flag -package ghc) - process-1.6.13.2 (exposed by flag -package process) ``` Fixes #21307 - - - - - 5e5a12d9 by Matthew Pickering at 2022-04-01T11:15:32+01:00 driver: In oneshot mode, look for interface files in hidir How things should work: * -i is the search path for source files * -hidir explicitly sets the search path for interface files and the output location for interface files. * -odir sets the search path and output location for object files. Before in one shot mode we would look for the interface file in the search locations given by `-i`, but then set the path to be in the `hidir`, so in unusual situations the finder could find an interface file in the `-i` dir but later fail because it tried to read the interface file from the `-hidir`. A bug identified by #20569 - - - - - 950f58e7 by Matthew Pickering at 2022-04-01T11:15:36+01:00 docs: Update documentation interaction of search path, -hidir and -c mode. As noted in #20569 the documentation for search path was wrong because it seemed to indicate that `-i` dirs were important when looking for interface files in `-c` mode, but they are not important if `-hidir` is set. Fixes #20569 - - - - - d85c7dcb by sheaf at 2022-04-01T11:17:56+01:00 Keep track of promotion ticks in HsOpTy This patch adds a PromotionFlag field to HsOpTy, which is used in pretty-printing and when determining whether to emit warnings with -fwarn-unticked-promoted-constructors. This allows us to correctly report tick-related warnings for things like: type A = Int : '[] type B = [Int, Bool] Updates haddock submodule Fixes #19984 - - - - - 32070e6c by Jakob Bruenker at 2022-04-01T20:31:08+02:00 Implement \cases (Proposal 302) This commit implements proposal 302: \cases - Multi-way lambda expressions. This adds a new expression heralded by \cases, which works exactly like \case, but can match multiple apats instead of a single pat. Updates submodule haddock to support the ITlcases token. Closes #20768 - - - - - c6f77f39 by sheaf at 2022-04-01T20:33:05+02:00 Add a regression test for #21323 This bug was fixed at some point between GHC 9.0 and GHC 9.2; this patch simply adds a regression test. - - - - - 3596684e by Jakob Bruenker at 2022-04-01T20:33:05+02:00 Fix error when using empty case in arrow notation It was previously not possible to use -XEmptyCase in Arrow notation, since GHC would print "Exception: foldb of empty list". This is now fixed. Closes #21301 - - - - - 9a325b59 by Ben Gamari at 2022-04-01T20:33:05+02:00 users-guide: Fix various markup issues - - - - - aefb1e6d by sheaf at 2022-04-01T20:36:01+02:00 Ensure implicit parameters are lifted `tcExpr` typechecked implicit parameters by introducing a metavariable of kind `TYPE kappa`, without enforcing that `kappa ~ LiftedRep`. This patch instead creates a metavariable of kind `Type`. Fixes #21327 - - - - - ed62dc66 by Ben Gamari at 2022-04-05T11:44:51-04:00 gitlab-ci: Disable cabal-install store caching on Windows For reasons that remain a mystery, cabal-install seems to consistently corrupt its cache on Windows. Disable caching for now. Works around #21347. - - - - - 5ece5c5a by Ryan Scott at 2022-04-06T13:00:51-04:00 Add /linters/*/dist-install/ to .gitignore Fixes #21335. [ci skip] - - - - - 410c76ee by Ben Gamari at 2022-04-06T13:01:28-04:00 Use static archives as an alternative to object merging Unfortunately, `lld`'s COFF backend does not currently support object merging. With ld.bfd having broken support for high image-load base addresses, it's necessary to find an alternative. Here I introduce support in the driver for generating static archives, which we use on Windows instead of object merging. Closes #21068. - - - - - 400666c8 by Ben Gamari at 2022-04-06T13:01:28-04:00 rts/linker: Catch archives masquerading as object files Check the file's header to catch static archive bearing the `.o` extension, as may happen on Windows after the Clang refactoring. See #21068 - - - - - 694d39f0 by Ben Gamari at 2022-04-06T13:01:28-04:00 driver: Make object merging optional On Windows we don't have a linker which supports object joining (i.e. the `-r` flag). Consequently, `-pgmlm` is now a `Maybe`. See #21068. - - - - - 41fcb5cd by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Refactor handling of ar flags Previously the setup was quite fragile as it had to assume which arguments were file arguments and which were flags. - - - - - 3ac80a86 by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Produce ar archives with L modifier on Windows Since object files may in fact be archive files, we must ensure that their contents are merged rather than constructing an archive-of-an-archive. See #21068. - - - - - 295c35c5 by Ben Gamari at 2022-04-06T13:01:28-04:00 Add a Note describing lack of object merging on Windows See #21068. - - - - - d2ae0a3a by Ben Gamari at 2022-04-06T13:01:28-04:00 Build ar archives with -L when "joining" objects Since there may be .o files which are in fact archives. - - - - - babb47d2 by Zubin Duggal at 2022-04-06T13:02:04-04:00 Add warnings for file header pragmas that appear in the body of a module (#20385) Once we are done parsing the header of a module to obtain the options, we look through the rest of the tokens in order to determine if they contain any misplaced file header pragmas that would usually be ignored, potentially resulting in bad error messages. The warnings are reported immediately so that later errors don't shadow over potentially helpful warnings. Metric Increase: T13719 - - - - - 3f31825b by Ben Gamari at 2022-04-06T13:02:40-04:00 rts/AdjustorPool: Generalize to allow arbitrary contexts Unfortunately the i386 adjustor logic needs this. - - - - - 9b645ee1 by Ben Gamari at 2022-04-06T13:02:40-04:00 adjustors/i386: Use AdjustorPool In !7511 (closed) I introduced a new allocator for adjustors, AdjustorPool, which eliminates the address space fragmentation issues which adjustors can introduce. In that work I focused on amd64 since that was the platform where I observed issues. However, in #21132 we noted that the size of adjustors is also a cause of CI fragility on i386. In this MR I port i386 to use AdjustorPool. Sadly the complexity of the i386 adjustor code does cause require a bit of generalization which makes the code a bit more opaque but such is the world. Closes #21132. - - - - - c657a616 by Ben Gamari at 2022-04-06T13:03:16-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 9ce273b9 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Drop dead HACKAGE_INDEX_STATE variable - - - - - 01845375 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab/darwin: Factor out bindists This makes it a bit easier to bump them. - - - - - c41c478e by Ben Gamari at 2022-04-06T13:03:16-04:00 Fix a few new warnings when booting with GHC 9.2.2 -Wuni-incomplete-patterns and apparent improvements in the pattern match checker surfaced these. - - - - - 6563cd24 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Bump bootstrap compiler to 9.2.2 This is necessary to build recent `text` commits. Bumps Hackage index state for a hashable which builds with GHC 9.2. - - - - - a62e983e by Ben Gamari at 2022-04-06T13:03:16-04:00 Bump text submodule to current `master` Addresses #21295. - - - - - 88d61031 by Vladislav Zavialov at 2022-04-06T13:03:53-04:00 Refactor OutputableBndrFlag instances The matching on GhcPass introduced by 95275a5f25a is not necessary. This patch reverts it to make the code simpler. - - - - - f601f002 by GHC GitLab CI at 2022-04-06T15:18:26-04:00 rts: Eliminate use of nested functions This is a gcc-specific extension. - - - - - d4c5f29c by Ben Gamari at 2022-04-06T15:18:26-04:00 driver: Drop hacks surrounding windres invocation Drop hack for #1828, among others as they appear to be unnecessary when using `llvm-windres`. - - - - - 6be2c5a7 by Ben Gamari at 2022-04-06T15:18:26-04:00 Windows/Clang: Build system adaptation * Bump win32-tarballs to 0.7 * Move Windows toolchain autoconf logic into separate file * Use clang and LLVM utilities as described in #21019 * Disable object merging as lld doesn't support -r * Drop --oformat=pe-bigobj-x86-64 arguments from ld flags as LLD detects that the output is large on its own. * Drop gcc wrapper since Clang finds its root fine on its own. - - - - - c6fb7aff by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Test that we can build bigobj PE objects - - - - - 79851c07 by Ben Gamari at 2022-04-06T15:18:26-04:00 Drop -static-libgcc This flag is not applicable when Clang is used. - - - - - 1f8a8264 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Port T16514 to C Previously this test was C++ which made it a bit of a portability problem. - - - - - d7e650d1 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark Windows as a libc++ platform - - - - - d7886c46 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark T9405 as fixed on Windows I have not seen it fail since moving to clang. Closes #12714. - - - - - 4c3fbb4e by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark FloatFnInverses as fixed The new toolchain has fixed it. Closes #15670. - - - - - 402c36ba by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Rework T13606 to avoid gcc dependence Previously we used libgcc_s's import library in T13606. However, now that we ship with clang we no longer have this library. Instead we now use gdi32. - - - - - 9934ad54 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Clean up tests depending on C++ std lib - - - - - 12fcdef2 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Split T13366 into two tests Split up the C and C++ uses since the latter is significantly more platform-dependent. - - - - - 3c08a198 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Fix mk-big-obj I'm a bit unclear on how this previously worked as it attempted to build an executable without defining `main`. - - - - - 7e97cc23 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Provide module definitions in T10955dyn Otherwise the linker will export all symbols, including those provided by the RTS, from the produced shared object. Consequently, attempting to link against multiple objects simultaneously will cause the linker to complain that RTS symbols are multiply defined. Avoid this by limiting the DLL exports with a module definition file. - - - - - 9a248afa by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark test-defaulting-plugin as fragile on Windows Currently llvm-ar does not handle long file paths, resulting in occassional failures of these tests and #21293. - - - - - 39371aa4 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite/driver: Treat framework failures of fragile tests as non-fatal Previously we would report framework failures of tests marked as fragile as failures. Now we rather treat them as fragile test failures, which are not fatal to the testsuite run. Noticed while investigating #21293. - - - - - a1e6661d by Ben Gamari at 2022-04-06T15:18:32-04:00 Bump Cabal submodule - Disable support for library-for-ghci on Windows as described in #21068. - Teach Cabal to use `ar -L` when available - - - - - f7b0f63c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump process submodule Fixes missing TEST_CC_OPTS in testsuite tests. - - - - - 109cee19 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Disable ghci libraries when object merging is not available - - - - - c22fba5c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump bytestring submodule - - - - - 6e2744cc by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump text submodule - - - - - 32333747 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Build wrappers using ghc rather than cc - - - - - 59787ba5 by Ben Gamari at 2022-04-06T15:18:37-04:00 linker/PEi386: More descriptive error message - - - - - 5e3c3c4f by Ben Gamari at 2022-04-06T15:18:37-04:00 testsuite: Mark TH_spliceE5_prof as unbroken on Windows It was previously failing due to #18721 and now passes with the new toolchain. Closes #18721. - - - - - 9eb0a9d9 by GHC GitLab CI at 2022-04-06T15:23:48-04:00 rts/PEi386: Move some debugging output to -DL - - - - - ce874595 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen/x86: Use %rip-relative addressing On Windows with high-entropy ASLR we must use %rip-relative addressing to avoid overflowing the signed 32-bit immediate size of x86-64. Since %rip-relative addressing comes essentially for free and can make linking significantly easier, we use it on all platforms. - - - - - 52deee64 by Ben Gamari at 2022-04-06T15:24:01-04:00 Generate LEA for label expressions - - - - - 105a0056 by Ben Gamari at 2022-04-06T15:24:01-04:00 Refactor is32BitLit to take Platform rather than Bool - - - - - ec4526b5 by Ben Gamari at 2022-04-06T15:24:01-04:00 Don't assume that labels are 32-bit on Windows - - - - - ffdbe457 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen: Note signed-extended nature of MOV - - - - - bfb79697 by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 5ad143fd by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - a59a66a8 by Ben Gamari at 2022-04-06T15:30:56-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - 42bf7528 by GHC GitLab CI at 2022-04-06T16:25:04-04:00 rts/PEi386: Fix memory leak Previously we would leak the section information of the `.bss` section. - - - - - d286a55c by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Preserve information about symbol types As noted in #20978, the linker would previously handle overflowed relocations by creating a jump island. While this is fine in the case of code symbols, it's very much not okay in the case of data symbols. To fix this we must keep track of whether each symbol is code or data and relocate them appropriately. This patch takes the first step in this direction, adding a symbol type field to the linker's symbol table. It doesn't yet change relocation behavior to take advantage of this knowledge. Fixes #20978. - - - - - e689e9d5 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Fix relocation overflow behavior This fixes handling of overflowed relocations on PEi386 targets: * Refuse to create jump islands for relocations of data symbols * Correctly handle the `__imp___acrt_iob_func` symbol, which is an new type of symbol: `SYM_TYPE_INDIRECT_DATA` - - - - - 655e7d8f by GHC GitLab CI at 2022-04-06T16:25:25-04:00 rts: Mark anything that might have an info table as data Tables-next-to-code mandates that we treat symbols with info tables like data since we cannot relocate them using a jump island. See #20983. - - - - - 7e8cc293 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Rework linker This is a significant rework of the PEi386 linker, making the linker compatible with high image base addresses. Specifically, we now use the m32 allocator instead of `HeapAllocate`. In addition I found a number of latent bugs in our handling of import libraries and relocations. I've added quite a few comments describing what I've learned about Windows import libraries while fixing these. Thanks to Tamar Christina (@Phyx) for providing the address space search logic, countless hours of help while debugging, and his boundless Windows knowledge. Co-Authored-By: Tamar Christina <tamar at zhox.com> - - - - - ff625218 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Move allocateBytes to MMap.c - - - - - f562b5ca by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Avoid accidentally-quadratic allocation cost We now preserve the address that we last mapped, allowing us to resume our search and avoiding quadratic allocation costs. This fixes the runtime of T10296a, which allocates many adjustors. - - - - - 3247b7db by Ben Gamari at 2022-04-06T16:25:25-04:00 Move msvcrt dep out of base - - - - - fa404335 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: More descriptive debug output - - - - - 140f338f by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PathUtils: Define pathprintf in terms of snwprintf on Windows swprintf deviates from usual `snprintf` semantics in that it does not guarantee reasonable behavior when the buffer is NULL (that is, returning the number of bytes that would have been emitted). - - - - - eb60565b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Report archive member index - - - - - 209fd61b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Split up object resolution and initialization Previously the RTS linker would call initializers during the "resolve" phase of linking. However, this is problematic in the case of cyclic dependencies between objects. In particular, consider the case where we have a situation where a static library contains a set of recursive objects: * object A has depends upon symbols in object B * object B has an initializer that depends upon object A * we try to load object A The linker would previously: 1. start resolving object A 2. encounter the reference to object B, loading it resolve object B 3. run object B's initializer 4. the initializer will attempt to call into object A, which hasn't been fully resolved (and therefore protected) Fix this by moving constructor execution to a new linking phase, which follows resolution. Fix #21253. - - - - - 8e8a1021 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker/LoadArchive: Fix leaking file handle Previously `isArchive` could leak a `FILE` handle if the `fread` returned a short read. - - - - - 429ea5d9 by sheaf at 2022-04-07T07:55:52-04:00 Remove Fun pattern from Typeable COMPLETE set GHC merge request !963 improved warnings in the presence of COMPLETE annotations. This allows the removal of the Fun pattern from the complete set. Doing so expectedly causes some redundant pattern match warnings, in particular in GHC.Utils.Binary.Typeable and Data.Binary.Class from the binary library; this commit addresses that. Updates binary submodule Fixes #20230 - - - - - 54b18824 by Alan Zimmerman at 2022-04-07T07:56:28-04:00 EPA: handling of con_bndrs in mkGadtDecl Get rid of unnnecessary case clause that always matched. Closes #20558 - - - - - 9c838429 by Ben Gamari at 2022-04-07T09:38:53-04:00 testsuite: Mark T10420 as broken on Windows Due to #21322. - - - - - 50739d2b by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Refactor and fix printf attributes on clang Clang on Windows does not understand the `gnu_printf` attribute; use `printf` instead. - - - - - 9eeaeca4 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Add missing newline in error message - - - - - fcef9a17 by Ben Gamari at 2022-04-07T09:42:42-04:00 configure: Make environ decl check more robust Some platforms (e.g. Windows/clang64) declare `environ` in `<stdlib.h>`, not `<unistd.h>` - - - - - 8162b4f3 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Adjust RTS symbol table on Windows for ucrt - - - - - 633280d7 by Ben Gamari at 2022-04-07T09:43:21-04:00 testsuite: Fix exit code of bounds checking tests on Windows `abort` exits with 255, not 134, on Windows. - - - - - cab4dc01 by Ben Gamari at 2022-04-07T09:43:31-04:00 testsuite: Update expected output from T5435 tests on Windows I'll admit, I don't currently see *why* this output is reordered but it is a fairly benign difference and I'm out of time to investigate. - - - - - edf5134e by Ben Gamari at 2022-04-07T09:43:35-04:00 testsuite: Mark T20918 as broken on Windows Our toolchain on Windows doesn't currently have Windows support. - - - - - d0ddeff3 by Ben Gamari at 2022-04-07T09:43:39-04:00 testsuite: Mark linker unloading tests as broken on Windows Due to #20354. We will need to investigate this prior the release. - - - - - 5a86da2b by Ben Gamari at 2022-04-07T09:43:43-04:00 testsuite: Mark T9405 as broken on Windows Due to #21361. - - - - - 4aa86dcf by Ben Gamari at 2022-04-07T09:44:18-04:00 Merge branches 'wip/windows-high-codegen', 'wip/windows-high-linker', 'wip/windows-clang-2' and 'wip/lint-rts-includes' into wip/windows-clang-join - - - - - 7206f055 by Ben Gamari at 2022-04-07T09:45:07-04:00 rts/CloneStack: Ensure that Rts.h is #included first As is necessary on Windows. - - - - - 9cfcb27b by Ben Gamari at 2022-04-07T09:45:07-04:00 rts: Fallback to ucrtbase not msvcrt Since we have switched to Clang the toolchain now links against ucrt rather than msvcrt. - - - - - d6665d85 by Ben Gamari at 2022-04-07T09:46:25-04:00 Accept spurious perf test shifts on Windows Metric Decrease: T16875 Metric Increase: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 83363c8b by Simon Peyton Jones at 2022-04-07T12:57:21-04:00 Use prepareBinding in tryCastWorkerWrapper As #21144 showed, tryCastWorkerWrapper was calling prepareRhs, and then unconditionally floating the bindings, without the checks of doFloatFromRhs. That led to floating an unlifted binding into a Rec group. This patch refactors prepareBinding to make these checks, and do them uniformly across all calls. A nice improvement. Other changes * Instead of passing around a RecFlag and a TopLevelFlag; and sometimes a (Maybe SimplCont) for join points, define a new Simplifier-specific data type BindContext: data BindContext = BC_Let TopLevelFlag RecFlag | BC_Join SimplCont and use it consistently. * Kill off completeNonRecX by inlining it. It was only called in one place. * Add a wrapper simplImpRules for simplRules. Compile time on T9630 drops by 4.7%; little else changes. Metric Decrease: T9630 - - - - - 02279a9c by Vladislav Zavialov at 2022-04-07T12:57:59-04:00 Rename [] to List (#21294) This patch implements a small part of GHC Proposal #475. The key change is in GHC.Types: - data [] a = [] | a : [a] + data List a = [] | a : List a And the rest of the patch makes sure that List is pretty-printed as [] in various contexts. Updates the haddock submodule. - - - - - 08480d2a by Simon Peyton Jones at 2022-04-07T12:58:36-04:00 Fix the free-var test in validDerivPred The free-var test (now documented as (VD3)) was too narrow, affecting only class predicates. #21302 demonstrated that this wasn't enough! Fixes #21302. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - b3d6d23d by Andreas Klebinger at 2022-04-07T12:59:12-04:00 Properly explain where INLINE pragmas can appear. Fixes #20676 - - - - - 23ef62b3 by Ben Gamari at 2022-04-07T14:28:28-04:00 rts: Fix off-by-one in snwprintf usage - - - - - b2dbcc7d by Simon Jakobi at 2022-04-08T03:00:38-04:00 Improve seq[D]VarSet Previously, the use of size[D]VarSet would involve a traversal of the entire underlying IntMap. Since IntMaps are already spine-strict, this is unnecessary. - - - - - 64ac20a7 by sheaf at 2022-04-08T03:01:16-04:00 Add test for #21338 This no-skolem-info bug was fixed by the no-skolem-info patch that will be part of GHC 9.4. This patch adds a regression test for the issue reported in issue #21338. Fixes #21338. - - - - - c32c4db6 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 56f85d62 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - cb1f31f5 by Ben Gamari at 2022-04-08T03:01:53-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - c44432db by Krzysztof Gogolewski at 2022-04-08T03:02:29-04:00 Fixes to 9.4 release notes - Mention -Wforall-identifier - Improve description of withDict - Fix formatting - - - - - 777365f1 by sheaf at 2022-04-08T09:43:35-04:00 Correctly report SrcLoc of redundant constraints We were accidentally dropping the source location information in certain circumstances when reporting redundant constraints. This patch makes sure that we set the TcLclEnv correctly before reporting the warning. Fixes #21315 - - - - - af300a43 by Vladislav Zavialov at 2022-04-08T09:44:11-04:00 Reject illegal quote mark in data con declarations (#17865) * Non-fatal (i.e. recoverable) parse error * Checking infix constructors * Extended the regression test - - - - - 56254e6b by Ben Gamari at 2022-04-08T09:59:46-04:00 Merge remote-tracking branch 'origin/master' - - - - - 6e2c3b7c by Matthew Pickering at 2022-04-08T13:55:15-04:00 driver: Introduce HomeModInfoCache abstraction The HomeModInfoCache is a mutable cache which is updated incrementally as the driver completes, this makes it robust to exceptions including (SIGINT) The interface for the cache is described by the `HomeMOdInfoCache` data type: ``` data HomeModInfoCache = HomeModInfoCache { hmi_clearCache :: IO [HomeModInfo] , hmi_addToCache :: HomeModInfo -> IO () } ``` The first operation clears the cache and returns its contents. This is designed so it's harder to end up in situations where the cache is retained throughout the execution of upsweep. The second operation allows a module to be added to the cache. The one slightly nasty part is in `interpretBuildPlan` where we have to be careful to ensure that the cache writes happen: 1. In parralel 2. Before the executation continues after upsweep. This requires some simple, localised MVar wrangling. Fixes #20780 - - - - - 85f4a3c9 by Andreas Klebinger at 2022-04-08T13:55:50-04:00 Add flag -fprof-manual which controls if GHC should honour manual cost centres. This allows disabling of manual control centres in code a user doesn't control like libraries. Fixes #18867 - - - - - 3415981c by Vladislav Zavialov at 2022-04-08T13:56:27-04:00 HsUniToken for :: in GADT constructors (#19623) One more step towards the new design of EPA. Updates the haddock submodule. - - - - - 23f95735 by sheaf at 2022-04-08T13:57:07-04:00 Docs: datacon eta-expansion, rep-poly checks The existing notes weren't very clear on how the eta-expansion of data constructors that occurs in tcInferDataCon/dsConLike interacts with the representation polymorphism invariants. So we explain with a few more details how we ensure that the representation-polymorphic lambdas introduced by tcInferDataCon/dsConLike don't end up causing problems, by checking they are properly instantiated and then relying on the simple optimiser to perform beta reduction. A few additional changes: - ConLikeTc just take type variables instead of binders, as we never actually used the binders. - Removed the FRRApp constructor of FRROrigin; it was no longer used now that we use ExpectedFunTyOrigin. - Adds a bit of documentation to the constructors of ExpectedFunTyOrigin. - - - - - d4480490 by Matthew Pickering at 2022-04-08T13:57:43-04:00 ci: Replace "always" with "on_success" to stop build jobs running before hadrian-ghci has finished See https://docs.gitlab.com/ee/ci/yaml/#when * always means, always run not matter what * on_success means, run if the dependencies have built successfully - - - - - 0736e949 by Vladislav Zavialov at 2022-04-08T13:58:19-04:00 Disallow (->) as a data constructor name (#16999) The code was misusing isLexCon, which was never meant for validation. In fact, its documentation states the following: Use these functions to figure what kind of name a 'FastString' represents; these functions do /not/ check that the identifier is valid. Ha! This sign can't stop me because I can't read. The fix is to use okConOcc instead. The other checks (isTcOcc or isDataOcc) seem superfluous, so I also removed those. - - - - - e58d5eeb by Simon Peyton Jones at 2022-04-08T13:58:55-04:00 Tiny documentation wibble This commit commit 83363c8b04837ee871a304cf85207cf79b299fb0 Author: Simon Peyton Jones <simon.peytonjones at gmail.com> Date: Fri Mar 11 16:55:38 2022 +0000 Use prepareBinding in tryCastWorkerWrapper refactored completeNonRecX away, but left a Note referring to it. This MR fixes that Note. - - - - - 4bb00839 by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Fix nightly head.hackage pipelines This also needs a corresponding commit to head.hackage, I also made the job explicitly depend on the fedora33 job so that it isn't blocked by a failing windows job, which causes docs-tarball to fail. - - - - - 3c48e12a by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Remove doc-tarball dependency from perf and perf-nofib jobs These don't depend on the contents of the tarball so we can run them straight after the fedora33 job finishes. - - - - - 27362265 by Matthew Pickering at 2022-04-09T07:41:04-04:00 Bump deepseq to 1.4.7.0 Updates deepseq submodule Fixes #20653 - - - - - dcf30da8 by Joachim Breitner at 2022-04-09T13:02:19-04:00 Drop the app invariant previously, GHC had the "let/app-invariant" which said that the RHS of a let or the argument of an application must be of lifted type or ok for speculation. We want this on let to freely float them around, and we wanted that on app to freely convert between the two (e.g. in beta-reduction or inlining). However, the app invariant meant that simple code didn't stay simple and this got in the way of rules matching. By removing the app invariant, this thus fixes #20554. The new invariant is now called "let-can-float invariant", which is hopefully easier to guess its meaning correctly. Dropping the app invariant means that everywhere where we effectively do beta-reduction (in the two simplifiers, but also in `exprIsConApp_maybe` and other innocent looking places) we now have to check if the argument must be evaluated (unlifted and side-effecting), and analyses have to be adjusted to the new semantics of `App`. Also, `LetFloats` in the simplifier can now also carry such non-floating bindings. The fix for DmdAnal, refine by Sebastian, makes functions with unlifted arguments strict in these arguments, which changes some signatures. This causes some extra calls to `exprType` and `exprOkForSpeculation`, so some perf benchmarks regress a bit (while others improve). Metric Decrease: T9020 Metric Increase: LargeRecord T12545 T15164 T16577 T18223 T5642 T9961 Co-authored-by: Sebastian Graf <sebastian.graf at kit.edu> - - - - - 6c6c5379 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add functions traceWith, traceShowWith, traceEventWith. As discussed at https://github.com/haskell/core-libraries-committee/issues/36 - - - - - 8fafacf7 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add tests for several trace functions. - - - - - 20bbf3ac by Philip Hazelden at 2022-04-09T13:02:59-04:00 Update changelog. - - - - - 47d18b0b by Andreas Klebinger at 2022-04-09T13:03:35-04:00 Add regression test for #19569 - - - - - 5f8d6e65 by sheaf at 2022-04-09T13:04:14-04:00 Fix missing SymCo in pushCoercionIntoLambda There was a missing SymCo in pushCoercionIntoLambda. Currently this codepath is only used with rewrite rules, so this bug managed to slip by, but trying to use pushCoercionIntoLambda in other contexts revealed the bug. - - - - - 20eca489 by Vladislav Zavialov at 2022-04-09T13:04:50-04:00 Refactor: simplify lexing of the dot Before this patch, the lexer did a truly roundabout thing with the dot: 1. look up the varsym in reservedSymsFM and turn it into ITdot 2. under OverloadedRecordDot, turn it into ITvarsym 3. in varsym_(prefix|suffix|...) turn it into ITvarsym, ITdot, or ITproj, depending on extensions and whitespace Turns out, the last step is sufficient to handle the dot correctly. This patch removes the first two steps. - - - - - 5440f63e by Hécate Moonlight at 2022-04-12T11:11:06-04:00 Document that DuplicateRecordFields doesn't tolerates ambiguous fields Fix #19891 - - - - - 0090ad7b by Sebastian Graf at 2022-04-12T11:11:42-04:00 Eta reduction based on evaluation context (#21261) I completely rewrote our Notes surrounding eta-reduction. The new entry point is `Note [Eta reduction makes sense]`. Then I went on to extend the Simplifier to maintain an evaluation context in the form of a `SubDemand` inside a `SimplCont`. That `SubDemand` is useful for doing eta reduction according to `Note [Eta reduction based on evaluation context]`, which describes how Demand analysis, Simplifier and `tryEtaReduce` interact to facilitate eta reduction in more scenarios. Thus we fix #21261. ghc/alloc perf marginally improves (-0.0%). A medium-sized win is when compiling T3064 (-3%). It seems that haddock improves by 0.6% to 1.0%, too. Metric Decrease: T3064 - - - - - 4d2ee313 by Sebastian Graf at 2022-04-12T17:54:57+02:00 Specialising through specialised method calls (#19644) In #19644, we discovered that the ClassOp/DFun rules from Note [ClassOp/DFun selection] inhibit transitive specialisation in a scenario like ``` class C a where m :: Show b => a -> b -> ...; n :: ... instance C Int where m = ... -- $cm :: Show b => Int -> b -> ... f :: forall a b. (C a, Show b) => ... f $dC $dShow = ... m @a $dC @b $dShow ... main = ... f @Int @Bool ... ``` After we specialise `f` for `Int`, we'll see `m @a $dC @b $dShow` in the body of `$sf`. But before this patch, Specialise doesn't apply the ClassOp/DFun rule to rewrite to a call of the instance method for `C Int`, e.g., `$cm @Bool $dShow`. As a result, Specialise couldn't further specialise `$cm` for `Bool`. There's a better example in `Note [Specialisation modulo dictionary selectors]`. This patch enables proper Specialisation, as follows: 1. In the App case of `specExpr`, try to apply the CalssOp/DictSel rule on the head of the application 2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and `$dShow` in `bindAuxiliaryDict` NB: Without (2), (1) would be pointless, because `lookupRule` wouldn't be able to look into the RHS of `$dC` to see the DFun. (2) triggered #21332, because the Specialiser floats around dictionaries without accounting for them in the `SpecEnv`'s `InScopeSet`, triggering a panic when rewriting dictionary unfoldings. Fixes #19644 and #21332. - - - - - b06f4f47 by Sebastian Graf at 2022-04-12T17:54:58+02:00 Specialise: Check `typeDeterminesValue` before specialising on an interesting dictionary I extracted the checks from `Note [Type determines value]` into its own function, so that we share the logic properly. Then I made sure that we actually call `typeDeterminesValue` everywhere we check for `interestingDict`. - - - - - a42dbc55 by Matthew Pickering at 2022-04-13T06:24:52-04:00 Refine warning about defining rules in SAFE modules This change makes it clear that it's the definition rather than any usage which is a problem, and that rules defined in other modules will still be used to do rewrites. Fixes #20923 - - - - - df893f66 by Andreas Klebinger at 2022-04-14T08:18:37-04:00 StgLint: Lint constructor applications and strict workers for arity. This will mean T9208 when run with lint will return a lint error instead of resulting in a panic. Fixes #21117 - - - - - 426ec446 by sheaf at 2022-04-14T08:19:16-04:00 Hadrian: use a set to keep track of ways The order in which ways are provided doesn't matter, so we use a data structure with the appropriate semantics to represent ways. Fixes #21378 - - - - - 7c639b9a by Dylan Yudaken at 2022-04-15T13:55:59-04:00 Only enable PROF_SPIN in DEBUG - - - - - 96b9e5ea by Ben Gamari at 2022-04-15T13:56:34-04:00 testsuite: Add test for #21390 - - - - - d8392f6a by Ben Gamari at 2022-04-15T13:56:34-04:00 rts: Ensure that the interpreter doesn't disregard tags Previously the interpreter's handling of `RET_BCO` stack frames would throw away the tag of the returned closure. This resulted in #21390. - - - - - 83c67f76 by Alan Zimmerman at 2022-04-20T11:49:28-04:00 Add -dkeep-comments flag to keep comments in the parser This provides a way to set the Opt_KeepRawTokenStream from the command line, allowing exact print annotation users to see exactly what is produced for a given parsed file, when used in conjunction with -ddump-parsed-ast Discussed in #19706, but this commit does not close the issue. - - - - - a5ea65c9 by Krzysztof Gogolewski at 2022-04-20T11:50:04-04:00 Remove LevityInfo Every Id was storing a boolean whether it could be levity-polymorphic. This information is no longer needed since representation-checking has been moved to the typechecker. - - - - - 49bd7584 by Andreas Klebinger at 2022-04-20T11:50:39-04:00 Fix a shadowing issue in StgUnarise. For I assume performance reasons we don't record no-op replacements during unarise. This lead to problems with code like this: f = \(Eta_B0 :: VoidType) x1 x2 -> ... let foo = \(Eta_B0 :: LiftedType) -> g x y Eta_B0 in ... Here we would record the outer Eta_B0 as void rep, but would not shadow Eta_B0 inside `foo` because this arg is single-rep and so doesn't need to replaced. But this means when looking at occurence sites we would check the env and assume it's void rep based on the entry we made for the (no longer in scope) outer `Eta_B0`. Fixes #21396 and the ticket has a few more details. - - - - - 0c02c919 by Simon Peyton Jones at 2022-04-20T11:51:15-04:00 Fix substitution in bindAuxiliaryDict In GHC.Core.Opt.Specialise.bindAuxiliaryDict we were unnecessarily calling `extendInScope` to bring into scope variables that were /already/ in scope. Worse, GHC.Core.Subst.extendInScope strangely deleted the newly-in-scope variables from the substitution -- and that was fatal in #21391. I removed the redundant calls to extendInScope. More ambitiously, I changed GHC.Core.Subst.extendInScope (and cousins) to stop deleting variables from the substitution. I even changed the names of the function to extendSubstInScope (and cousins) and audited all the calls to check that deleting from the substitution was wrong. In fact there are very few such calls, and they are all about introducing a fresh non-in-scope variable. These are "OutIds"; it is utterly wrong to mess with the "InId" substitution. I have not added a Note, because I'm deleting wrong code, and it'd be distracting to document a bug. - - - - - 0481a6af by Cheng Shao at 2022-04-21T11:06:06+00:00 [ci skip] Drop outdated TODO in RtsAPI.c - - - - - 1e062a8a by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Introduce ip_STACK_FRAME While debugging it is very useful to be able to determine whether a given info table is a stack frame or not. We have spare bits in the closure flags array anyways, use one for this information. - - - - - 08a6a2ee by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Mark closureFlags array as const - - - - - 8f9b8282 by Krzysztof Gogolewski at 2022-04-22T02:13:35-04:00 Check for zero-bit types in sizeExpr Fixes #20940 Metric Decrease: T18698a - - - - - fcf22883 by Andreas Klebinger at 2022-04-22T02:14:10-04:00 Include the way string in the file name for dump files. This can be disabled by `-fno-dump-with-ways` if not desired. Finally we will be able to look at both profiled and non-profiled dumps when compiling with dump flags and we compile in both ways. - - - - - 252394ce by Andrew Lelechenko at 2022-04-22T02:14:48-04:00 Improve error messages from GHC.IO.Encoding.Failure - - - - - 250f57c1 by Andrew Lelechenko at 2022-04-22T02:14:48-04:00 Update test baselines to match new error messages from GHC.IO.Encoding.Failure - - - - - 5ac9b321 by Ben Gamari at 2022-04-22T02:15:25-04:00 get-win32-tarballs: Drop i686 architecture As of #18487 we no longer support 32-bit Windows. Fixes #21372. - - - - - dd5fecb0 by Ben Gamari at 2022-04-22T02:16:00-04:00 hadrian: Don't rely on xxx not being present in installation path Previously Hadrian's installation makefile would assume that the string `xxx` did not appear in the installation path. This would of course break for some users. Fixes #21402. - - - - - 09e98859 by Ben Gamari at 2022-04-22T02:16:35-04:00 testsuite: Ensure that GHC doesn't pick up environment files Here we set GHC_ENVIRONMENT="-" to ensure that GHC invocations of tests don't pick up a user's local package environment. Fixes #21365. Metric Decrease: T10421 T12234 T12425 T13035 T16875 T9198 - - - - - 76bb8cb3 by Ben Gamari at 2022-04-22T02:17:11-04:00 hadrian: Enable -dlint in devel2 flavour Previously only -dcore-lint was enabled. - - - - - f435d55f by Krzysztof Gogolewski at 2022-04-22T08:00:18-04:00 Fixes to rubbish literals * In CoreToStg, the application 'RUBBISH[rep] x' was simplified to 'RUBBISH[rep]'. But it is possible that the result of the function is represented differently than the function. * In Unarise, 'LitRubbish (primRepToType prep)' is incorrect: LitRubbish takes a RuntimeRep such as IntRep, while primRepToType returns a type such as Any @(TYPE IntRep). Use primRepToRuntimeRep instead. This code is never run in the testsuite. * In StgToByteCode, all rubbish literals were assumed to be boxed. This code predates representation-polymorphic RubbishLit and I think it was not updated. I don't have a testcase for any of those issues, but the code looks wrong. - - - - - 93c16b94 by sheaf at 2022-04-22T08:00:57-04:00 Relax "suppressing errors" assert in reportWanteds The assertion in reportWanteds that we aren't suppressing all the Wanted constraints was too strong: it might be the case that we are inside an implication, and have already reported an unsolved Wanted from outside the implication. It is possible that all Wanteds inside the implication have been rewritten by the outer Wanted, so we shouldn't throw an assertion failure in that case. Fixes #21405 - - - - - 78ec692d by Andreas Klebinger at 2022-04-22T08:01:33-04:00 Mention new MutableByteArray# wrapper in base changelog. - - - - - 56d7cb53 by Eric Lindblad at 2022-04-22T14:13:32-04:00 unlist announce - - - - - 1e4dcf23 by sheaf at 2022-04-22T14:14:12-04:00 decideMonoTyVars: account for CoVars in candidates The "candidates" passed to decideMonoTyVars can contain coercion holes. This is because we might well decide to quantify over some unsolved equality constraints, as long as they are not definitely insoluble. In that situation, decideMonoTyVars was passing a set of type variables that was not closed over kinds to closeWrtFunDeps, which was tripping up an assertion failure. Fixes #21404 - - - - - 2c541f99 by Simon Peyton Jones at 2022-04-22T14:14:47-04:00 Improve floated dicts in Specialise Second fix to #21391. It turned out that we missed calling bringFloatedDictsIntoScope when specialising imports, which led to the same bug as before. I refactored to move that call to a single place, in specCalls, so we can't forget it. This meant making `FloatedDictBinds` into its own type, pairing the dictionary bindings themselves with the set of their binders. Nicer this way. - - - - - 0950e2c4 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Ensure that --extra-lib-dirs are used Previously we only took `extraLibDirs` and friends from the package description, ignoring any contribution from the `LocalBuildInfo`. Fix this. Fixes #20566. - - - - - 53cc93ae by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Drop redundant include directories The package-specific include directories in Settings.Builders.Common.cIncludeDirs are now redundant since they now come from Cabal. Closes #20566. - - - - - b2721819 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Clean up handling of libffi dependencies - - - - - 18e5103f by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: More robust library way detection Previously `test.mk` would try to determine whether the dynamic, profiling, and vanilla library ways are available by searching for `PrimOpWrappers.{,dyn_,p_}hi` in directory reported by `ghc-pkg field ghc-prim library-dirs`. However, this is extremely fragile as there is no guarantee that there is only one library directory. To handle the case of multiple `library-dirs` correct we would have to carry out the delicate task of tokenising the directory list (in shell, no less). Since this isn't a task that I am eager to solve, I have rather moved the detection logic into the testsuite driver and instead perform a test compilation in each of the ways. This should be more robust than the previous approach. I stumbled upon this while fixing #20579. - - - - - 6c7a4913 by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: Cabalify ghc-config To ensure that the build benefits from Hadrian's usual logic for building packages, avoiding #21409. Closes #21409. - - - - - 9af091f7 by Ben Gamari at 2022-04-25T10:18:53-04:00 rts: Factor out built-in GC roots - - - - - e7c4719d by Ben Gamari at 2022-04-25T10:18:54-04:00 Ensure that wired-in exception closures aren't GC'd As described in Note [Wired-in exceptions are not CAFfy], a small set of built-in exception closures get special treatment in the code generator, being declared as non-CAFfy despite potentially containing CAF references. The original intent of this treatment for the RTS to then add StablePtrs for each of the closures, ensuring that they are not GC'd. However, this logic was not applied consistently and eventually removed entirely in 951c1fb0. This lead to #21141. Here we fix this bug by reintroducing the StablePtrs and document the status quo. Closes #21141. - - - - - 9587726f by Ben Gamari at 2022-04-25T10:18:54-04:00 testsuite: Add testcase for #21141 - - - - - cb71226f by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop dead code in GHC.Linker.Static.linkBinary' Previously we supported building statically-linked executables using libtool. However, this was dropped in 91262e75dd1d80f8f28a3922934ec7e59290e28c in favor of using ar/ranlib directly. Consequently we can drop this logic. Fixes #18826. - - - - - 9420d26b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop libtool path from settings file GHC no longers uses libtool for linking and therefore this is no longer necessary. - - - - - 41cf758b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop remaining vestiges of libtool Drop libtool logic from gen-dll, allowing us to drop the remaining logic from the `configure` script. Strangely, this appears to reliably reduce compiler allocations of T16875 on Windows. Closes #18826. Metric Decrease: T16875 - - - - - e09afbf2 by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - e76705cf by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Improve documentation of closure types Also drops the unused TREC_COMMITTED transaction state. - - - - - f2c08124 by Andrew Lelechenko at 2022-04-25T10:20:44-04:00 Document behaviour of RULES with KnownNat - - - - - 360dc2bc by Li-yao Xia at 2022-04-25T19:13:06+00:00 Fix rendering of liftA haddock - - - - - 16df6058 by Ben Gamari at 2022-04-27T10:02:25-04:00 testsuite: Report minimum and maximum stat changes As suggested in #20733. - - - - - e39cab62 by Fabian Thorand at 2022-04-27T10:03:03-04:00 Defer freeing of mega block groups Solves the quadratic worst case performance of freeing megablocks that was described in issue #19897. During GC runs, we now keep a secondary free list for megablocks that is neither sorted, nor coalesced. That way, free becomes an O(1) operation at the expense of not being able to reuse memory for larger allocations. At the end of a GC run, the secondary free list is sorted and then merged into the actual free list in a single pass. That way, our worst case performance is O(n log(n)) rather than O(n^2). We postulate that temporarily losing coalescense during a single GC run won't have any adverse effects in practice because: - We would need to release enough memory during the GC, and then after that (but within the same GC run) allocate a megablock group of more than one megablock. This seems unlikely, as large objects are not copied during GC, and so we shouldn't need such large allocations during a GC run. - Allocations of megablock groups of more than one megablock are rare. They only happen when a single heap object is large enough to require that amount of space. Any allocation areas that are supposed to hold more than one heap object cannot use megablock groups, because only the first megablock of a megablock group has valid `bdescr`s. Thus, heap object can only start in the first megablock of a group, not in later ones. - - - - - 5de6be0c by Fabian Thorand at 2022-04-27T10:03:03-04:00 Add note about inefficiency in returnMemoryToOS - - - - - 8bef471a by sheaf at 2022-04-27T10:03:43-04:00 Ensure that Any is Boxed in FFI imports/exports We should only accept the type `Any` in foreign import/export declarations when it has type `Type` or `UnliftedType`. This patch adds a kind check, and a special error message triggered by occurrences of `Any` in foreign import/export declarations at other kinds. Fixes #21305 - - - - - ba3d4e1c by Ben Gamari at 2022-04-27T10:04:19-04:00 Basic response file support Here we introduce support into our command-line parsing infrastructure and driver for handling gnu-style response file arguments, typically used to work around platform command-line length limitations. Fixes #16476. - - - - - 3b6061be by Ben Gamari at 2022-04-27T10:04:19-04:00 testsuite: Add test for #16476 - - - - - 75bf1337 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix cabal-reinstall job It's quite nice we can do this by mostly deleting code Fixes #21373 - - - - - 2c00d904 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add test to check that release jobs have profiled libs - - - - - 50d78d3b by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Explicitly handle failures in test_hadrian We also disable the stage1 testing which is broken. Related to #21072 - - - - - 2dcdf091 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix shell command - - - - - 55c84123 by Matthew Pickering at 2022-04-27T10:04:55-04:00 bootstrap: Add bootstrapping files for ghc-9_2_2 Fixes #21373 - - - - - c7ee0be6 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add linting job which checks authors are not GHC CI - - - - - 23aad124 by Adam Sandberg Ericsson at 2022-04-27T10:05:31-04:00 rts: state explicitly what evacuate and scavange mean in the copying gc - - - - - 318e0005 by Ben Gamari at 2022-04-27T10:06:07-04:00 rts/eventlog: Don't attempt to flush if there is no writer If the user has not configured a writer then there is nothing to flush. - - - - - ee11d043 by Ben Gamari at 2022-04-27T10:06:07-04:00 Enable eventlog support in all ways by default Here we deprecate the eventlogging RTS ways and instead enable eventlog support in the remaining ways. This simplifies packaging and reduces GHC compilation times (as we can eliminate two whole compilations of the RTS) while simplifying the end-user story. The trade-off is a small increase in binary sizes in the case that the user does not want eventlogging support, but we think that this is a fine trade-off. This also revealed a latent RTS bug: some files which included `Cmm.h` also assumed that it defined various macros which were in fact defined by `Config.h`, which `Cmm.h` did not include. Fixing this in turn revealed that `StgMiscClosures.cmm` failed to import various spinlock statistics counters, as evidenced by the failed unregisterised build. Closes #18948. - - - - - a2e5ab70 by Andreas Klebinger at 2022-04-27T10:06:43-04:00 Change `-dsuppress-ticks` to only suppress non-code ticks. This means cost centres and coverage ticks will still be present in output. Makes using -dsuppress-all more convenient when looking at profiled builds. - - - - - ec9d7e04 by Ben Gamari at 2022-04-27T10:07:21-04:00 Bump text submodule. This should fix #21352 - - - - - c3105be4 by Andrew Lelechenko at 2022-04-27T10:08:01-04:00 Documentation for setLocaleEncoding - - - - - 7f618fd3 by sheaf at 2022-04-27T10:08:40-04:00 Update docs for change to type-checking plugins There was no mention of the changes to type-checking plugins in the 9.4.1 notes, and the extending_ghc documentation contained a reference to an outdated type. - - - - - 4419dd3a by Adam Sandberg Ericsson at 2022-04-27T10:09:18-04:00 rts: add some more documentation to StgWeak closure type - - - - - 5a7f0dee by Matthew Pickering at 2022-04-27T10:09:54-04:00 Give Cmm files fake ModuleNames which include full filepath This fixes the initialisation functions when using -prof or -finfo-table-map. Fixes #21370 - - - - - 81cf52bb by sheaf at 2022-04-27T10:10:33-04:00 Mark GHC.Prim.PtrEq as Unsafe This module exports unsafe pointer equality operations, so we accordingly mark it as Unsafe. Fixes #21433 - - - - - f6a8185d by Ben Gamari at 2022-04-28T09:10:31+00:00 testsuite: Add performance test for #14766 This distills the essence of the Sigs.hs program found in the ticket. - - - - - c7a3dc29 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Add Monoid instance to Way - - - - - 654bafea by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Enrich flavours to build profiled/debugged/threaded ghcs per stage - - - - - 4ad559c8 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: add debug_ghc and debug_stage1_ghc flavour transformers - - - - - f9728fdb by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Don't pass -rtsopts when building libraries - - - - - 769279e6 by Matthew Pickering at 2022-04-28T18:54:44-04:00 testsuite: Fix calculation about whether to pass -dynamic to compiler - - - - - da8ae7f2 by Ben Gamari at 2022-04-28T18:55:20-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 61305184 by Ben Gamari at 2022-04-28T18:55:56-04:00 Bump process submodule - - - - - a8c99391 by sheaf at 2022-04-28T18:56:37-04:00 Fix unification of ConcreteTvs, removing IsRefl# This patch fixes the unification of concrete type variables. The subtlety was that unifying concrete metavariables is more subtle than other metavariables, as decomposition is possible. See the Note [Unifying concrete metavariables], which explains how we unify a concrete type variable with a type 'ty' by concretising 'ty', using the function 'GHC.Tc.Utils.Concrete.concretise'. This can be used to perform an eager syntactic check for concreteness, allowing us to remove the IsRefl# special predicate. Instead of emitting two constraints `rr ~# concrete_tv` and `IsRefl# rr concrete_tv`, we instead concretise 'rr'. If this succeeds we can fill 'concrete_tv', and otherwise we directly emit an error message to the typechecker environment instead of deferring. We still need the error message to be passed on (instead of directly thrown), as we might benefit from further unification in which case we will need to zonk the stored types. To achieve this, we change the 'wc_holes' field of 'WantedConstraints' to 'wc_errors', which stores general delayed errors. For the moement, a delayed error is either a hole, or a syntactic equality error. hasFixedRuntimeRep_MustBeRefl is now hasFixedRuntimeRep_syntactic, and hasFixedRuntimeRep has been refactored to directly return the most useful coercion for PHASE 2 of FixedRuntimeRep. This patch also adds a field ir_frr to the InferResult datatype, holding a value of type Maybe FRROrigin. When this value is not Nothing, this means that we must fill the ir_ref field with a type which has a fixed RuntimeRep. When it comes time to fill such an ExpType, we ensure that the type has a fixed RuntimeRep by performing a representation-polymorphism check with the given FRROrigin This is similar to what we already do to ensure we fill an Infer ExpType with a type of the correct TcLevel. This allows us to properly perform representation-polymorphism checks on 'Infer' 'ExpTypes'. The fillInferResult function had to be moved to GHC.Tc.Utils.Unify to avoid a cyclic import now that it calls hasFixedRuntimeRep. This patch also changes the code in matchExpectedFunTys to make use of the coercions, which is now possible thanks to the previous change. This implements PHASE 2 of FixedRuntimeRep in some situations. For example, the test cases T13105 and T17536b are now both accepted. Fixes #21239 and #21325 ------------------------- Metric Decrease: T18223 T5631 ------------------------- - - - - - 43bd897d by Simon Peyton Jones at 2022-04-28T18:57:13-04:00 Add INLINE pragmas for Enum helper methods As #21343 showed, we need to be super-certain that the "helper methods" for Enum instances are actually inlined or specialised. I also tripped over this when I discovered that numericEnumFromTo and friends had no pragmas at all, so their performance was very fragile. If they weren't inlined, all bets were off. So I've added INLINE pragmas for them too. See new Note [Inline Enum method helpers] in GHC.Enum. I also expanded Note [Checking for INLINE loop breakers] in GHC.Core.Lint to explain why an INLINE function might temporarily be a loop breaker -- this was the initial bug report in #21343. Strangely we get a 16% runtime allocation decrease in perf/should_run/T15185, but only on i386. Since it moves in the right direction I'm disinclined to investigate, so I'll accept it. Metric Decrease: T15185 - - - - - ca1434e3 by Ben Gamari at 2022-04-28T18:57:49-04:00 configure: Bump GHC version to 9.5 Bumps haddock submodule. - - - - - 292e3971 by Teo Camarasu at 2022-04-28T18:58:28-04:00 add since annotation for GHC.Stack.CCS.whereFrom - - - - - 905206d6 by Tamar Christina at 2022-04-28T22:19:34-04:00 winio: add support to iserv. - - - - - d182897e by Tamar Christina at 2022-04-28T22:19:34-04:00 Remove unused line - - - - - 22cf4698 by Matthew Pickering at 2022-04-28T22:20:10-04:00 Revert "rts: Refactor handling of dead threads' stacks" This reverts commit e09afbf2a998beea7783e3de5dce5dd3c6ff23db. - - - - - 8ed57135 by Matthew Pickering at 2022-04-29T04:11:29-04:00 Provide efficient unionMG function for combining two module graphs. This function is used by API clients (hls). This supercedes !6922 - - - - - 0235ff02 by Ben Gamari at 2022-04-29T04:12:05-04:00 Bump bytestring submodule Update to current `master`. - - - - - 01988418 by Matthew Pickering at 2022-04-29T04:12:05-04:00 testsuite: Normalise package versions in UnusedPackages test - - - - - 724d0dc0 by Matthew Pickering at 2022-04-29T08:59:42+00:00 testsuite: Deduplicate ways correctly This was leading to a bug where we would run a profasm test twice which led to invalid junit.xml which meant the test results database was not being populated for the fedora33-perf job. - - - - - 5630dde6 by Ben Gamari at 2022-04-29T13:06:20-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - 0cdef807 by parsonsmatt at 2022-04-30T16:51:12-04:00 Add a note about instance visibility across component boundaries In principle, the *visible* instances are * all instances defined in a prior top-level declaration group (see docs on `newDeclarationGroup`), or * all instances defined in any module transitively imported by the module being compiled However, actually searching all modules transitively below the one being compiled is unreasonably expensive, so `reifyInstances` will report only the instance for modules that GHC has had some cause to visit during this compilation. This is a shortcoming: `reifyInstances` might fail to report instances for a type that is otherwise unusued, or instances defined in a different component. You can work around this shortcoming by explicitly importing the modules whose instances you want to be visible. GHC issue #20529 has some discussion around this. Fixes #20529 - - - - - e2dd884a by Ryan Scott at 2022-04-30T16:51:47-04:00 Make mkFunCo take AnonArgFlags into account Previously, whenever `mkFunCo` would produce reflexive coercions, it would use `mkVisFunTy` to produce the kind of the coercion. However, `mkFunCo` is also used to produce coercions between types of the form `ty1 => ty2` in certain places. This has the unfortunate side effect of causing the type of the coercion to appear as `ty1 -> ty2` in certain error messages, as spotted in #21328. This patch address this by changing replacing the use of `mkVisFunTy` with `mkFunctionType` in `mkFunCo`. `mkFunctionType` checks the kind of `ty1` and makes the function arrow `=>` instead of `->` if `ty1` has kind `Constraint`, so this should always produce the correct `AnonArgFlag`. As a result, this patch fixes part (2) of #21328. This is not the only possible way to fix #21328, as the discussion on that issue lists some possible alternatives. Ultimately, it was concluded that the alternatives would be difficult to maintain, and since we already use `mkFunctionType` in `coercionLKind` and `coercionRKind`, using `mkFunctionType` in `mkFunCo` is consistent with this choice. Moreover, using `mkFunctionType` does not regress the performance of any test case we have in GHC's test suite. - - - - - 170da54f by Ben Gamari at 2022-04-30T16:52:27-04:00 Convert More Diagnostics (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors. - - - - - 39edc7b4 by Marius Ghita at 2022-04-30T16:53:06-04:00 Update user guide example rewrite rules formatting Change the rewrite rule examples to include a space between the composition of `f` and `g` in the map rewrite rule examples. Without this change, if the user has locally enabled the extension OverloadedRecordDot the copied example will result in a compile time error that `g` is not a field of `f`. ``` • Could not deduce (GHC.Records.HasField "g" (a -> b) (a1 -> b)) arising from selecting the field ‘g’ ``` - - - - - 2e951e48 by Adam Sandberg Ericsson at 2022-04-30T16:53:42-04:00 ghc-boot: export typesynonyms from GHC.Utils.Encoding This makes the Haddocks easier to understand. - - - - - d8cbc77e by Adam Sandberg Ericsson at 2022-04-30T16:54:18-04:00 users guide: add categories to some flags - - - - - d0f14fad by Chris Martin at 2022-04-30T16:54:57-04:00 hacking guide: mention the core libraries committee - - - - - 34b28200 by Matthew Pickering at 2022-04-30T16:55:32-04:00 Revert "Make the specialiser handle polymorphic specialisation" This reverts commit ef0135934fe32da5b5bb730dbce74262e23e72e8. See ticket #21229 ------------------------- Metric Decrease: T15164 Metric Increase: T13056 ------------------------- - - - - - ee891c1e by Matthew Pickering at 2022-04-30T16:55:32-04:00 Add test for T21229 - - - - - ab677cc8 by Matthew Pickering at 2022-04-30T16:56:08-04:00 Hadrian: Update README about the flavour/testsuite contract There have been a number of tickets about non-tested flavours not passing the testsuite.. this is expected and now noted in the documentation. You use other flavours to run the testsuite at your own risk. Fixes #21418 - - - - - b57b5b92 by Ben Gamari at 2022-04-30T16:56:44-04:00 rts/m32: Fix assertion failure This fixes an assertion failure in the m32 allocator due to the imprecisely specified preconditions of `m32_allocator_push_filled_list`. Specifically, the caller must ensure that the page type is set to filled prior to calling `m32_allocator_push_filled_list`. While this issue did result in an assertion failure in the debug RTS, the issue is in fact benign. - - - - - a7053a6c by sheaf at 2022-04-30T16:57:23-04:00 Testsuite driver: don't crash on empty metrics The testsuite driver crashed when trying to display minimum/maximum performance changes when there are no metrics (i.e. there is no baseline available). This patch fixes that. - - - - - 636f7c62 by Andreas Klebinger at 2022-05-01T22:21:17-04:00 StgLint: Check that functions are applied to compatible runtime reps We use compatibleRep to compare reps, and avoid checking functions with levity polymorphic types because of #21399. - - - - - 60071076 by Hécate Moonlight at 2022-05-01T22:21:55-04:00 Add documentation to the ByteArray# primetype. close #21417 - - - - - 2b2e3020 by Andreas Klebinger at 2022-05-01T22:22:31-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. - - - - - 4eaf0f33 by Eric Lindblad at 2022-05-01T22:23:11-04:00 typos - - - - - fc58df90 by Niklas Hambüchen at 2022-05-02T08:59:27+00:00 libraries/base: docs: Explain relationshipt between `finalizeForeignPtr` and `*Conc*` creation Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/21420 - - - - - 3e400f20 by Krzysztof Gogolewski at 2022-05-02T18:29:23-04:00 Remove obsolete code in CoreToStg Note [Nullary unboxed tuple] was removed in e9e61f18a548b70693f4. This codepath is tested by T15696_3. - - - - - 4a780928 by Krzysztof Gogolewski at 2022-05-02T18:29:24-04:00 Fix several note references - - - - - 15ffe2b0 by Sebastian Graf at 2022-05-03T20:11:51+02:00 Assume at least one evaluation for nested SubDemands (#21081, #21133) See the new `Note [SubDemand denotes at least one evaluation]`. A demand `n :* sd` on a let binder `x=e` now means > "`x` was evaluated `n` times and in any program trace it is evaluated, `e` is > evaluated deeply in sub-demand `sd`." The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081) ```hs f :: (Bool, Bool) -> (Bool, Bool) f pr = (case pr of (a,b) -> a /= b, True) -- before: <MP(L,L)> -- after: <MP(SL,SL)> g :: Int -> (Bool, Bool) g x = let y = let z = odd x in (z,z) in f y ``` The change in demand signature "before" to "after" allows us to case-bind `z` here. Similarly good things happen for the `sd` in call sub-demands `Cn(sd)`, which allows for more eta-reduction (which is only sound with `-fno-pedantic-bottoms`, albeit). We also fix #21085, a surprising inconsistency with `Poly` to `Call` sub-demand expansion. In an attempt to fix a regression caused by less inlining due to eta-reduction in T15426, I eta-expanded the definition of `elemIndex` and `elemIndices`, thus fixing #21345 on the go. The main point of this patch is that it fixes #21081 and #21133. Annoyingly, I discovered that more precise demand signatures for join points can transform a program into a lazier program if that join point gets floated to the top-level, see #21392. There is no simple fix at the moment, but !5349 might. Thus, we accept a ~5% regression in `MultiLayerModulesTH_OneShot`, where #21392 bites us in `addListToUniqDSet`. T21392 reliably reproduces the issue. Surprisingly, ghc/alloc perf on Windows improves much more than on other jobs, by 0.4% in the geometric mean and by 2% in T16875. Metric Increase: MultiLayerModulesTH_OneShot Metric Decrease: T16875 - - - - - 948c7e40 by Andreas Klebinger at 2022-05-04T09:57:34-04:00 CoreLint - When checking for levity polymorphism look through more ticks. For expressions like `(scc<cc_name> primOp#) arg1` we should also look at arg1 to determine if we call primOp# at a fixed runtime rep. This is what corePrep already does but CoreLint didn't yet. This patch will bring them in sync in this regard. It also uses tickishFloatable in CorePrep instead of CorePrep having it's own slightly differing definition of when a tick is floatable. - - - - - 85bc73bd by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Support Unicode properly - - - - - 063d485e by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Replace LaTeX documentation syntax with Haddock The LaTeX documentation generator does not seem to have been used for quite some time, so the LaTeX-to-Haddock preprocessing step has become a pointless complication that makes documenting the contents of GHC.Prim needlessly difficult. This commit replaces the LaTeX syntax with the Haddock it would have been converted into, anyway, though with an additional distinction: it uses single quotes in places to instruct Haddock to generate hyperlinks to bindings. This improves the quality of the generated output. - - - - - d61f7428 by Ben Gamari at 2022-05-04T09:58:50-04:00 rts/ghc.mk: Only build StgCRunAsm.S when it is needed Previously the make build system unconditionally included StgCRunAsm.S in the link, meaning that the RTS would require an execstack unnecessarily. Fixes #21478. - - - - - 934a90dd by Simon Peyton Jones at 2022-05-04T16:15:34-04:00 Improve error reporting in generated code Our error reporting in generated code (via desugaring before typechecking) only worked when the generated code was just a simple call. This commit makes it work in nested cases. - - - - - 445d3657 by sheaf at 2022-05-04T16:16:12-04:00 Ensure Any is not levity-polymorphic in FFI The previous patch forgot to account for a type such as Any @(TYPE (BoxedRep l)) for a quantified levity variable l. - - - - - ddd2591c by Ben Gamari at 2022-05-04T16:16:48-04:00 Update supported LLVM versions Pull forward minimum version to match 9.2. (cherry picked from commit c26faa54c5fbe902ccb74e79d87e3fa705e270d1) - - - - - f9698d79 by Ben Gamari at 2022-05-04T16:16:48-04:00 testsuite/T7275: Use sed -r Darwin requires the `-r` flag to be compatible with GNU sed. (cherry picked from commit 512338c8feec96c38ef0cf799f3a01b77c967c56) - - - - - 8635323b by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Use ld.lld on ARMv7/Linux Due to #16177. Also cleanup some code style issues. (cherry picked from commit cc1c3861e2372f464bf9e3c9c4d4bd83f275a1a6) - - - - - 4f6370c7 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Always preserve artifacts, even in failed jobs (cherry picked from commit fd08b0c91ea3cab39184f1b1b1aafcd63ce6973f) - - - - - 6f662754 by Ben Gamari at 2022-05-04T16:16:48-04:00 configure: Make sphinx version check more robust It appears that the version of sphinx shipped on CentOS 7 reports a version string of `Sphinx v1...`. Accept the `v`. (cherry picked from commit a9197a292fd4b13308dc6664c01351c7239357ed) - - - - - 0032dc38 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Don't run make job in release pipelines (cherry picked from commit 16d6a8ff011f2194485387dcca1c00f8ddcdbdeb) - - - - - 27f9aab3 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab/ci: Fix name of bootstrap compiler directory Windows binary distributions built with Hadrian have a target platform suffix in the name of their root directory. Teach `ci.sh` about this fact. (cherry picked from commit df5752f39671f6d04d8cd743003469ae5eb67235) - - - - - b528f0f6 by Krzysztof Gogolewski at 2022-05-05T09:05:43-04:00 Fix several note references, part 2 - - - - - 691aacf6 by Adam Sandberg Ericsson at 2022-05-05T09:06:19-04:00 adjustors: align comment about number of integer like arguments with implementation for Amd4+MinGW implementation - - - - - f050557e by Simon Jakobi at 2022-05-05T12:47:32-04:00 Remove two uses of IntMap.size IntMap.size is O(n). The new code should be slightly more efficient. The transformation of GHC.CmmToAsm.CFG.calcFreqs.nodeCount can be described formally as the transformation: (\sum_{0}^{n-1} \sum_{0}^{k-1} i_nk) + n ==> (\sum_{0}^{n-1} 1 + \sum_{0}^{k-1} i_nk) - - - - - 7da90ae3 by Tom Ellis at 2022-05-05T12:48:09-04:00 Explain that 'fail s' should run in the monad itself - - - - - 610d0283 by Matthew Craven at 2022-05-05T12:48:47-04:00 Add a test for the bracketing in rules for (^) - - - - - 016f9ca6 by Matthew Craven at 2022-05-05T12:48:47-04:00 Fix broken rules for (^) with known small powers - - - - - 9372aaab by Matthew Craven at 2022-05-05T12:48:47-04:00 Give the two T19569 tests different names - - - - - 61901b32 by Andreas Klebinger at 2022-05-05T12:49:23-04:00 SpecConstr: Properly create rules for call patterns representing partial applications The main fix is that in addVoidWorkerArg we now add the argument to the front. This fixes #21448. ------------------------- Metric Decrease: T16875 ------------------------- - - - - - 71278dc7 by Teo Camarasu at 2022-05-05T12:50:03-04:00 add since annotations for instances of ByteArray - - - - - 962ff90b by sheaf at 2022-05-05T12:50:42-04:00 Start 9.6.1-notes Updates the documentation notes to start tracking changes for the 9.6.1 release (instead of 9.4). - - - - - aacb15a3 by Matthew Pickering at 2022-05-05T20:24:01-04:00 ci: Add job to check that jobs.yaml is up-to-date There have been quite a few situations where jobs.yaml has been out of date. It's better to add a CI job which checks that it's right. We don't want to use a staged pipeline because it obfuscates the structure of the pipeline. - - - - - be7102e5 by Ben Gamari at 2022-05-05T20:24:37-04:00 rts: Ensure that XMM registers are preserved on Win64 Previously we only preserved the bottom 64-bits of the callee-saved 128-bit XMM registers, in violation of the Win64 calling convention. Fix this. Fixes #21465. - - - - - 73b22ff1 by Ben Gamari at 2022-05-05T20:24:37-04:00 testsuite: Add test for #21465 - - - - - e2ae9518 by Ziyang Liu at 2022-05-06T19:22:22-04:00 Allow `let` just before pure/return in ApplicativeDo The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case. - - - - - 0415449a by Matthew Pickering at 2022-05-06T19:22:58-04:00 template-haskell: Fix representation of OPAQUE pragmas There is a mis-match between the TH representation of OPAQUE pragmas and GHC's internal representation due to how OPAQUE pragmas disallow phase annotations. It seemed most in keeping to just fix the wired in name issue by adding a special case to the desugaring of INLINE pragmas rather than making TH/GHC agree with how the representation should look. Fixes #21463 - - - - - 4de887e2 by Simon Peyton Jones at 2022-05-06T19:23:34-04:00 Comments only: Note [AppCtxt] - - - - - 6e69964d by Matthew Pickering at 2022-05-06T19:24:10-04:00 Fix name of windows release bindist in doc-tarball job - - - - - ced4689e by Matthew Pickering at 2022-05-06T19:24:46-04:00 ci: Generate source-tarball in release jobs We need to distribute the source tarball so we should generate it in the CI pipeline. - - - - - 3c91de21 by Rob at 2022-05-08T13:40:53+02:00 Change Specialise to use OrdList. Fixes #21362 Metric Decrease: T16875 - - - - - 67072c31 by Simon Jakobi at 2022-05-08T12:23:43-04:00 Tweak GHC.CmmToAsm.CFG.delEdge mapAdjust is more efficient than mapAlter. - - - - - 374554bb by Teo Camarasu at 2022-05-09T16:24:37-04:00 Respect -po when heap profiling (#21446) - - - - - 1ea414b6 by Teo Camarasu at 2022-05-09T16:24:37-04:00 add test case for #21446 - - - - - c7902078 by Jens Petersen at 2022-05-09T16:25:17-04:00 avoid hadrian/bindist/Makefile install_docs error when --docs=none When docs are disabled the bindist does not have docs/ and hence docs-utils/ is not generated. Here we just test that docs-utils exists before attempting to install prologue.txt and gen_contents_index to avoid the error: /usr/bin/install: cannot stat 'docs-utils/prologue.txt': No such file or directory make: *** [Makefile:195: install_docs] Error 1 - - - - - 158bd659 by Hécate Moonlight at 2022-05-09T16:25:56-04:00 Correct base's changelog for 4.16.1.0 This commit reaffects the new Ix instances of the foreign integral types from base 4.17 to 4.16.1.0 closes #21529 - - - - - a4fbb589 by Sylvain Henry at 2022-05-09T16:26:36-04:00 STG: only print cost-center if asked to - - - - - 50347ded by Gergő Érdi at 2022-05-10T11:43:33+00:00 Improve "Glomming" note Add a paragraph that clarifies that `occurAnalysePgm` finding out-of-order references, and thus needing to glom, is not a cause for concern when its root cause is rewrite rules. - - - - - df2e3373 by Eric Lindblad at 2022-05-10T20:45:41-04:00 update INSTALL - - - - - dcac3833 by Matthew Pickering at 2022-05-10T20:46:16-04:00 driver: Make -no-keep-o-files -no-keep-hi-files work in --make mode It seems like it was just an oversight to use the incorrect DynFlags (global rather than local) when implementing these two options. Using the local flags allows users to request these intermediate files get cleaned up, which works fine in --make mode because 1. Interface files are stored in memory 2. Object files are only cleaned at the end of session (after link) Fixes #21349 - - - - - 35da81f8 by Ben Gamari at 2022-05-10T20:46:52-04:00 configure: Check for ffi.h As noted in #21485, we checked for ffi.h yet then failed to throw an error if it is missing. Fixes #21485. - - - - - bdc99cc2 by Simon Peyton Jones at 2022-05-10T20:47:28-04:00 Check for uninferrable variables in tcInferPatSynDecl This fixes #21479 See Note [Unquantified tyvars in a pattern synonym] While doing this, I found that some error messages pointed at the pattern synonym /name/, rather than the /declaration/ so I widened the SrcSpan to encompass the declaration. - - - - - 142a73d9 by Matthew Pickering at 2022-05-10T20:48:04-04:00 hadrian: Fix split-sections transformer The splitSections transformer has been broken since -dynamic-too support was implemented in hadrian. This is because we actually build the dynamic way when building the dynamic way, so the predicate would always fail. The fix is to just always pass `split-sections` even if it doesn't do anything for a particular way. Fixes #21138 - - - - - 699f5935 by Matthew Pickering at 2022-05-10T20:48:04-04:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. Closes #21135 - - - - - 21feece2 by Simon Peyton Jones at 2022-05-10T20:48:39-04:00 Use the wrapper for an unlifted binding We assumed the wrapper for an unlifted binding is the identity, but as #21516 showed, that is no always true. Solution is simple: use it. - - - - - 68d1ea5f by Matthew Pickering at 2022-05-10T20:49:15-04:00 docs: Fix path to GHC API docs in index.html In the make bindists we generate documentation in docs/ghc-<VER> but the hadrian bindists generate docs/ghc/ so the path to the GHC API docs was wrong in the index.html file. Rather than make the hadrian and make bindists the same it was easier to assume that if you're using the mkDocs script that you're using hadrian bindists. Fixes #21509 - - - - - 9d8f44a9 by Matthew Pickering at 2022-05-10T20:49:51-04:00 hadrian: Don't pass -j to haddock This has high potential for oversubcribing as many haddock jobs can be spawned in parralel which will each request the given number of capabilities. Once -jsem is implemented (#19416, !5176) we can expose that haddock via haddock and use that to pass a semaphore. Ticket #21136 - - - - - fec3e7aa by Matthew Pickering at 2022-05-10T20:50:27-04:00 hadrian: Only copy and install libffi headers when using in-tree libffi When passed `--use-system-libffi` then we shouldn't copy and install the headers from the system package. Instead the headers are expected to be available as a runtime dependency on the users system. Fixes #21485 #21487 - - - - - 5b791ed3 by mikael at 2022-05-11T08:22:13-04:00 FIND_LLVM_PROG: Recognize llvm suffix used by FreeBSD, ie llc10. - - - - - 8500206e by ARATA Mizuki at 2022-05-11T08:22:57-04:00 Make floating-point abs IEEE 754 compliant The old code used by via-C backend didn't handle the sign bit of NaN. See #21043. - - - - - 4a4c77ed by Alan Zimmerman at 2022-05-11T08:23:33-04:00 EPA: do statement with leading semicolon has wrong anchor The code do; a <- doAsync; b Generated an incorrect Anchor for the statement list that starts after the first semicolon. This commit fixes it. Closes #20256 - - - - - e3ca8dac by Simon Peyton Jones at 2022-05-11T08:24:08-04:00 Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. - - - - - fcc7dc4c by Ben Gamari at 2022-05-11T20:05:41-04:00 gitlab-ci: Check for dynamic msys2 dependencies Both #20878 and #21196 were caused by unwanted dynamic dependencies being introduced by boot libraries. Ensure that we catch this in CI by attempting to run GHC in an environment with a minimal PATH. - - - - - 3c998f0d by Matthew Pickering at 2022-05-11T20:06:16-04:00 Add back Debian9 CI jobs We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19 not being at EOL until April 2023 and they still need tinfo5. Fixes #21469 - - - - - dea9a3d9 by Ben Gamari at 2022-05-11T20:06:51-04:00 rts: Drop setExecutable Since f6e366c058b136f0789a42222b8189510a3693d1 setExecutable has been dead code. Drop it. - - - - - 32cdf62d by Simon Peyton Jones at 2022-05-11T20:07:27-04:00 Add a missing guard in GHC.HsToCore.Utils.is_flat_prod_pat This missing guard gave rise to #21519. - - - - - 2c00a8d0 by Matthew Pickering at 2022-05-11T20:08:02-04:00 Add mention of -hi to RTS --help Fixes #21546 - - - - - a2dcad4e by Andre Marianiello at 2022-05-12T02:15:48+00:00 Decouple dynflags in Cmm parser (related to #17957) - - - - - 3a022baa by Andre Marianiello at 2022-05-12T02:15:48+00:00 Remove Module argument from initCmmParserConfig - - - - - 2fc8d76b by Andre Marianiello at 2022-05-12T02:15:48+00:00 Move CmmParserConfig and PDConfig into GHC.Cmm.Parser.Config - - - - - b8c5ffab by Andre Marianiello at 2022-05-12T18:13:55-04:00 Decouple dynflags in GHC.Core.Opt.Arity (related to #17957) Metric Decrease: T16875 - - - - - 3bf938b6 by sheaf at 2022-05-12T18:14:34-04:00 Update extending_ghc for TcPlugin changes The documentation still mentioned Derived constraints and an outdated datatype TcPluginResult. - - - - - 668a9ef4 by jackohughes at 2022-05-13T12:10:34-04:00 Fix printing of brackets in multiplicities (#20315) Change mulArrow to allow for printing of correct application precedence where necessary and update callers of mulArrow to reflect this. As part of this, move mulArrow from GHC/Utils/Outputtable to GHC/Iface/Type. Fixes #20315 - - - - - 30b8b7f1 by Ben Gamari at 2022-05-13T12:11:09-04:00 rts: Add debug output on ocResolve failure This makes it easier to see how resolution failures nest. - - - - - 53b3fa1c by Ben Gamari at 2022-05-13T12:11:09-04:00 rts/PEi386: Fix handling of weak symbols Previously we would flag the symbol as weak but failed to set its address, which must be computed from an "auxiliary" symbol entry the follows the weak symbol. Fixes #21556. - - - - - 5678f017 by Ben Gamari at 2022-05-13T12:11:09-04:00 testsuite: Add tests for #21556 - - - - - 49af0e52 by Ben Gamari at 2022-05-13T22:23:26-04:00 Re-export augment and build from GHC.List Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/19127 - - - - - aed356e1 by Simon Peyton Jones at 2022-05-13T22:24:02-04:00 Comments only around HsWrapper - - - - - 27b90409 by Ben Gamari at 2022-05-16T08:30:44-04:00 hadrian: Introduce linting flavour transformer (+lint) The linting flavour enables -dlint uniformly across anything build by the stage1 compiler. -dcmm-lint is not currently enabled because it fails on i386 (see #21563) - - - - - 3f316776 by Matthew Pickering at 2022-05-16T08:30:44-04:00 hadrian: Uniformly enable -dlint with enableLinting transformer This fixes some bugs where * -dcore-lint was being passed when building stage1 libraries with the boot compiler * -dcore-lint was not being passed when building executables. Fixes #20135 - - - - - 3d74cfca by Andreas Klebinger at 2022-05-16T08:31:20-04:00 Make closure macros EXTERN_INLINE to make debugging easier Implements #21424. The RTS macros get_itbl and friends are extremely helpful during debugging. However only a select few of those were available in the compiled RTS as actual symbols as the rest were INLINE macros. This commit marks all of them as EXTERN_INLINE. This will still inline them at use sites but allow us to use their compiled counterparts during debugging. This allows us to use things like `p get_fun_itbl(ptr)` in the gdb shell since `get_fun_itbl` will now be available as symbol! - - - - - 93153aab by Matthew Pickering at 2022-05-16T08:31:55-04:00 packaging: Introduce CI job for generating hackage documentation This adds a CI job (hackage-doc-tarball) which generates the necessary tarballs for uploading libraries and documentation to hackage. The release script knows to download this folder and the upload script will also upload the release to hackage as part of the release. The `ghc_upload_libs` script is moved from ghc-utils into .gitlab/ghc_upload_libs There are two modes, preparation and upload. * The `prepare` mode takes a link to a bindist and creates a folder containing the source and doc tarballs ready to upload to hackage. * The `upload` mode takes the folder created by prepare and performs the upload to hackage. Fixes #21493 Related to #21512 - - - - - 65d31d05 by Simon Peyton Jones at 2022-05-16T15:32:50-04:00 Add arity to the INLINE pragmas for pattern synonyms The lack of INLNE arity was exposed by #21531. The fix is simple enough, if a bit clumsy. - - - - - 43c018aa by Krzysztof Gogolewski at 2022-05-16T15:33:25-04:00 Misc cleanup - Remove groupWithName (unused) - Use the RuntimeRepType synonym where possible - Replace getUniqueM + mkSysLocalOrCoVar with mkSysLocalOrCoVarM No functional changes. - - - - - 8dfea078 by Pavol Vargovcik at 2022-05-16T15:34:04-04:00 TcPlugin: access to irreducible givens + fix passed ev_binds_var - - - - - fb579e15 by Ben Gamari at 2022-05-17T00:25:02-04:00 driver: Introduce pgmcxx Here we introduce proper support for compilation of C++ objects. This includes: * logic in `configure` to detect the C++ toolchain and propagating this information into the `settings` file * logic in the driver to use the C++ toolchain when compiling C++ sources - - - - - 43628ed4 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Build T20918 with HC, not CXX - - - - - 0ef249aa by Ben Gamari at 2022-05-17T00:25:02-04:00 Introduce package to capture dependency on C++ stdlib Here we introduce a new "virtual" package into the initial package database, `system-cxx-std-lib`. This gives users a convenient, platform agnostic way to link against C++ libraries, addressing #20010. Fixes #20010. - - - - - 03efe283 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Add tests for system-cxx-std-lib package Test that we can successfully link against C++ code both in GHCi and batch compilation. See #20010 - - - - - 5f6527e0 by nineonine at 2022-05-17T00:25:38-04:00 OverloadedRecordFields: mention parent name in 'ambiguous occurrence' error for better disambiguation (#17420) - - - - - eccdb208 by Simon Peyton Jones at 2022-05-17T07:16:39-04:00 Adjust flags for pprTrace We were using defaultSDocContext for pprTrace, which suppresses lots of useful infomation. This small MR adds GHC.Utils.Outputable.traceSDocContext and uses it for pprTrace and pprTraceUserWarning. traceSDocContext is a global, and hence not influenced by flags, but that seems unavoidable. But I made the sdocPprDebug bit controlled by unsafeHasPprDebug, since we have the latter for exactly this purpose. Fixes #21569 - - - - - d2284c4c by Simon Peyton Jones at 2022-05-17T07:17:15-04:00 Fix bad interaction between withDict and the Specialiser This MR fixes a bad bug, where the withDict was inlined too vigorously, which in turn made the type-class Specialiser generate a bogus specialisation, because it saw the same overloaded function applied to two /different/ dictionaries. Solution: inline `withDict` later. See (WD8) of Note [withDict] in GHC.HsToCore.Expr See #21575, which is fixed by this change. - - - - - 70f52443 by Matthew Pickering at 2022-05-17T07:17:50-04:00 Bump time submodule to 1.12.2 This bumps the time submodule to the 1.12.2 release. Fixes #21571 - - - - - 2343457d by Vladislav Zavialov at 2022-05-17T07:18:26-04:00 Remove unused test files (#21582) Those files were moved to the perf/ subtree in 11c9a469, and then accidentally reintroduced in 680ef2c8. - - - - - cb52b4ae by Ben Gamari at 2022-05-17T16:00:14-04:00 CafAnal: Improve code clarity Here we implement a few measures to improve the clarity of the CAF analysis implementation. Specifically: * Use CafInfo instead of Bool since the former is more descriptive * Rename CAFLabel to CAFfyLabel, since not all CAFfyLabels are in fact CAFs * Add numerous comments - - - - - b048a9f4 by Ben Gamari at 2022-05-17T16:00:14-04:00 codeGen: Ensure that static datacon apps are included in SRTs When generating an SRT for a recursive group, GHC.Cmm.Info.Build.oneSRT filters out recursive references, as described in Note [recursive SRTs]. However, doing so for static functions would be unsound, for the reason described in Note [Invalid optimisation: shortcutting]. However, the same argument applies to static data constructor applications, as we discovered in #20959. Fix this by ensuring that static data constructor applications are included in recursive SRTs. The approach here is not entirely satisfactory, but it is a starting point. Fixes #20959. - - - - - 0e2d16eb by Matthew Pickering at 2022-05-17T16:00:50-04:00 Add test for #21558 This is now fixed on master and 9.2 branch. Closes #21558 - - - - - ef3c8d9e by Sylvain Henry at 2022-05-17T20:22:02-04:00 Don't store LlvmConfig into DynFlags LlvmConfig contains information read from llvm-passes and llvm-targets files in GHC's top directory. Reading these files is done only when needed (i.e. when the LLVM backend is used) and cached for the whole compiler session. This patch changes the way this is done: - Split LlvmConfig into LlvmConfig and LlvmConfigCache - Store LlvmConfigCache in HscEnv instead of DynFlags: there is no good reason to store it in DynFlags. As it is fixed per session, we store it in the session state instead (HscEnv). - Initializing LlvmConfigCache required some changes to driver functions such as newHscEnv. I've used the opportunity to untangle initHscEnv from initGhcMonad (in top-level GHC module) and to move it to GHC.Driver.Main, close to newHscEnv. - I've also made `cmmPipeline` independent of HscEnv in order to remove the call to newHscEnv in regalloc_unit_tests. - - - - - 828fbd8a by Andreas Klebinger at 2022-05-17T20:22:38-04:00 Give all EXTERN_INLINE closure macros prototypes - - - - - cfc8e2e2 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Introduce [sg]etFinalizerExceptionHandler This introduces a global hook which is called when an exception is thrown during finalization. - - - - - 372cf730 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Throw exceptions raised while closing finalized Handles Fixes #21336. - - - - - 3dd2f944 by Ben Gamari at 2022-05-19T04:57:51-04:00 testsuite: Add tests for #21336 - - - - - 297156e0 by Matthew Pickering at 2022-05-19T04:58:27-04:00 Add release flavour and use it for the release jobs The release flavour is essentially the same as the perf flavour currently but also enables `-haddock`. I have hopefully updated all the relevant places where the `-perf` flavour was hardcoded. Fixes #21486 - - - - - a05b6293 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Don't build sphinx documentation on centos The centos docker image lacks the sphinx builder so we disable building sphinx docs for these jobs. Fixes #21580 - - - - - 209d7c69 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Use correct syntax when args list is empty This seems to fail on the ancient version of bash present on CentOS - - - - - 02d16334 by Matthew Pickering at 2022-05-19T04:59:03-04:00 hadrian: Don't attempt to build dynamic profiling libraries We only support building static profiling libraries, the transformer was requesting things like a dynamic, threaded, debug, profiling RTS, which we have never produced nor distributed. Fixes #21567 - - - - - 35bdab1c by Ben Gamari at 2022-05-19T04:59:39-04:00 configure: Check CC_STAGE0 for --target support We previously only checked the stage 1/2 compiler for --target support. We got away with this for quite a while but it eventually caught up with us in #21579, where `bytestring`'s new NEON implementation was unbuildable on Darwin due to Rosetta's seemingly random logic for determining which executable image to execute. This lead to a confusing failure to build `bytestring`'s cbits, when `clang` tried to compile NEON builtins while targetting x86-64. Fix this by checking CC_STAGE0 for --target support. Fixes #21579. - - - - - 0ccca94b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator analysis of `CmmGraph` This commit adds module `GHC.Cmm.Dominators`, which provides a wrapper around two existing algorithms in GHC: the Lengauer-Tarjan dominator analysis from the X86 back end and the reverse postorder ordering from the Cmm Dataflow framework. Issue #20726 proposes that we evaluate some alternatives for dominator analysis, but for the time being, the best path forward is simply to use the existing analysis on `CmmGraph`s. This commit addresses a bullet in #21200. - - - - - 54f0b578 by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator-tree function - - - - - 05ed917b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add HasDebugCallStack; remove unneeded extensions - - - - - 0b848136 by Andreas Klebinger at 2022-05-20T05:32:32-04:00 document fields of `DominatorSet` - - - - - 8a26e8d6 by Ben Gamari at 2022-05-20T05:33:08-04:00 nonmoving: Fix documentation of GC statistics fields These were previously incorrect. Fixes #21553. - - - - - c1e24e61 by Matthew Pickering at 2022-05-20T05:33:44-04:00 Remove pprTrace from pushCoercionIntoLambda (#21555) This firstly caused spurious output to be emitted (as evidenced by #21555) but even worse caused a massive coercion to be attempted to be printed (> 200k terms) which would invariably eats up all the memory of your computer. The good news is that removing this trace allows the program to compile to completion, the bad news is that the program exhibits a core lint error (on 9.0.2) but not any other releases it seems. Fixes #21577 and #21555 - - - - - a36d12ee by Zubin Duggal at 2022-05-20T10:44:35-04:00 docs: Fix LlvmVersion in manpage (#21280) - - - - - 36b8a57c by Matthew Pickering at 2022-05-20T10:45:10-04:00 validate: Use $make rather than make In the validate script we are careful to use the $make variable as this stores whether we are using gmake, make, quiet mode etc. There was just this one place where we failed to use it. Fixes #21598 - - - - - 4aa3c5bd by Norman Ramsey at 2022-05-21T03:11:04+00:00 Change `Backend` type and remove direct dependencies With this change, `Backend` becomes an abstract type (there are no more exposed value constructors). Decisions that were formerly made by asking "is the current back end equal to (or different from) this named value constructor?" are now made by interrogating the back end about its properties, which are functions exported by `GHC.Driver.Backend`. There is a description of how to migrate code using `Backend` in the user guide. Clients using the GHC API can find a backdoor to access the Backend datatype in GHC.Driver.Backend.Internal. Bumps haddock submodule. Fixes #20927 - - - - - ecf5f363 by Julian Ospald at 2022-05-21T12:51:16-04:00 Respect DESTDIR in hadrian bindist Makefile, fixes #19646 - - - - - 7edd991e by Julian Ospald at 2022-05-21T12:51:16-04:00 Test DESTDIR in test_hadrian() - - - - - ea895b94 by Matthew Pickering at 2022-05-22T21:57:47-04:00 Consider the stage of typeable evidence when checking stage restriction We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547 - - - - - ffbe28e5 by Dominik Peteler at 2022-05-22T21:58:23-04:00 Modularize GHC.Core.Opt.LiberateCase Progress towards #17957 - - - - - bc723ac2 by Simon Peyton Jones at 2022-05-23T17:09:34+01:00 Improve FloatOut and SpecConstr This patch addresses a relatively obscure situation that arose when chasing perf regressions in !7847, which itself is fixing It does two things: * SpecConstr can specialise on ($df d1 d2) dictionary arguments * FloatOut no longer checks argument strictness See Note [Specialising on dictionaries] in GHC.Core.Opt.SpecConstr. A test case is difficult to construct, but it makes a big difference in nofib/real/eff/VSM, at least when we have the patch for #21286 installed. (The latter stops worker/wrapper for dictionary arguments). There is a spectacular, but slightly illusory, improvement in runtime perf on T15426. I have documented the specifics in T15426 itself. Metric Decrease: T15426 - - - - - 1a4195b0 by John Ericson at 2022-05-23T17:33:59-04:00 Make debug a `Bool` not an `Int` in `StgToCmmConfig` We don't need any more resolution than this. Rename the field to `stgToCmmEmitDebugInfo` to indicate it is no longer conveying any "level" information. - - - - - e9fff12b by Alan Zimmerman at 2022-05-23T21:04:49-04:00 EPA : Remove duplicate comments in DataFamInstD The code data instance Method PGMigration = MigrationQuery Query -- ^ Run a query against the database | MigrationCode (Connection -> IO (Either String ())) -- ^ Run any arbitrary IO code Resulted in two instances of the "-- ^ Run a query against the database" comment appearing in the Exact Print Annotations when it was parsed. Ensure only one is kept. Closes #20239 - - - - - e2520df3 by Alan Zimmerman at 2022-05-23T21:05:27-04:00 EPA: Comment Order Reversed Make sure comments captured in the exact print annotations are in order of increasing location Closes #20718 - - - - - 4b45fd72 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Add test for T21455 - - - - - e2cd1d43 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Allow passing -po outside profiling way Resolves #21455 - - - - - 3b8c413a by Greg Steuck at 2022-05-24T10:49:52-04:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 1db877a3 by Ben Gamari at 2022-05-24T10:50:28-04:00 hadrian/bindist: Drop redundant include of install.mk `install.mk` is already included by `config.mk`. Moreover, `install.mk` depends upon `config.mk` to set `RelocatableBuild`, making this first include incorrect. - - - - - f485d267 by Greg Steuck at 2022-05-24T10:51:08-04:00 Remove -z wxneeded for OpenBSD With all the recent W^X fixes in the loader this workaround is not necessary any longer. I verified that the only tests failing for me on OpenBSD 7.1-current are the same (libc++ related) before and after this commit (with --fast). - - - - - 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Andrew Lelechenko at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergő Érdi at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Andrew Lelechenko at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Andrew Lelechenko at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by Matthew Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Andrew Lelechenko at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by Matthew Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Andrew Lelechenko at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Andrew Lelechenko at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Andrew Lelechenko at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Andrew Lelechenko at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Andrew Lelechenko at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Andrew Lelechenko at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Andrew Lelechenko at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 8c72411d by Gergő Érdi at 2022-10-17T19:20:04-04:00 Add `Enum (Down a)` instance that swaps `succ` and `pred` See https://github.com/haskell/core-libraries-committee/issues/51 for discussion. The key points driving the implementation are the following two ideas: * For the `Int` type, `comparing (complement @Int)` behaves exactly as an order-swapping `compare @Int`. * `enumFrom @(Down a)` can be implemented in terms of `enumFromThen @a`, if only the corner case of starting at the very end is handled specially - - - - - d80ad2f4 by Alan Zimmerman at 2022-10-17T19:20:40-04:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 08ab5419 by Andreas Klebinger at 2022-10-17T19:21:15-04:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - ff6275ef by Andreas Klebinger at 2022-10-17T19:21:52-04:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - abb82f38 by Eric Lindblad at 2022-10-17T19:22:33-04:00 example rewrite - - - - - 39beb801 by Eric Lindblad at 2022-10-17T19:22:33-04:00 remove redirect - - - - - 0d9fb651 by Eric Lindblad at 2022-10-17T19:22:33-04:00 use heredoc - - - - - 0fa2d185 by Matthew Pickering at 2022-10-17T19:23:10-04:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - ced664a2 by Krzysztof Gogolewski at 2022-10-17T19:23:10-04:00 Fix T15155l not getting -fllvm - - - - - 0ac60423 by Andreas Klebinger at 2022-10-18T03:34:47-04:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 9ecd1ac0 by M Farkas-Dyck at 2022-10-18T03:35:38-04:00 Make `Functor` a superclass of `TrieMap`, which lets us derive the `map` functions. - - - - - f60244d7 by Ben Gamari at 2022-10-18T03:36:15-04:00 configure: Bump minimum bootstrap GHC version Fixes #22245 - - - - - ba4bd4a4 by Matthew Pickering at 2022-10-18T03:36:55-04:00 Build System: Remove out-of-date comment about make build system Both make and hadrian interleave compilation of modules of different modules and don't respect the package boundaries. Therefore I just remove this comment which points out this "difference". Fixes #22253 - - - - - e1bbd368 by Matthew Pickering at 2022-10-18T16:15:49+02:00 Allow configuration of error message printing This MR implements the idea of #21731 that the printing of a diagnostic method should be configurable at the printing time. The interface of the `Diagnostic` class is modified from: ``` class Diagnostic a where diagnosticMessage :: a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` to ``` class Diagnostic a where type DiagnosticOpts a defaultDiagnosticOpts :: DiagnosticOpts a diagnosticMessage :: DiagnosticOpts a -> a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` and so each `Diagnostic` can implement their own configuration record which can then be supplied by a client in order to dictate how to print out the error message. At the moment this only allows us to implement #21722 nicely but in future it is more natural to separate the configuration of how much information we put into an error message and how much we decide to print out of it. Updates Haddock submodule - - - - - 99dc3e3d by Matthew Pickering at 2022-10-18T16:15:53+02:00 Add -fsuppress-error-contexts to disable printing error contexts in errors In many development environments, the source span is the primary means of seeing what an error message relates to, and the In the expression: and In an equation for: clauses are not particularly relevant. However, they can grow to be quite long, which can make the message itself both feel overwhelming and interact badly with limited-space areas. It's simple to implement this flag so we might as well do it and give the user control about how they see their messages. Fixes #21722 - - - - - 5b3a992f by Dai at 2022-10-19T10:45:45-04:00 Add VecSlot for unboxed sums of SIMD vectors This patch adds the missing `VecRep` case to `primRepSlot` function and all the necessary machinery to carry this new `VecSlot` through code generation. This allows programs involving unboxed sums of SIMD vectors to be written and compiled. Fixes #22187 - - - - - 6d7d9181 by sheaf at 2022-10-19T10:45:45-04:00 Remove SIMD conversions This patch makes it so that packing/unpacking SIMD vectors always uses the right sized types, e.g. unpacking a Word16X4# will give a tuple of Word16#s. As a result, we can get rid of the conversion instructions that were previously required. Fixes #22296 - - - - - 3be48877 by sheaf at 2022-10-19T10:45:45-04:00 Cmm Lint: relax SIMD register assignment check As noted in #22297, SIMD vector registers can be used to store different kinds of values, e.g. xmm1 can be used both to store integer and floating point values. The Cmm type system doesn't properly account for this, so we weaken the Cmm register assignment lint check to only compare widths when comparing a vector type with its allocated vector register. - - - - - f7b7a312 by sheaf at 2022-10-19T10:45:45-04:00 Disable some SIMD tests on non-X86 architectures - - - - - 83638dce by M Farkas-Dyck at 2022-10-19T10:46:29-04:00 Scrub various partiality involving lists (again). Lets us avoid some use of `head` and `tail`, and some panics. - - - - - c3732c62 by M Farkas-Dyck at 2022-10-19T10:47:13-04:00 Enforce invariant of `ListBag` constructor. - - - - - 488d3631 by Andrew Lelechenko at 2022-10-19T10:47:52-04:00 More precise types for fields of OverlappingInstances and UnsafeOverlap in TcSolverReportMsg It's clear from asserts in `GHC.Tc.Errors` that `overlappingInstances_matches` and `unsafeOverlapped` are supposed to be non-empty, and `unsafeOverlap_matches` contains a single instance, but these invariants are immediately lost afterwards and not encoded in types. This patch enforces the invariants by pattern matching and makes types more precise, avoiding asserts and partial functions such as `head`. - - - - - 607ce263 by sheaf at 2022-10-19T10:47:52-04:00 Rename unsafeOverlap_matches -> unsafeOverlap_match in UnsafeOverlap - - - - - 1fab9598 by Matthew Pickering at 2022-10-19T10:48:29-04:00 Add SpliceTypes test for hie files This test checks that typed splices and quotes get the right type information when used in hiefiles. See #21619 - - - - - a8b52786 by Jan Hrček at 2022-10-19T10:49:09-04:00 Small language fixes in 'Using GHC' - - - - - 1dab1167 by Gergő Érdi at 2022-10-19T10:49:51-04:00 Fix typo in `Opt_WriteIfSimplifiedCore`'s name - - - - - b17cfc9c by sheaf at 2022-10-19T10:50:37-04:00 TyEq:N assertion: only for saturated applications The assertion that checked TyEq:N in canEqCanLHSFinish incorrectly triggered in the case of an unsaturated newtype TyCon heading the RHS, even though we can't unwrap such an application. Now, we only trigger an assertion failure in case of a saturated application of a newtype TyCon. Fixes #22310 - - - - - ff6f2228 by M Farkas-Dyck at 2022-10-20T16:15:51-04:00 CoreToStg: purge `DynFlags`. - - - - - 1ebd521f by Matthew Pickering at 2022-10-20T16:16:27-04:00 ci: Make fat014 test robust For some reason I implemented this as a makefile test rather than a ghci_script test. Hopefully making it a ghci_script test makes it more robust. Fixes #22313 - - - - - 8cd6f435 by Curran McConnell at 2022-10-21T02:58:01-04:00 remove a no-warn directive from GHC.Cmm.ContFlowOpt This patch is motivated by the desire to remove the {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} directive at the top of GHC.Cmm.ContFlowOpt. (Based on the text in this coding standards doc, I understand it's a goal of the project to remove such directives.) I chose this task because I'm a new contributor to GHC, and it seemed like a good way to get acquainted with the patching process. In order to address the warning that arose when I removed the no-warn directive, I added a case to removeUnreachableBlocksProc to handle the CmmData constructor. Clearly, since this partial function has not been erroring out in the wild, its inputs are always in practice wrapped by the CmmProc constructor. Therefore the CmmData case is handled by a precise panic (which is an improvement over the partial pattern match from before). - - - - - a2af7c4c by Nicolas Trangez at 2022-10-21T02:58:39-04:00 build: get rid of `HAVE_TIME_H` As advertized by `autoreconf`: > All current systems provide time.h; it need not be checked for. Hence, remove the check for it in `configure.ac` and remove conditional inclusion of the header in `HAVE_TIME_H` blocks where applicable. The `time.h` header was being included in various source files without a `HAVE_TIME_H` guard already anyway. - - - - - 25cdc630 by Nicolas Trangez at 2022-10-21T02:58:39-04:00 rts: remove use of `TIME_WITH_SYS_TIME` `autoreconf` will insert an `m4_warning` when the obsolescent `AC_HEADER_TIME` macro is used: > Update your code to rely only on HAVE_SYS_TIME_H, > then remove this warning and the obsolete code below it. > All current systems provide time.h; it need not be checked for. > Not all systems provide sys/time.h, but those that do, all allow > you to include it and time.h simultaneously. Presence of `sys/time.h` was already checked in an earlier `AC_CHECK_HEADERS` invocation, so `AC_HEADER_TIME` can be dropped and guards relying on `TIME_WITH_SYS_TIME` can be reworked to (unconditionally) include `time.h` and include `sys/time.h` based on `HAVE_SYS_TIME_H`. Note the documentation of `AC_HEADER_TIME` in (at least) Autoconf 2.67 says > This macro is obsolescent, as current systems can include both files > when they exist. New programs need not use this macro. - - - - - 1fe7921c by Eric Lindblad at 2022-10-21T02:59:21-04:00 runhaskell - - - - - e3b3986e by David Feuer at 2022-10-21T03:00:00-04:00 Document how to quote certain names with spaces Quoting a name for Template Haskell is a bit tricky if the second character of that name is a single quote. The User's Guide falsely claimed that it was impossible. Document how to do it. Fixes #22236 - - - - - 0eba81e8 by Krzysztof Gogolewski at 2022-10-21T03:00:00-04:00 Fix syntax - - - - - a4dbd102 by Ben Gamari at 2022-10-21T09:11:12-04:00 Fix manifest filename when writing Windows .rc files As noted in #12971, we previously used `show` which resulted in inappropriate escaping of non-ASCII characters. - - - - - 30f0d9a9 by Ben Gamari at 2022-10-21T09:11:12-04:00 Write response files in UTF-8 on Windows This reverts the workaround introduced in f63c8ef33ec9666688163abe4ccf2d6c0428a7e7, which taught our response file logic to write response files with the `latin1` encoding to workaround `gcc`'s lacking Unicode support. This is now no longer necessary (and in fact actively unhelpful) since we rather use Clang. - - - - - b8304648 by Matthew Farkas-Dyck at 2022-10-21T09:11:56-04:00 Scrub some partiality in `GHC.Core.Opt.Simplify.Utils`. - - - - - 09ec7de2 by Teo Camarasu at 2022-10-21T13:23:07-04:00 template-haskell: Improve documentation of strictness annotation types Before it was undocumentated that DecidedLazy can be returned by reifyConStrictness for strict fields. This can happen when a field has an unlifted type or its the single field of a newtype constructor. Fixes #21380 - - - - - 88172069 by M Farkas-Dyck at 2022-10-21T13:23:51-04:00 Delete `eqExpr`, since GHC 9.4 has been released. - - - - - 86e6549e by Ömer Sinan Ağacan at 2022-10-22T07:41:30-04:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const 0; // padding for indirectee const 0; // static link const 0; // saved info const hey1_r1Gg_bytes; // the payload } This is much smaller in code. Metric Decrease: T10421 T11195 T12150 T12425 T16577 T18282 T18698a T18698b Co-Authored By: Ben Gamari <ben at well-typed.com> - - - - - 1937016b by Andreas Klebinger at 2022-10-22T07:42:06-04:00 hadrian: Improve error for wrong key/value errors. - - - - - 11fe42d8 by Vladislav Zavialov at 2022-10-23T00:11:50+03:00 Class layout info (#19623) Updates the haddock submodule. - - - - - f0a90c11 by Sven Tennie at 2022-10-24T00:12:51-04:00 Pin used way for test cloneMyStack (#21977) cloneMyStack checks the order of closures on the cloned stack. This may change for different ways. Thus we limit this test to one way (normal). - - - - - 0614e74d by Aaron Allen at 2022-10-24T17:11:21+02:00 Convert Diagnostics in GHC.Tc.Gen.Splice (#20116) Replaces uses of `TcRnUnknownMessage` in `GHC.Tc.Gen.Splice` with structured diagnostics. closes #20116 - - - - - 8d2dbe2d by Andreas Klebinger at 2022-10-24T15:59:41-04:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 41406da5 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 5a997e16 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 7f203d00 by Sylvain Henry at 2022-10-25T18:07:43-04:00 Numeric exceptions: replace FFI calls with primops ghc-bignum needs a way to raise numerical exceptions defined in base package. At the time we used FFI calls into primops defined in the RTS. These FFI calls had to be wrapped into hacky bottoming functions because "foreign import prim" syntax doesn't support giving a bottoming demand to the foreign call (cf #16929). These hacky wrapper functions trip up the JavaScript backend (#21078) because they are polymorphic in their return type. This commit replaces them with primops very similar to raise# but raising predefined exceptions. - - - - - 0988a23d by Sylvain Henry at 2022-10-25T18:08:24-04:00 Enable popcount rewrite rule when cross-compiling The comment applies only when host's word size < target's word size. So we can relax the guard. - - - - - a2f53ac8 by Sylvain Henry at 2022-10-25T18:09:05-04:00 Add GHC.SysTools.Cpp module Move doCpp out of the driver to be able to use it in the upcoming JS backend. - - - - - 1fd7f201 by Ben Gamari at 2022-10-25T18:09:42-04:00 llvm-targets: Add datalayouts for big-endian AArch64 targets Fixes #22311. Thanks to @zeldin for the patch. - - - - - f5a486eb by Krzysztof Gogolewski at 2022-10-25T18:10:19-04:00 Cleanup String/FastString conversions Remove unused mkPtrString and isUnderscoreFS. We no longer use mkPtrString since 1d03d8bef96. Remove unnecessary conversions between FastString and String and back. - - - - - f7bfb40c by Ryan Scott at 2022-10-26T00:01:24-04:00 Broaden the in-scope sets for liftEnvSubst and composeTCvSubst This patch fixes two distinct (but closely related) buglets that were uncovered in #22235: * `liftEnvSubst` used an empty in-scope set, which was not wide enough to cover the variables in the range of the substitution. This patch fixes this by populating the in-scope set from the free variables in the range of the substitution. * `composeTCvSubst` applied the first substitution argument to the range of the second substitution argument, but the first substitution's in-scope set was not wide enough to cover the range of the second substutition. We similarly fix this issue in this patch by widening the first substitution's in-scope set before applying it. Fixes #22235. - - - - - 0270cc54 by Vladislav Zavialov at 2022-10-26T00:02:01-04:00 Introduce TcRnWithHsDocContext (#22346) Before this patch, GHC used withHsDocContext to attach an HsDocContext to an error message: addErr $ mkTcRnUnknownMessage $ mkPlainError noHints (withHsDocContext ctxt msg) The problem with this approach is that it only works with TcRnUnknownMessage. But could we attach an HsDocContext to a structured error message in a generic way? This patch solves the problem by introducing a new constructor to TcRnMessage: data TcRnMessage where ... TcRnWithHsDocContext :: !HsDocContext -> !TcRnMessage -> TcRnMessage ... - - - - - 9ab31f42 by Sylvain Henry at 2022-10-26T09:32:20+02:00 Testsuite: more precise test options Necessary for newer cross-compiling backends (JS, Wasm) that don't support TH yet. - - - - - f60a1a62 by Vladislav Zavialov at 2022-10-26T12:17:14-04:00 Use TcRnVDQInTermType in noNestedForallsContextsErr (#20115) When faced with VDQ in the type of a term, GHC generates the following error message: Illegal visible, dependent quantification in the type of a term (GHC does not yet support this) Prior to this patch, there were two ways this message could have been generated and represented: 1. with the dedicated constructor TcRnVDQInTermType (see check_type in GHC.Tc.Validity) 2. with the transitional constructor TcRnUnknownMessage (see noNestedForallsContextsErr in GHC.Rename.Utils) Not only this led to duplication of code generating the final SDoc, it also made it tricky to track the origin of the error message. This patch fixes the problem by using TcRnVDQInTermType exclusively. - - - - - 223e159d by Owen Shepherd at 2022-10-27T13:54:33-04:00 Remove source location information from interface files This change aims to minimize source location information leaking into interface files, which makes ABI hashes dependent on the build location. The `Binary (Located a)` instance has been removed completely. It seems that the HIE interface still needs the ability to serialize SrcSpans, but by wrapping the instances, it should be a lot more difficult to inadvertently add source location information. - - - - - 22e3deb9 by Simon Peyton Jones at 2022-10-27T13:55:37-04:00 Add missing dict binds to specialiser I had forgotten to add the auxiliary dict bindings to the /unfolding/ of a specialised function. This caused #22358, which reports failures when compiling Hackage packages fixed-vector indexed-traversable Regression test T22357 is snarfed from indexed-traversable - - - - - a8ed36f9 by Evan Relf at 2022-10-27T13:56:36-04:00 Fix broken link to `async` package - - - - - 750846cd by Zubin Duggal at 2022-10-28T00:49:22-04:00 Pass correct package db when testing stage1. It used to pick the db for stage-2 which obviously didn't work. - - - - - ad612f55 by Krzysztof Gogolewski at 2022-10-28T00:50:00-04:00 Minor SDoc-related cleanup * Rename pprCLabel to pprCLabelStyle, and use the name pprCLabel for a function using CStyle (analogous to pprAsmLabel) * Move LabelStyle to the CLabel module, it no longer needs to be in Outputable. * Move calls to 'text' right next to literals, to make sure the text/str rule is triggered. * Remove FastString/String roundtrip in Tc.Deriv.Generate * Introduce showSDocForUser', which abstracts over a pattern in GHCi.UI - - - - - c2872f3f by Bryan Richter at 2022-10-28T11:36:34+03:00 CI: Don't run lint-submods on nightly Fixes #22325 - - - - - 270037fa by Hécate Moonlight at 2022-10-28T19:46:12-04:00 Start the deprecation process for GHC.Pack - - - - - d45d8cb3 by M Farkas-Dyck at 2022-11-01T12:47:21-04:00 Drop a kludge for binutils<2.17, which is now over 10 years old. - - - - - 8ee8b418 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: `name` argument of `createOSThread` can be `const` Since we don't intend to ever change the incoming string, declare this to be true. Also, in the POSIX implementation, the argument is no longer `STG_UNUSED` (since ee0deb8054da2a597fc5624469b4c44fd769ada2) in any code path. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 - - - - - 13b5f102 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix lifetime of `start_thread`s `name` value Since, unlike the code in ee0deb8054da2^, usage of the `name` value passed to `createOSThread` now outlives said function's lifetime, and could hence be released by the caller by the time the new thread runs `start_thread`, it needs to be copied. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - edd175c9 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix OS thread naming in ticker Since ee0deb805, the use of `pthread_setname_np` on Darwin was fixed when invoking `createOSThread`. However, the 'ticker' has some thread-creation code which doesn't rely on `createOSThread`, yet also uses `pthread_setname_np`. This patch enforces all thread creation to go through a single function, which uses the (correct) thread-naming code introduced in ee0deb805. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22206 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - b7a00113 by Krzysztof Gogolewski at 2022-11-01T12:48:35-04:00 Typo: rename -fwrite-if-simplfied-core to -fwrite-if-simplified-core - - - - - 30e625e6 by Vladislav Zavialov at 2022-11-01T12:49:10-04:00 ThToHs: fix overzealous parenthesization Before this patch, when converting from TH.Exp to LHsExpr GhcPs, the compiler inserted more parentheses than required: ((f a) (b + c)) d This was happening because the LHS of the function application was parenthesized as if it was the RHS. Now we use funPrec and appPrec appropriately and produce sensibly parenthesized expressions: f a (b + c) d I also took the opportunity to remove the special case for LamE, which was not special at all and simply duplicated code. - - - - - 0560821f by Simon Peyton Jones at 2022-11-01T12:49:47-04:00 Add accurate skolem info when quantifying Ticket #22379 revealed that skolemiseQuantifiedTyVar was dropping the passed-in skol_info on the floor when it encountered a SkolemTv. Bad! Several TyCons thereby share a single SkolemInfo on their binders, which lead to bogus error reports. - - - - - 38d19668 by Fendor at 2022-11-01T12:50:25-04:00 Expose UnitEnvGraphKey for user-code - - - - - 77e24902 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Shrink test case for #22357 Ryan Scott offered a cut-down repro case (60 lines instead of more than 700 lines) - - - - - 4521f649 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Add two tests for #17366 - - - - - 6b400d26 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_NORETURN` Instead of sprinkling the codebase with `GNU(C3)_ATTRIBUTE(__noreturn__)`, add a `STG_NORETURN` macro (for, basically, the same thing) similar to `STG_UNUSED` and others, and update the code to use this macro where applicable. - - - - - f9638654 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: consistently use `STG_UNUSED` - - - - - 81a58433 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_USED` Similar to `STG_UNUSED`, have a specific macro for `__attribute__(used)`. - - - - - 41e1f748 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_MALLOC` Instead of using `GNUC3_ATTRIBUTE(__malloc__)`, provide a `STG_MALLOC` macro definition and use it instead. - - - - - 3a9a8bde by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `STG_UNUSED` - - - - - 9ab999de by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: specify deallocator of allocating functions This patch adds a new `STG_MALLOC1` macro (and its counterpart `STG_MALLOC2` for completeness) which allows to specify the deallocation function to be used with allocations of allocating functions, and applies it to `stg*allocBytes`. It also fixes a case where `free` was used to free up an `stgMallocBytes` allocation, found by the above change. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 81c0c7c9 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `alloc_size` attribute This patch adds the `STG_ALLOC_SIZE1` and `STG_ALLOC_SIZE2` macros which allow to set the `alloc_size` attribute on functions, when available. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 99a1d896 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: add and use `STG_RETURNS_NONNULL` See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - c235b399 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: tag `stgStrndup` as `STG_MALLOC` See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - ed81b448 by Oleg Grenrus at 2022-11-02T12:07:27-04:00 Move Symbol implementation note out of public haddock - - - - - 284fd39c by Ben Gamari at 2022-11-03T01:58:54-04:00 gen-dll: Drop it Currently it is only used by the make build system, which is soon to be retired, and it has not built since 41cf758b. We may need to reintroduce it when dynamic-linking support is introduced on Windows, but we will cross that bridge once we get there. Fixes #21753. - - - - - 24f4f54f by Matthew Pickering at 2022-11-03T01:59:30-04:00 Port foundation numeric tests to GHC testsuite This commit ports the numeric tests which found a regression in GHC-9.4. https://github.com/haskell-foundation/foundation/issues/571 Included in the commit is a simple random number generator and simplified QuickCheck implementation. In future these could be factored out of this standalone file and reused as a general purpose library which could be used for other QuickCheck style tests in the testsuite. See #22282 - - - - - d51bf7bd by M Farkas-Dyck at 2022-11-03T02:00:13-04:00 git: ignore HIE files. Cleans up git status if one sets -fwrite-ide-info in hadrian/ghci. - - - - - a9fc15b1 by Matthew Pickering at 2022-11-03T02:00:49-04:00 Clarify status of bindings in WholeCoreBindings Gergo points out that these bindings are tidied, rather than prepd as the variable claims. Therefore we update the name of the variable to reflect reality and add a comment to the data type to try to erase any future confusion. Fixes #22307 - - - - - 634da448 by Andrew Lelechenko at 2022-11-03T21:25:02+00:00 Fix haddocks for GHC.IORef - - - - - 31125154 by Andreas Klebinger at 2022-11-03T23:08:09-04:00 Export pprTrace and friends from GHC.Prelude. Introduces GHC.Prelude.Basic which can be used in modules which are a dependency of the ppr code. - - - - - bdc8cbb3 by Bryan Richter at 2022-11-04T10:27:37+02:00 CI: Allow hadrian-ghc-in-ghci to run in nightlies Since lint-submods doesn't run in nightlies, hadrian-ghc-in-ghci needs to mark it as "optional" so it can run if the job doesn't exist. Fixes #22396. - - - - - 3c0e3793 by Krzysztof Gogolewski at 2022-11-05T00:29:57-04:00 Minor refactor around FastStrings Pass FastStrings to functions directly, to make sure the rule for fsLit "literal" fires. Remove SDoc indirection in GHCi.UI.Tags and GHC.Unit.Module.Graph. - - - - - e41b2f55 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump unix submodule to 2.8.0.0 Also bumps process and ghc-boot bounds on unix. For hadrian, when cross-compiling, we add -Wwarn=unused-imports -Wwarn=unused-top-binds to validation flavour. Further fixes in unix and/or hsc2hs is needed to make it completely free of warnings; for the time being, this change is needed to unblock other cross-compilation related work. - - - - - 42938a58 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump Win32 submodule to 2.13.4.0 Fixes #22098 - - - - - e7372bc5 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump ci-images revision ci-images has recently been updated, including changes needed for wasm32-wasi CI. - - - - - 88cb9492 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump gmp-tarballs submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 69427ce9 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump haskeline submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 5fe11fe6 by Carter Schonwald at 2022-11-07T13:22:14-05:00 bump llvm upper bound - - - - - 68f49874 by M Farkas-Dyck at 2022-11-08T12:53:55-05:00 Define `Infinite` list and use where appropriate. Also add perf test for infinite list fusion. In particular, in `GHC.Core`, often we deal with infinite lists of roles. Also in a few locations we deal with infinite lists of names. Thanks to simonpj for helping to write the Note [Fusion for `Infinite` lists]. - - - - - ce726cd2 by Ross Paterson at 2022-11-08T12:54:34-05:00 Fix TypeData issues (fixes #22315 and #22332) There were two bugs here: 1. Treating type-level constructors as PromotedDataCon doesn't always work, in particular because constructors promoted via DataKinds are called both T and 'T. (Tests T22332a, T22332b, T22315a, T22315b) Fix: guard these cases with isDataKindsPromotedDataCon. 2. Type-level constructors were sent to the code generator, producing things like constructor wrappers. (Tests T22332a, T22332b) Fix: test for them in isDataTyCon. Other changes: * changed the marking of "type data" DataCon's as suggested by SPJ. * added a test TDGADT for a type-level GADT. * comment tweaks * change tcIfaceTyCon to ignore IfaceTyConInfo, so that IfaceTyConInfo is used only for pretty printing, not for typechecking. (SPJ) - - - - - 132f8908 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Clarify msum/asum documentation - - - - - bb5888c5 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Add example for (<$) - - - - - 080fffa1 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Document what Alternative/MonadPlus instances actually do - - - - - 92ccb8de by Giles Anderson at 2022-11-09T09:27:52-05:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Instance (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnWarnUnsatisfiedMinimalDefinition TcRnMisplacedInstSig TcRnBadBootFamInstDeclErr TcRnIllegalFamilyInstance TcRnAssocInClassErr TcRnBadFamInstDecl TcRnNotOpenFamily - - - - - 90c5abd4 by Hécate Moonlight at 2022-11-09T09:28:30-05:00 GHCi tags generation phase 2 see #19884 - - - - - f9f17b68 by Simon Peyton Jones at 2022-11-10T12:20:03+00:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. The reorganisation in the Simplifier improve compile times a bit (geom mean -0.1%), but T9961 is an outlier Metric Decrease: T9961 - - - - - 2b3d0bee by Simon Peyton Jones at 2022-11-10T12:21:13+00:00 Make indexError work better The problem here is described at some length in Note [Boxity for bottoming functions] and Note [Reboxed crud for bottoming calls] in GHC.Core.Opt.DmdAnal. This patch adds a SPECIALISE pragma for indexError, which makes it much less vulnerable to the problem described in these Notes. (This came up in another line of work, where a small change made indexError do reboxing (in nofib/spectral/simple/table_sort) that didn't happen before my change. I've opened #22404 to document the fagility. - - - - - 399e921b by Simon Peyton Jones at 2022-11-10T12:21:14+00:00 Fix DsUselessSpecialiseForClassMethodSelector msg The error message for DsUselessSpecialiseForClassMethodSelector was just wrong (a typo in some earlier work); trivial fix - - - - - dac0682a by Sebastian Graf at 2022-11-10T21:16:01-05:00 WorkWrap: Unboxing unboxed tuples is not always useful (#22388) See Note [Unboxing through unboxed tuples]. Fixes #22388. - - - - - 1230c268 by Sebastian Graf at 2022-11-10T21:16:01-05:00 Boxity: Handle argument budget of unboxed tuples correctly (#21737) Now Budget roughly tracks the combined width of all arguments after unarisation. See the changes to `Note [Worker argument budgets]`. Fixes #21737. - - - - - 2829fd92 by Cheng Shao at 2022-11-11T00:26:54-05:00 autoconf: check getpid getuid raise This patch adds checks for getpid, getuid and raise in autoconf. These functions are absent in wasm32-wasi and thus needs to be checked. - - - - - f5dfd1b4 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add -Wwarn only for cross-compiling unix - - - - - 2e6ab453 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add targetSupportsThreadedRts flag This patch adds a targetSupportsThreadedRts flag to indicate whether the target supports the threaded rts at all, different from existing targetSupportsSMP that checks whether -N is supported by the RTS. All existing flavours have also been updated accordingly to respect this flags. Some targets (e.g. wasm32-wasi) does not support the threaded rts, therefore this flag is needed for the default flavours to work. It makes more sense to have proper autoconf logic to check for threading support, but for the time being, we just set the flag to False iff the target is wasm32. - - - - - 8104f6f5 by Cheng Shao at 2022-11-11T00:26:55-05:00 Fix Cmm symbol kind - - - - - b2035823 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add the two key graph modules from Martin Erwig's FGL Martin Erwig's FGL (Functional Graph Library) provides an "inductive" representation of graphs. A general graph has labeled nodes and labeled edges. The key operation on a graph is to decompose it by removing one node, together with the edges that connect the node to the rest of the graph. There is also an inverse composition operation. The decomposition and composition operations make this representation of graphs exceptionally well suited to implement graph algorithms in which the graph is continually changing, as alluded to in #21259. This commit adds `GHC.Data.Graph.Inductive.Graph`, which defines the interface, and `GHC.Data.Graph.Inductive.PatriciaTree`, which provides an implementation. Both modules are taken from `fgl-5.7.0.3` on Hackage, with these changes: - Copyright and license text have been copied into the files themselves, not stored separately. - Some calls to `error` have been replaced with calls to `panic`. - Conditional-compilation support for older versions of GHC, `containers`, and `base` has been removed. - - - - - 3633a5f5 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add new modules for reducibility and WebAssembly translation - - - - - df7bfef8 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add support for the wasm32-wasi target tuple This patch adds the wasm32-wasi tuple support to various places in the tree: autoconf, hadrian, ghc-boot and also the compiler. The codegen logic will come in subsequent commits. - - - - - 32ae62e6 by Cheng Shao at 2022-11-11T00:26:55-05:00 deriveConstants: parse .ll output for wasm32 due to broken nm This patch makes deriveConstants emit and parse an .ll file when targeting wasm. It's a necessary workaround for broken llvm-nm on wasm, which isn't capable of reporting correct constant values when parsing an object. - - - - - 07e92c92 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: workaround cmm's improper variadic ccall breaking wasm32 typechecking Unlike other targets, wasm requires the function signature of the call site and callee to strictly match. So in Cmm, when we call a C function that actually returns a value, we need to add an _unused local variable to receive it, otherwise type error awaits. An even bigger problem is calling variadic functions like barf() and such. Cmm doesn't support CAPI calling convention yet, so calls to variadic functions just happen to work in some cases with some target's ABI. But again, it doesn't work with wasm. Fortunately, the wasm C ABI lowers varargs to a stack pointer argument, and it can be passed NULL when no other arguments are expected to be passed. So we also add the additional unused NULL arguments to those functions, so to fix wasm, while not affecting behavior on other targets. - - - - - 00124d12 by Cheng Shao at 2022-11-11T00:26:55-05:00 testsuite: correct sleep() signature in T5611 In libc, sleep() returns an integer. The ccall type signature should match the libc definition, otherwise it causes linker error on wasm. - - - - - d72466a9 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: prefer ffi_type_void over FFI_TYPE_VOID This patch uses ffi_type_void instead of FFI_TYPE_VOID in the interpreter code, since the FFI_TYPE_* macros are not available in libffi-wasm32 yet. The libffi public documentation also only mentions the lower-case ffi_type_* symbols, so we should prefer the lower-case API here. - - - - - 4d36a1d3 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't define RTS_USER_SIGNALS when signal.h is not present In the rts, we have a RTS_USER_SIGNALS macro, and most signal-related logic is guarded with RTS_USER_SIGNALS. This patch extends the range of code guarded with RTS_USER_SIGNALS, and define RTS_USER_SIGNALS iff signal.h is actually detected by autoconf. This is required for wasm32-wasi to work, which lacks signals. - - - - - 3f1e164f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: use HAVE_GETPID to guard subprocess related logic We've previously added detection of getpid() in autoconf. This patch uses HAVE_GETPID to guard some subprocess related logic in the RTS. This is required for certain targets like wasm32-wasi, where there isn't a process model at all. - - - - - 50bf5e77 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: IPE.c: don't do mutex stuff when THREADED_RTS is not defined This patch adds the missing THREADED_RTS CPP guard to mutex logic in IPE.c. - - - - - ed3b3da0 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: genericRaise: use exit() instead when not HAVE_RAISE We check existence of raise() in autoconf, and here, if not HAVE_RAISE, we should use exit() instead in genericRaise. - - - - - c0ba1547 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: checkSuid: don't do it when not HAVE_GETUID When getuid() is not present, don't do checkSuid since it doesn't make sense anyway on that target. - - - - - d2d6dfd2 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 placeholder linker This patch adds minimal placeholder linker logic for wasm32, just enough to unblock compiling rts on wasm32. RTS linker functionality is not properly implemented yet for wasm32. - - - - - 65ba3285 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: chdir to PWD on wasm32 This patch adds a wasm32-specific behavior to RtsStartup logic. When the PWD environment variable is present, we chdir() to it first. The point is to workaround an issue in wasi-libc: it's currently not possible to specify the initial working directory, it always defaults to / (in the virtual filesystem mapped from some host directory). For some use cases this is sufficient, but there are some other cases (e.g. in the testsuite) where the program needs to access files outside. - - - - - 65b82542 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: no timer for wasm32 Due to the lack of threads, on wasm32 there can't be a background timer that periodically resets the context switch flag. This patch disables timer for wasm32, and also makes the scheduler default to -C0 on wasm32 to avoid starving threads. - - - - - e007586f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsSymbols: empty RTS_POSIX_ONLY_SYMBOLS for wasm32 The default RTS_POSIX_ONLY_SYMBOLS doesn't make sense on wasm32. - - - - - 0e33f667 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: Schedule: no FORKPROCESS_PRIMOP_SUPPORTED on wasm32 On wasm32 there isn't a process model at all, so no FORKPROCESS_PRIMOP_SUPPORTED. - - - - - 88bbdb31 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: LibffiAdjustor: adapt to ffi_alloc_prep_closure interface for wasm32 libffi-wasm32 only supports non-standard libffi closure api via ffi_alloc_prep_closure(). This patch implements ffi_alloc_prep_closure() via standard libffi closure api on other targets, and uses it to implement adjustor functionality. - - - - - 15138746 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't return memory to OS on wasm32 This patch makes the storage manager not return any memory on wasm32. The detailed reason is described in Note [Megablock allocator on wasm]. - - - - - 631af3cc by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: make flushExec a no-op on wasm32 This patch makes flushExec a no-op on wasm32, since there's no such thing as executable memory on wasm32 in the first place. - - - - - 654a3d46 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: don't call resetTerminalSettings, freeThreadingResources on wasm32 This patch prevents resetTerminalSettings and freeThreadingResources to be called on wasm32, since there is no TTY or threading on wasm32 at all. - - - - - f271e7ca by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: OSThreads.h: stub types for wasm32 This patch defines stub Condition/Mutex/OSThreadId/ThreadLocalKey types for wasm32, just enough to unblock compiling RTS. Any threading-related functionality has been patched to be disabled on wasm32. - - - - - a6ac67b0 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add register mapping for wasm32 This patch adds register mapping logic for wasm32. See Note [Register mapping on WebAssembly] in wasm32 NCG for more description. - - - - - d7b33982 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 specific logic This patch adds the rest of wasm32 specific logic in rts. - - - - - 7f59b0f3 by Cheng Shao at 2022-11-11T00:26:55-05:00 base: fall back to using monotonic clock to emulate cputime on wasm32 On wasm32, we have to fall back to using monotonic clock to emulate cputime, since there's no native support for cputime as a clock id. - - - - - 5fcbae0b by Cheng Shao at 2022-11-11T00:26:55-05:00 base: more autoconf checks for wasm32 This patch adds more autoconf checks to base, since those functions and headers may exist on other POSIX systems but don't exist on wasm32. - - - - - 00a9359f by Cheng Shao at 2022-11-11T00:26:55-05:00 base: avoid using unsupported posix functionality on wasm32 This base patch avoids using unsupported posix functionality on wasm32. - - - - - 34b8f611 by Cheng Shao at 2022-11-11T00:26:55-05:00 autoconf: set CrossCompiling=YES in cross bindist configure This patch fixes the bindist autoconf logic to properly set CrossCompiling=YES when it's a cross GHC bindist. - - - - - 5ebeaa45 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: add util functions for UniqFM and UniqMap This patch adds addToUFM_L (backed by insertLookupWithKey), addToUniqMap_L and intersectUniqMap_C. These UniqFM/UniqMap util functions are used by the wasm32 NCG. - - - - - 177c56c1 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: avoid -Wl,--no-as-needed for wasm32 The driver used to pass -Wl,--no-as-needed for LLD linking. This is actually only supported for ELF targets, and must be avoided when linking for wasm32. - - - - - 06f01c74 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: allow big arith for wasm32 This patch enables Cmm big arithmetic on wasm32, since 64-bit arithmetic can be efficiently lowered to wasm32 opcodes. - - - - - df6bb112 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: pass -Wa,--no-type-check for wasm32 when runAsPhase This patch passes -Wa,--no-type-check for wasm32 when compiling assembly. See the added note for more detailed explanation. - - - - - c1fe4ab6 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: enforce cmm switch planning for wasm32 This patch forcibly enable Cmm switch planning for wasm32, since otherwise the switch tables we generate may exceed the br_table maximum allowed size. - - - - - a8adc71e by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: annotate CmmFileEmbed with blob length This patch adds the blob length field to CmmFileEmbed. The wasm32 NCG needs to know the precise size of each data segment. - - - - - 36340328 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: wasm32 NCG This patch adds the wasm32 NCG. - - - - - 435f42ea by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add wasm32-wasi release bindist job - - - - - d8262fdc by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add a stronger test for cross bindists This commit adds a simple GHC API program that parses and reprints the original hello world program used for basic testing of cross bindists. Before there's full cross-compilation support in the test suite driver, this provides better coverage than the original test. - - - - - 8e6ae882 by Cheng Shao at 2022-11-11T00:26:55-05:00 CODEOWNERS: add wasm-specific maintainers - - - - - 707d5651 by Zubin Duggal at 2022-11-11T00:27:31-05:00 Clarify that LLVM upper bound is non-inclusive during configure (#22411) - - - - - 430eccef by Ben Gamari at 2022-11-11T13:16:45-05:00 rts: Check for program_invocation_short_name via autoconf Instead of assuming support on all Linuxes. - - - - - 6dab0046 by Matthew Pickering at 2022-11-11T13:17:22-05:00 driver: Fix -fdefer-diagnostics flag The `withDeferredDiagnostics` wrapper wasn't doing anything because the session it was modifying wasn't used in hsc_env. Therefore the fix is simple, just push the `getSession` call into the scope of `withDeferredDiagnostics`. Fixes #22391 - - - - - d0c691b6 by Simon Peyton Jones at 2022-11-11T13:18:07-05:00 Add a fast path for data constructor workers See Note [Fast path for data constructors] in GHC.Core.Opt.Simplify.Iteration This bypasses lots of expensive logic, in the special case of applications of data constructors. It is a surprisingly worthwhile improvement, as you can see in the figures below. Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Read(normal) -2.0% CoOpt_Singletons(normal) -2.0% ManyConstructors(normal) -1.3% T10421(normal) -1.9% GOOD T10421a(normal) -1.5% T10858(normal) -1.6% T11545(normal) -1.7% T12234(optasm) -1.3% T12425(optasm) -1.9% GOOD T13035(normal) -1.0% GOOD T13056(optasm) -1.8% T13253(normal) -3.3% GOOD T15164(normal) -1.7% T15304(normal) -3.4% T15630(normal) -2.8% T16577(normal) -4.3% GOOD T17096(normal) -1.1% T17516(normal) -3.1% T18282(normal) -1.9% T18304(normal) -1.2% T18698a(normal) -1.2% GOOD T18698b(normal) -1.5% GOOD T18923(normal) -1.3% T1969(normal) -1.3% GOOD T19695(normal) -4.4% GOOD T21839c(normal) -2.7% GOOD T21839r(normal) -2.7% GOOD T4801(normal) -3.8% GOOD T5642(normal) -3.1% GOOD T6048(optasm) -2.5% GOOD T9020(optasm) -2.7% GOOD T9630(normal) -2.1% GOOD T9961(normal) -11.7% GOOD WWRec(normal) -1.0% geo. mean -1.1% minimum -11.7% maximum +0.1% Metric Decrease: T10421 T12425 T13035 T13253 T16577 T18698a T18698b T1969 T19695 T21839c T21839r T4801 T5642 T6048 T9020 T9630 T9961 - - - - - 3c37d30b by Krzysztof Gogolewski at 2022-11-11T19:18:39+01:00 Use a more efficient printer for code generation (#21853) The changes in `GHC.Utils.Outputable` are the bulk of the patch and drive the rest. The types `HLine` and `HDoc` in Outputable can be used instead of `SDoc` and support printing directly to a handle with `bPutHDoc`. See Note [SDoc versus HDoc] and Note [HLine versus HDoc]. The classes `IsLine` and `IsDoc` are used to make the existing code polymorphic over `HLine`/`HDoc` and `SDoc`. This is done for X86, PPC, AArch64, DWARF and dependencies (printing module names, labels etc.). Co-authored-by: Alexis King <lexi.lambda at gmail.com> Metric Decrease: CoOpt_Read ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13379 T18140 T18282 T18698a T18698b T1969 T20049 T21839c T21839r T3064 T3294 T4801 T5321FD T5321Fun T5631 T6048 T783 T9198 T9233 - - - - - 6b92b47f by Matthew Craven at 2022-11-11T18:32:14-05:00 Weaken wrinkle 1 of Note [Scrutinee Constant Folding] Fixes #22375. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 154c70f6 by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Fix fragile RULE setup in GHC.Float In testing my type-vs-constraint patch I found that the handling of Natural literals was very fragile -- and I somehow tripped that fragility in my work. So this patch fixes the fragility. See Note [realToFrac natural-to-float] This made a big (9%) difference in one existing test in perf/should_run/T1-359 Metric Decrease: T10359 - - - - - 778c6adc by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Type vs Constraint: finally nailed This big patch addresses the rats-nest of issues that have plagued us for years, about the relationship between Type and Constraint. See #11715/#21623. The main payload of the patch is: * To introduce CONSTRAINT :: RuntimeRep -> Type * To make TYPE and CONSTRAINT distinct throughout the compiler Two overview Notes in GHC.Builtin.Types.Prim * Note [TYPE and CONSTRAINT] * Note [Type and Constraint are not apart] This is the main complication. The specifics * New primitive types (GHC.Builtin.Types.Prim) - CONSTRAINT - ctArrowTyCon (=>) - tcArrowTyCon (-=>) - ccArrowTyCon (==>) - funTyCon FUN -- Not new See Note [Function type constructors and FunTy] and Note [TYPE and CONSTRAINT] * GHC.Builtin.Types: - New type Constraint = CONSTRAINT LiftedRep - I also stopped nonEmptyTyCon being built-in; it only needs to be wired-in * Exploit the fact that Type and Constraint are distinct throughout GHC - Get rid of tcView in favour of coreView. - Many tcXX functions become XX functions. e.g. tcGetCastedTyVar --> getCastedTyVar * Kill off Note [ForAllTy and typechecker equality], in (old) GHC.Tc.Solver.Canonical. It said that typechecker-equality should ignore the specified/inferred distinction when comparein two ForAllTys. But that wsa only weakly supported and (worse) implies that we need a separate typechecker equality, different from core equality. No no no. * GHC.Core.TyCon: kill off FunTyCon in data TyCon. There was no need for it, and anyway now we have four of them! * GHC.Core.TyCo.Rep: add two FunTyFlags to FunCo See Note [FunCo] in that module. * GHC.Core.Type. Lots and lots of changes driven by adding CONSTRAINT. The key new function is sORTKind_maybe; most other changes are built on top of that. See also `funTyConAppTy_maybe` and `tyConAppFun_maybe`. * Fix a longstanding bug in GHC.Core.Type.typeKind, and Core Lint, in kinding ForAllTys. See new tules (FORALL1) and (FORALL2) in GHC.Core.Type. (The bug was that before (forall (cv::t1 ~# t2). blah), where blah::TYPE IntRep, would get kind (TYPE IntRep), but it should be (TYPE LiftedRep). See Note [Kinding rules for types] in GHC.Core.Type. * GHC.Core.TyCo.Compare is a new module in which we do eqType and cmpType. Of course, no tcEqType any more. * GHC.Core.TyCo.FVs. I moved some free-var-like function into this module: tyConsOfType, visVarsOfType, and occCheckExpand. Refactoring only. * GHC.Builtin.Types. Compiletely re-engineer boxingDataCon_maybe to have one for each /RuntimeRep/, rather than one for each /Type/. This dramatically widens the range of types we can auto-box. See Note [Boxing constructors] in GHC.Builtin.Types The boxing types themselves are declared in library ghc-prim:GHC.Types. GHC.Core.Make. Re-engineer the treatment of "big" tuples (mkBigCoreVarTup etc) GHC.Core.Make, so that it auto-boxes unboxed values and (crucially) types of kind Constraint. That allows the desugaring for arrows to work; it gathers up free variables (including dictionaries) into tuples. See Note [Big tuples] in GHC.Core.Make. There is still work to do here: #22336. But things are better than before. * GHC.Core.Make. We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and aBSENT_CONSTRAINT_ERROR_ID for vaues of kind Constraint. Ditto noInlineId vs noInlieConstraintId in GHC.Types.Id.Make; see Note [inlineId magic]. * GHC.Core.TyCo.Rep. Completely refactor the NthCo coercion. It is now called SelCo, and its fields are much more descriptive than the single Int we used to have. A great improvement. See Note [SelCo] in GHC.Core.TyCo.Rep. * GHC.Core.RoughMap.roughMatchTyConName. Collapse TYPE and CONSTRAINT to a single TyCon, so that the rough-map does not distinguish them. * GHC.Core.DataCon - Mainly just improve documentation * Some significant renamings: GHC.Core.Multiplicity: Many --> ManyTy (easier to grep for) One --> OneTy GHC.Core.TyCo.Rep TyCoBinder --> GHC.Core.Var.PiTyBinder GHC.Core.Var TyCoVarBinder --> ForAllTyBinder AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag GHC.Core.TyCon TyConTyCoBinder --> TyConPiTyBinder Many functions are renamed in consequence e.g. isinvisibleArgFlag becomes isInvisibleForAllTyFlag, etc * I refactored FunTyFlag (was AnonArgFlag) into a simple, flat data type data FunTyFlag = FTF_T_T -- (->) Type -> Type | FTF_T_C -- (-=>) Type -> Constraint | FTF_C_T -- (=>) Constraint -> Type | FTF_C_C -- (==>) Constraint -> Constraint * GHC.Tc.Errors.Ppr. Some significant refactoring in the TypeEqMisMatch case of pprMismatchMsg. * I made the tyConUnique field of TyCon strict, because I saw code with lots of silly eval's. That revealed that GHC.Settings.Constants.mAX_SUM_SIZE can only be 63, because we pack the sum tag into a 6-bit field. (Lurking bug squashed.) Fixes * #21530 Updates haddock submodule slightly. Performance changes ~~~~~~~~~~~~~~~~~~~ I was worried that compile times would get worse, but after some careful profiling we are down to a geometric mean 0.1% increase in allocation (in perf/compiler). That seems fine. There is a big runtime improvement in T10359 Metric Decrease: LargeRecord MultiLayerModulesTH_OneShot T13386 T13719 Metric Increase: T8095 - - - - - 360f5fec by Simon Peyton Jones at 2022-11-11T23:40:11+00:00 Indent closing "#-}" to silence HLint - - - - - e160cf47 by Krzysztof Gogolewski at 2022-11-12T08:05:28-05:00 Fix merge conflict in T18355.stderr Fixes #22446 - - - - - 294f9073 by Simon Peyton Jones at 2022-11-12T23:14:13+00:00 Fix a trivial typo in dataConNonlinearType Fixes #22416 - - - - - 268a3ce9 by Ben Gamari at 2022-11-14T09:36:57-05:00 eventlog: Ensure that IPE output contains actual info table pointers The refactoring in 866c736e introduced a rather subtle change in the semantics of the IPE eventlog output, changing the eventlog field from encoding info table pointers to "TNTC pointers" (which point to entry code when tables-next-to-code is enabled). Fix this. Fixes #22452. - - - - - d91db679 by Matthew Pickering at 2022-11-14T16:48:10-05:00 testsuite: Add tests for T22347 These are fixed in recent versions but might as well add regression tests. See #22347 - - - - - 8f6c576b by Matthew Pickering at 2022-11-14T16:48:45-05:00 testsuite: Improve output from tests which have failing pre_cmd There are two changes: * If a pre_cmd fails, then don't attempt to run the test. * If a pre_cmd fails, then print the stdout and stderr from running that command (which hopefully has a nice error message). For example: ``` =====> 1 of 1 [0, 0, 0] *** framework failure for test-defaulting-plugin(normal) pre_cmd failed: 2 ** pre_cmd was "$MAKE -s --no-print-directory -C defaulting-plugin package.test-defaulting-plugin TOP={top}". stdout: stderr: DefaultLifted.hs:19:13: error: [GHC-76037] Not in scope: type constructor or class ‘Typ’ Suggested fix: Perhaps use one of these: ‘Type’ (imported from GHC.Tc.Utils.TcType), data constructor ‘Type’ (imported from GHC.Plugins) | 19 | instance Eq Typ where | ^^^ make: *** [Makefile:17: package.test-defaulting-plugin] Error 1 Performance Metrics (test environment: local): ``` Fixes #22329 - - - - - 2b7d5ccc by Madeline Haraj at 2022-11-14T22:44:17+00:00 Implement UNPACK support for sum types. This is based on osa's unpack_sums PR from ages past. The meat of the patch is implemented in dataConArgUnpackSum and described in Note [UNPACK for sum types]. - - - - - 78f7ecb0 by Andreas Klebinger at 2022-11-14T22:20:29-05:00 Expand on the need to clone local binders. Fixes #22402. - - - - - 65ce43cc by Krzysztof Gogolewski at 2022-11-14T22:21:05-05:00 Fix :i Constraint printing "type Constraint = Constraint" Since Constraint became a synonym for CONSTRAINT 'LiftedRep, we need the same code for handling printing as for the synonym Type = TYPE 'LiftedRep. This addresses the same bug as #18594, so I'm reusing the test. - - - - - 94549f8f by ARATA Mizuki at 2022-11-15T21:36:03-05:00 configure: Don't check for an unsupported version of LLVM The upper bound is not inclusive. Fixes #22449 - - - - - 02d3511b by Andrew Lelechenko at 2022-11-15T21:36:41-05:00 Fix capitalization in haddock for TestEquality - - - - - 08bf2881 by Cheng Shao at 2022-11-16T09:16:29+00:00 base: make Foreign.Marshal.Pool use RTS internal arena for allocation `Foreign.Marshal.Pool` used to call `malloc` once for each allocation request. Each `Pool` maintained a list of allocated pointers, and traverses the list to `free` each one of those pointers. The extra O(n) overhead is apparently bad for a `Pool` that serves a lot of small allocation requests. This patch uses the RTS internal arena to implement `Pool`, with these benefits: - Gets rid of the extra O(n) overhead. - The RTS arena is simply a bump allocator backed by the block allocator, each allocation request is likely faster than a libc `malloc` call. Closes #14762 #18338. - - - - - 37cfe3c0 by Krzysztof Gogolewski at 2022-11-16T14:50:06-05:00 Misc cleanup * Replace catMaybes . map f with mapMaybe f * Use concatFS to concatenate multiple FastStrings * Fix documentation of -exclude-module * Cleanup getIgnoreCount in GHCi.UI - - - - - b0ac3813 by Lawton Nichols at 2022-11-19T03:22:14-05:00 Give better errors for code corrupted by Unicode smart quotes (#21843) Previously, we emitted a generic and potentially confusing error during lexical analysis on programs containing smart quotes (“/”/‘/’). This commit adds smart quote-aware lexer errors. - - - - - cb8430f8 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make OpaqueNo* tests less noisy to unrelated changes - - - - - b1a8af69 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Simplifier: Consider `seq` as a `BoringCtxt` (#22317) See `Note [Seq is boring]` for the rationale. Fixes #22317. - - - - - 9fd11585 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make T21839c's ghc/max threshold more forgiving - - - - - 4b6251ab by Simon Peyton Jones at 2022-11-19T03:23:24-05:00 Be more careful when reporting unbound RULE binders See Note [Variables unbound on the LHS] in GHC.HsToCore.Binds. Fixes #22471. - - - - - e8f2b80d by Peter Trommler at 2022-11-19T03:23:59-05:00 PPC NCG: Fix generating assembler code Fixes #22479 - - - - - f2f9ef07 by Andrew Lelechenko at 2022-11-20T18:39:30-05:00 Extend documentation for Data.IORef - - - - - ef511b23 by Simon Peyton Jones at 2022-11-20T18:40:05-05:00 Buglet in GHC.Tc.Module.checkBootTyCon This lurking bug used the wrong function to compare two types in GHC.Tc.Module.checkBootTyCon It's hard to trigger the bug, which only came up during !9343, so there's no regression test in this MR. - - - - - 451aeac3 by Andrew Lelechenko at 2022-11-20T18:40:44-05:00 Add since pragmas for c_interruptible_open and hostIsThreaded - - - - - 8d6aaa49 by Duncan Coutts at 2022-11-22T02:06:16-05:00 Introduce CapIOManager as the per-cap I/O mangager state Rather than each I/O manager adding things into the Capability structure ad-hoc, we should have a common CapIOManager iomgr member of the Capability structure, with a common interface to initialise etc. The content of the CapIOManager struct will be defined differently for each I/O manager implementation. Eventually we should be able to have the CapIOManager be opaque to the rest of the RTS, and known just to the I/O manager implementation. We plan for that by making the Capability contain a pointer to the CapIOManager rather than containing the structure directly. Initially just move the Unix threaded I/O manager's control FD. - - - - - 8901285e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Add hook markCapabilityIOManager To allow I/O managers to have GC roots in the Capability, within the CapIOManager structure. Not yet used in this patch. - - - - - 5cf709c5 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move APPEND_TO_BLOCKED_QUEUE from cmm to C The I/O and delay blocking primitives for the non-threaded way currently access the blocked_queue and sleeping_queue directly. We want to move where those queues are to make their ownership clearer: to have them clearly belong to the I/O manager impls rather than to the scheduler. Ultimately we will want to change their representation too. It's inconvenient to do that if these queues are accessed directly from cmm code. So as a first step, replace the APPEND_TO_BLOCKED_QUEUE with a C version appendToIOBlockedQueue(), and replace the open-coded sleeping_queue insertion with insertIntoSleepingQueue(). - - - - - ced9acdb by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move {blocked,sleeping}_queue from scheduler global vars to CapIOManager The blocked_queue_{hd,tl} and the sleeping_queue are currently cooperatively managed between the scheduler and (some but not all of) the non-threaded I/O manager implementations. They lived as global vars with the scheduler, but are poked by I/O primops and the I/O manager backends. This patch is a step on the path towards making the management of I/O or timer blocking belong to the I/O managers and not the scheduler. Specifically, this patch moves the {blocked,sleeping}_queue from being global vars in the scheduler to being members of the CapIOManager struct within each Capability. They are not yet exclusively used by the I/O managers: they are still poked from a couple other places, notably in the scheduler before calling awaitEvent. - - - - - 0f68919e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Remove the now-unused markScheduler The global vars {blocked,sleeping}_queue are now in the Capability and so get marked there via markCapabilityIOManager. - - - - - 39a91f60 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move macros for checking for pending IO or timers from Schedule.h to Schedule.c and IOManager.h This is just moving, the next step will be to rejig them slightly. For the non-threaded RTS the scheduler needs to be able to test for there being pending I/O operation or pending timers. The implementation of these tests should really be considered to be part of the I/O managers and not part of the scheduler. - - - - - 664b034b by Duncan Coutts at 2022-11-22T02:06:17-05:00 Replace EMPTY_{BLOCKED,SLEEPING}_QUEUE macros by function These are the macros originaly from Scheduler.h, previously moved to IOManager.h, and now replaced with a single inline function anyPendingTimeoutsOrIO(). We can use a single function since the two macros were always checked together. Note that since anyPendingTimeoutsOrIO is defined for all IO manager cases, including threaded, we do not need to guard its use by cpp #if !defined(THREADED_RTS) - - - - - 32946220 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Expand emptyThreadQueues inline for clarity It was not really adding anything. The name no longer meant anything since those I/O and timeout queues do not belong to the scheuler. In one of the two places it was used, the comments already had to explain what it did, whereas now the code matches the comment nicely. - - - - - 9943baf9 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move the awaitEvent declaration into IOManager.h And add or adjust comments at the use sites of awaitEvent. - - - - - 054dcc9d by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to awaitEvent It is currently only used in the non-threaded RTS so it works to use MainCapability, but it's a bit nicer to pass the cap anyway. It's certainly shorter. - - - - - 667fe5a4 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to appendToIOBlockedQueue And to insertIntoSleepingQueue. Again, it's a bit cleaner and simpler though not strictly necessary given that these primops are currently only used in the non-threaded RTS. - - - - - 7181b074 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Reveiew feedback: improve one of the TODO comments The one about the nonsense (const False) test on WinIO for there being any IO or timers pending, leading to unnecessary complication later in the scheduler. - - - - - e5b68183 by Andreas Klebinger at 2022-11-22T02:06:52-05:00 Optimize getLevity. Avoid the intermediate data structures allocated by splitTyConApp. This avoids ~0.5% of allocations for a build using -O2. Fixes #22254 - - - - - de5fb348 by Andreas Klebinger at 2022-11-22T02:07:28-05:00 hadrian:Set TNTC when running testsuite. - - - - - 9d61c182 by Oleg Grenrus at 2022-11-22T15:59:34-05:00 Add unsafePtrEquality# restricted to UnliftedTypes - - - - - e817c871 by Jonathan Dowland at 2022-11-22T16:00:14-05:00 utils/unlit: adjust parser to match Report spec The Haskell 2010 Report says that, for Latex-style Literate format, "Program code begins on the first line following a line that begins \begin{code}". (This is unchanged from the 98 Report) However the unlit.c implementation only matches a line that contains "\begin{code}" and nothing else. One consequence of this is that one cannot suffix Latex options to the code environment. I.e., this does not work: \begin{code}[label=foo,caption=Foo Code] Adjust the matcher to conform to the specification from the Report. The Haskell Wiki currently recommends suffixing a '%' to \begin{code} in order to deliberately hide a code block from Haskell. This is bad advice, as it's relying on an implementation quirk rather than specified behaviour. None-the-less, some people have tried to use it, c.f. <https://mail.haskell.org/pipermail/haskell-cafe/2009-September/066780.html> An alternative solution is to define a separate, equivalent Latex environment to "code", that is functionally identical in Latex but ignored by unlit. This should not be a burden: users are required to manually define the code environment anyway, as it is not provided by the Latex verbatim or lstlistings packages usually used for presenting code in documents. Fixes #3549. - - - - - 0b7fef11 by Teo Camarasu at 2022-11-23T12:44:33-05:00 Fix eventlog all option Previously it didn't enable/disable nonmoving_gc and ticky event types Fixes #21813 - - - - - 04d0618c by Arnaud Spiwack at 2022-11-23T12:45:14-05:00 Expand Note [Linear types] with the stance on linting linearity Per the discussion on #22123 - - - - - e1538516 by Lawton Nichols at 2022-11-23T12:45:55-05:00 Add documentation on custom Prelude modules (#22228) Specifically, custom Prelude modules that are named `Prelude`. - - - - - b5c71454 by Sylvain Henry at 2022-11-23T12:46:35-05:00 Don't let configure perform trivial substitutions (#21846) Hadrian now performs substitutions, especially to generate .cabal files from .cabal.in files. Two benefits: 1. We won't have to re-configure when we modify thing.cabal.in. Hadrian will take care of this for us. 2. It paves the way to allow the same package to be configured differently by Hadrian in the same session. This will be useful to fix #19174: we want to build a stage2 cross-compiler for the host platform and a stage1 compiler for the cross target platform in the same Hadrian session. - - - - - 99aca26b by nineonine at 2022-11-23T12:47:11-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043) Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043 - - - - - 040bfdc3 by M Farkas-Dyck at 2022-11-23T21:59:03-05:00 Scrub some no-warning pragmas. - - - - - 178c1fd8 by Vladislav Zavialov at 2022-11-23T21:59:39-05:00 Check if the SDoc starts with a single quote (#22488) This patch fixes pretty-printing of character literals inside promoted lists and tuples. When we pretty-print a promoted list or tuple whose first element starts with a single quote, we want to add a space between the opening bracket and the element: '[True] -- ok '[ 'True] -- ok '['True] -- not ok If we don't add the space, we accidentally produce a character literal '['. Before this patch, pprSpaceIfPromotedTyCon inspected the type as an AST and tried to guess if it would be rendered with a single quote. However, it missed the case when the inner type was itself a character literal: '[ 'x'] -- ok '['x'] -- not ok Instead of adding this particular case, I opted for a more future-proof solution: check the SDoc directly. This way we can detect if the single quote is actually there instead of trying to predict it from the AST. The new function is called spaceIfSingleQuote. - - - - - 11627c42 by Matthew Pickering at 2022-11-23T22:00:15-05:00 notes: Fix references to HPT space leak note Updating this note was missed when updating the HPT to the HUG. Fixes #22477 - - - - - 86ff1523 by Andrei Borzenkov at 2022-11-24T17:24:51-05:00 Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115) Problem: avoid usage of TcRnMessageUnknown Solution: The following `TcRnMessage` messages has been introduced: TcRnNoRebindableSyntaxRecordDot TcRnNoFieldPunsRecordDot TcRnIllegalStaticExpression TcRnIllegalStaticFormInSplice TcRnListComprehensionDuplicateBinding TcRnEmptyStmtsGroup TcRnLastStmtNotExpr TcRnUnexpectedStatementInContext TcRnIllegalTupleSection TcRnIllegalImplicitParameterBindings TcRnSectionWithoutParentheses Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - d198a19a by Cheng Shao at 2022-11-24T17:25:29-05:00 rts: fix missing Arena.h symbols in RtsSymbols.c It was an unfortunate oversight in !8961 and broke devel2 builds. - - - - - 5943e739 by Andrew Lelechenko at 2022-11-25T04:38:28-05:00 Assorted fixes to avoid Data.List.{head,tail} - - - - - 1f1b99b8 by sheaf at 2022-11-25T04:38:28-05:00 Review suggestions for assorted fixes to avoid Data.List.{head,tail} - - - - - 13d627bb by Vladislav Zavialov at 2022-11-25T04:39:04-05:00 Print unticked promoted data constructors (#20531) Before this patch, GHC unconditionally printed ticks before promoted data constructors: ghci> type T = True -- unticked (user-written) ghci> :kind! T T :: Bool = 'True -- ticked (compiler output) After this patch, GHC prints ticks only when necessary: ghci> type F = False -- unticked (user-written) ghci> :kind! F F :: Bool = False -- unticked (compiler output) ghci> data False -- introduce ambiguity ghci> :kind! F F :: Bool = 'False -- ticked by necessity (compiler output) The old behavior can be enabled by -fprint-redundant-promotion-ticks. Summary of changes: * Rename PrintUnqualified to NamePprCtx * Add QueryPromotionTick to it * Consult the GlobalRdrEnv to decide whether to print a tick (see mkPromTick) * Introduce -fprint-redundant-promotion-ticks Co-authored-by: Artyom Kuznetsov <hi at wzrd.ht> - - - - - d10dc6bd by Simon Peyton Jones at 2022-11-25T22:31:27+00:00 Fix decomposition of TyConApps Ticket #22331 showed that we were being too eager to decompose a Wanted TyConApp, leading to incompleteness in the solver. To understand all this I ended up doing a substantial rewrite of the old Note [Decomposing equalities], now reborn as Note [Decomposing TyConApp equalities]. Plus rewrites of other related Notes. The actual fix is very minor and actually simplifies the code: in `can_decompose` in `GHC.Tc.Solver.Canonical.canTyConApp`, we now call `noMatchableIrreds`. A closely related refactor: we stop trying to use the same "no matchable givens" function here as in `matchClassInst`. Instead split into two much simpler functions. - - - - - 2da5c38a by Will Hawkins at 2022-11-26T04:05:04-05:00 Redirect output of musttail attribute test Compilation output from test for support of musttail attribute leaked to the console. - - - - - 0eb1c331 by Cheng Shao at 2022-11-28T08:55:53+00:00 Move hs_mulIntMayOflo cbits to ghc-prim It's only used by wasm NCG at the moment, but ghc-prim is a more reasonable place for hosting out-of-line primops. Also, we only need a single version of hs_mulIntMayOflo. - - - - - 36b53a9d by Cheng Shao at 2022-11-28T09:05:57+00:00 compiler: generate ccalls for clz/ctz/popcnt in wasm NCG We used to generate a single wasm clz/ctz/popcnt opcode, but it's wrong when it comes to subwords, so might as well generate ccalls for them. See #22470 for details. - - - - - d4134e92 by Cheng Shao at 2022-11-28T23:48:14-05:00 compiler: remove unused MO_U_MulMayOflo We actually only emit MO_S_MulMayOflo and never emit MO_U_MulMayOflo anywhere. - - - - - 8d15eadc by Apoorv Ingle at 2022-11-29T03:09:31-05:00 Killing cc_fundeps, streamlining kind equality orientation, and type equality processing order Fixes: #217093 Associated to #19415 This change * Flips the orientation of the the generated kind equality coercion in canEqLHSHetero; * Removes `cc_fundeps` in CDictCan as the check was incomplete; * Changes `canDecomposableTyConAppOk` to ensure we process kind equalities before type equalities and avoiding a call to `canEqLHSHetero` while processing wanted TyConApp equalities * Adds 2 new tests for validating the change - testsuites/typecheck/should_compile/T21703.hs and - testsuites/typecheck/should_fail/T19415b.hs (a simpler version of T19415.hs) * Misc: Due to the change in the equality direction some error messages now have flipped type mismatch errors * Changes in Notes: - Note [Fundeps with instances, and equality orientation] supercedes Note [Fundeps with instances] - Added Note [Kind Equality Orientation] to visualize the kind flipping - Added Note [Decomposing Dependent TyCons and Processing Wanted Equalties] - - - - - 646969d4 by Krzysztof Gogolewski at 2022-11-29T03:10:13-05:00 Change printing of sized literals to match the proposal Literals in Core were printed as e.g. 0xFF#16 :: Int16#. The proposal 451 now specifies syntax 0xFF#Int16. This change affects the Core printer only - more to be done later. Part of #21422. - - - - - 02e282ec by Simon Peyton Jones at 2022-11-29T03:10:48-05:00 Be a bit more selective about floating bottoming expressions This MR arranges to float a bottoming expression to the top only if it escapes a value lambda. See #22494 and Note [Floating to the top] in SetLevels. This has a generally beneficial effect in nofib +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || -0.93% | | imaginary/rfib || -0.05% | | real/fem || -0.03% | | real/fluid || -0.01% | | real/fulsom || +0.05% | | real/gamteb || -0.27% | | real/gg || -0.10% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/scs || -11.13% | | shootout/k-nucleotide || -0.01% | | shootout/n-body || -0.08% | | shootout/reverse-complement || -0.00% | | shootout/spectral-norm || -0.02% | | spectral/fibheaps || -0.20% | | spectral/hartel/fft || -1.04% | | spectral/hartel/solid || +0.33% | | spectral/hartel/wave4main || -0.35% | | spectral/mate || +0.76% | +===============================++==========+ | geom mean || -0.12% | The effect on compile time is generally slightly beneficial Metrics: compile_time/bytes allocated ---------------------------------------------- MultiLayerModulesTH_OneShot(normal) +0.3% PmSeriesG(normal) -0.2% PmSeriesT(normal) -0.1% T10421(normal) -0.1% T10421a(normal) -0.1% T10858(normal) -0.1% T11276(normal) -0.1% T11303b(normal) -0.2% T11545(normal) -0.1% T11822(normal) -0.1% T12150(optasm) -0.1% T12234(optasm) -0.3% T13035(normal) -0.2% T16190(normal) -0.1% T16875(normal) -0.4% T17836b(normal) -0.2% T17977(normal) -0.2% T17977b(normal) -0.2% T18140(normal) -0.1% T18282(normal) -0.1% T18304(normal) -0.2% T18698a(normal) -0.1% T18923(normal) -0.1% T20049(normal) -0.1% T21839r(normal) -0.1% T5837(normal) -0.4% T6048(optasm) +3.2% BAD T9198(normal) -0.2% T9630(normal) -0.1% TcPlugin_RewritePerf(normal) -0.4% hard_hole_fits(normal) -0.1% geo. mean -0.0% minimum -0.4% maximum +3.2% The T6048 outlier is hard to pin down, but it may be the effect of reading in more interface files definitions. It's a small program for which compile time is very short, so I'm not bothered about it. Metric Increase: T6048 - - - - - ab23dc5e by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Mark unpack_sums_6 as fragile due to #22504 This test is explicitly dependent upon runtime, which is generally not appropriate given that the testsuite is run in parallel and generally saturates the CPU. - - - - - def47dd3 by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Don't use grep -q in unpack_sums_7 `grep -q` closes stdin as soon as it finds the pattern it is looking for, resulting in #22484. - - - - - cc25d52e by Sylvain Henry at 2022-11-29T09:44:31+01:00 Add Javascript backend Add JS backend adapted from the GHCJS project by Luite Stegeman. Some features haven't been ported or implemented yet. Tests for these features have been disabled with an associated gitlab ticket. Bump array submodule Work funded by IOG. Co-authored-by: Jeffrey Young <jeffrey.young at iohk.io> Co-authored-by: Luite Stegeman <stegeman at gmail.com> Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 68c966cd by sheaf at 2022-11-30T09:31:25-05:00 Fix @since annotations on WithDict and Coercible Fixes #22453 - - - - - a3a8e9e9 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. - - - - - a9d9b8c0 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Use mkNakedFunTy in tcPatSynSig As #22521 showed, in tcPatSynSig we make a "fake type" to kind-generalise; and that type has unzonked type variables in it. So we must not use `mkFunTy` (which checks FunTy's invariants) via `mkPhiTy` when building this type. Instead we need to use `mkNakedFunTy`. Easy fix. - - - - - 31462d98 by Andreas Klebinger at 2022-11-30T14:50:58-05:00 Properly cast values when writing/reading unboxed sums. Unboxed sums might store a Int8# value as Int64#. This patch makes sure we keep track of the actual value type. See Note [Casting slot arguments] for the details. - - - - - 10a2a7de by Oleg Grenrus at 2022-11-30T14:51:39-05:00 Move Void to GHC.Base... This change would allow `Void` to be used deeper in module graph. For example exported from `Prelude` (though that might be already possible). Also this change includes a change `stimes @Void _ x = x`, https://github.com/haskell/core-libraries-committee/issues/95 While the above is not required, maintaining old stimes behavior would be tricky as `GHC.Base` doesn't know about `Num` or `Integral`, which would require more hs-boot files. - - - - - b4cfa8e2 by Sebastian Graf at 2022-11-30T14:52:24-05:00 DmdAnal: Reflect the `seq` of strict fields of a DataCon worker (#22475) See the updated `Note [Data-con worker strictness]` and the new `Note [Demand transformer for data constructors]`. Fixes #22475. - - - - - d87f28d8 by Baldur Blöndal at 2022-11-30T21:16:36+01:00 Make Functor a quantified superclass of Bifunctor. See https://github.com/haskell/core-libraries-committee/issues/91 for discussion. This change relates Bifunctor with Functor by requiring second = fmap. Moreover this change is a step towards unblocking the major version bump of bifunctors and profunctors to major version 6. This paves the way to move the Profunctor class into base. For that Functor first similarly becomes a superclass of Profunctor in the new major version 6. - - - - - 72cf4c5d by doyougnu at 2022-12-01T12:36:44-05:00 FastString: SAT bucket_match Metric Decrease: MultiLayerModulesTH_OneShot - - - - - afc2540d by Simon Peyton Jones at 2022-12-01T12:37:20-05:00 Add a missing varToCoreExpr in etaBodyForJoinPoint This subtle bug showed up when compiling a library with 9.4. See #22491. The bug is present in master, but it is hard to trigger; the new regression test T22491 fails in 9.4. The fix was easy: just add a missing varToCoreExpr in etaBodyForJoinPoint. The fix is definitely right though! I also did some other minor refatoring: * Moved the preInlineUnconditionally test in simplExprF1 to before the call to joinPointBinding_maybe, to avoid fruitless eta-expansion. * Added a boolean from_lam flag to simplNonRecE, to avoid two fruitless tests, and commented it a bit better. These refactorings seem to save 0.1% on compile-time allocation in perf/compiler; with a max saving of 1.4% in T9961 Metric Decrease: T9961 - - - - - 81eeec7f by M Farkas-Dyck at 2022-12-01T12:37:56-05:00 CI: Forbid the fully static build on Alpine to fail. To do so, we mark some tests broken in this configuration. - - - - - c5d1bf29 by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Remove ARMv7 jobs These jobs fail (and are allowed to fail) nearly every time. Soon they won't even be able to run at all, as we won't currently have runners that can run them. Fixing the latter problem is tracked in #22409. I went ahead and removed all settings and configurations. - - - - - d82992fd by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Fix CI lint Failure was introduced by conflicting changes to gen_ci.hs that did *not* trigger git conflicts. - - - - - ce126993 by Simon Peyton Jones at 2022-12-02T01:22:12-05:00 Refactor TyCon to have a top-level product This patch changes the representation of TyCon so that it has a top-level product type, with a field that gives the details (newtype, type family etc), #22458. Not much change in allocation, but execution seems to be a bit faster. Includes a change to the haddock submodule to adjust for API changes. - - - - - 74c767df by Matthew Pickering at 2022-12-02T01:22:48-05:00 ApplicativeDo: Set pattern location before running exhaustiveness checker This improves the error messages of the exhaustiveness checker when checking statements which have been moved around with ApplicativeDo. Before: Test.hs:2:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 2 | let x = () | ^^^^^^^^^^ After: Test.hs:4:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 4 | ~(Just res1) <- seq x (pure $ Nothing @()) | Fixes #22483 - - - - - 85ecc1a0 by Matthew Pickering at 2022-12-02T19:46:43-05:00 Add special case for :Main module in `GHC.IfaceToCore.mk_top_id` See Note [Root-main Id] The `:Main` special binding is actually defined in the current module (hence don't go looking for it externally) but the module name is rOOT_MAIN rather than the current module so we need this special case. There was already some similar logic in `GHC.Rename.Env` for External Core, but now the "External Core" is in interface files it needs to be moved here instead. Fixes #22405 - - - - - 108c319f by Krzysztof Gogolewski at 2022-12-02T19:47:18-05:00 Fix linearity checking in Lint Lint was not able to see that x*y <= x*y, because this inequality was decomposed to x <= x*y && y <= x*y, but there was no rule to see that x <= x*y. Fixes #22546. - - - - - bb674262 by Bryan Richter at 2022-12-03T04:38:46-05:00 Mark T16916 fragile See https://gitlab.haskell.org/ghc/ghc/-/issues/16966 - - - - - 5d267d46 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 Refactor: FreshOrReuse instead of addTyClTyVarBinds This is a refactoring that should have no effect on observable behavior. Prior to this change, GHC.HsToCore.Quote contained a few closely related functions to process type variable bindings: addSimpleTyVarBinds, addHsTyVarBinds, addQTyVarBinds, and addTyClTyVarBinds. We can classify them by their input type and name generation strategy: Fresh names only Reuse bound names +---------------------+-------------------+ [Name] | addSimpleTyVarBinds | | [LHsTyVarBndr flag GhcRn] | addHsTyVarBinds | | LHsQTyVars GhcRn | addQTyVarBinds | addTyClTyVarBinds | +---------------------+-------------------+ Note how two functions are missing. Because of this omission, there were two places where a LHsQTyVars value was constructed just to be able to pass it to addTyClTyVarBinds: 1. mk_qtvs in addHsOuterFamEqnTyVarBinds -- bad 2. mkHsQTvs in repFamilyDecl -- bad This prevented me from making other changes to LHsQTyVars, so the main goal of this refactoring is to get rid of those workarounds. The most direct solution would be to define the missing functions. But that would lead to a certain amount of code duplication. To avoid code duplication, I factored out the name generation strategy into a function parameter: data FreshOrReuse = FreshNamesOnly | ReuseBoundNames addSimpleTyVarBinds :: FreshOrReuse -> ... addHsTyVarBinds :: FreshOrReuse -> ... addQTyVarBinds :: FreshOrReuse -> ... - - - - - c189b831 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 addHsOuterFamEqnTyVarBinds: use FreshNamesOnly for explicit binders Consider this example: [d| instance forall a. C [a] where type forall b. G [a] b = Proxy b |] When we process "forall b." in the associated type instance, it is unambiguously the binding site for "b" and we want a fresh name for it. Therefore, FreshNamesOnly is more fitting than ReuseBoundNames. This should not have any observable effect but it avoids pointless lookups in the MetaEnv. - - - - - 42512264 by Ross Paterson at 2022-12-03T10:32:45+00:00 Handle type data declarations in Template Haskell quotations and splices (fixes #22500) This adds a TypeDataD constructor to the Template Haskell Dec type, and ensures that the constructors it contains go in the TyCls namespace. - - - - - 1a767fa3 by Vladislav Zavialov at 2022-12-05T05:18:50-05:00 Add BufSpan to EpaLocation (#22319, #22558) The key part of this patch is the change to mkTokenLocation: - mkTokenLocation (RealSrcSpan r _) = TokenLoc (EpaSpan r) + mkTokenLocation (RealSrcSpan r mb) = TokenLoc (EpaSpan r mb) mkTokenLocation used to discard the BufSpan, but now it is saved and can be retrieved from LHsToken or LHsUniToken. This is made possible by the following change to EpaLocation: - data EpaLocation = EpaSpan !RealSrcSpan + data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | ... The end goal is to make use of the BufSpan in Parser/PostProcess/Haddock. - - - - - cd31acad by sheaf at 2022-12-06T15:45:58-05:00 Hadrian: fix ghcDebugAssertions off-by-one error Commit 6b2f7ffe changed the logic that decided whether to enable debug assertions. However, it had an off-by-one error, as the stage parameter to the function inconsistently referred to the stage of the compiler being used to build or the stage of the compiler we are building. This patch makes it consistent. Now the parameter always refers to the the compiler which is being built. In particular, this patch re-enables assertions in the stage 2 compiler when building with devel2 flavour, and disables assertions in the stage 2 compiler when building with validate flavour. Some extra performance tests are now run in the "validate" jobs because the stage2 compiler no longer contains assertions. ------------------------- Metric Decrease: CoOpt_Singletons MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot T11374 T12227 T12234 T13253-spj T13701 T14683 T14697 T15703 T17096 T17516 T18304 T18478 T18923 T5030 T9872b TcPlugin_RewritePerf Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T13386 T13719 T3294 T9233 T9675 parsing001 ------------------------- - - - - - 21d66db1 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInstallNameTool - - - - - aaaaa79b by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of askOtool - - - - - 4e28f49e by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInjectRPaths - - - - - a7422580 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of Linker.MacOS - - - - - e902d771 by Matthew Craven at 2022-12-08T08:30:23-05:00 Fix bounds-checking buglet in Data.Array.Byte ...another manifestation of #20851 which I unfortunately missed in my first pass. - - - - - 8d36c0c6 by Gergő Érdi at 2022-12-08T08:31:03-05:00 Remove copy-pasted definitions of `graphFromEdgedVertices*` - - - - - c5d8ed3a by Gergő Érdi at 2022-12-08T08:31:03-05:00 Add version of `reachableGraph` that avoids loop for cyclic inputs by building its result connected component by component Fixes #22512 - - - - - 90cd5396 by Krzysztof Gogolewski at 2022-12-08T08:31:39-05:00 Mark Type.Reflection.Unsafe as Unsafe This module can be used to construct ill-formed TypeReps, so it should be Unsafe. - - - - - 2057c77d by Ian-Woo Kim at 2022-12-08T08:32:19-05:00 Truncate eventlog event for large payload (#20221) RTS eventlog events for postCapsetVecEvent are truncated if payload is larger than EVENT_PAYLOAD_SIZE_MAX Previously, postCapsetVecEvent records eventlog event with payload of variable size larger than EVENT_PAYLOAD_SIZE_MAX (2^16) without any validation, resulting in corrupted data. For example, this happens when a Haskell binary is invoked with very long command line arguments exceeding 2^16 bytes (see #20221). Now we check the size of accumulated payload messages incrementally, and truncate the message just before the payload size exceeds EVENT_PAYLOAD_SIZE_MAX. RTS will warn the user with a message showing how many arguments are truncated. - - - - - 9ec76f61 by Cheng Shao at 2022-12-08T08:32:59-05:00 hadrian: don't add debug info to non-debug ways of rts Hadrian used to pass -g when building all ways of rts. It makes output binaries larger (especially so for wasm backend), and isn't needed by most users out there, so this patch removes that flag. In case the debug info is desired, we still pass -g3 when building the debug way, and there's also the debug_info flavour transformer which ensures -g3 is passed for all rts ways. - - - - - 7658cdd4 by Krzysztof Gogolewski at 2022-12-08T08:33:36-05:00 Restore show (typeRep @[]) == "[]" The Show instance for TypeRep [] has changed in 9.5 to output "List" because the name of the type constructor changed. This seems to be accidental and is inconsistent with TypeReps of saturated lists, which are printed as e.g. "[Int]". For now, I'm restoring the old behavior; in the future, maybe we should show TypeReps without puns (List, Tuple, Type). - - - - - 216deefd by Matthew Pickering at 2022-12-08T22:45:27-05:00 Add test for #22162 - - - - - 5d0a311f by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job to test interface file determinism guarantees In this job we can run on every commit we add a test which builds the Cabal library twice and checks that the ABI hash and interface hash is stable across the two builds. * We run the test 20 times to try to weed out any race conditions due to `-j` * We run the builds in different temporary directories to try to weed out anything related to build directory affecting ABI or interface file hash. Fixes #22180 - - - - - 0a76d7d4 by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job for testing interface stability across builds The idea is that both the bindists should product libraries with the same ABI and interface hash. So the job checks with ghc-pkg to make sure the computed ABI is the same. In future this job can be extended to check for the other facets of interface determinism. Fixes #22180 - - - - - 74c9bf91 by Matthew Pickering at 2022-12-08T22:45:27-05:00 backpack: Be more careful when adding together ImportAvails There was some code in the signature merging logic which added together the ImportAvails of the signature and the signature which was merged into it. This had the side-effect of making the merged signature depend on the signature (via a normal module dependency). The intention was to propagate orphan instances through the merge but this also messed up recompilation logic because we shouldn't be attempting to load B.hi when mergeing it. The fix is to just combine the part of ImportAvails that we intended to (transitive info, orphan instances and type family instances) rather than the whole thing. - - - - - d122e022 by Matthew Pickering at 2022-12-08T22:45:27-05:00 Fix mk_mod_usage_info if the interface file is not already loaded In #22217 it was observed that the order modules are compiled in affects the contents of an interface file. This was because a module dependended on another module indirectly, via a re-export but the interface file for this module was never loaded because the symbol was never used in the file. If we decide that we depend on a module then we jolly well ought to record this fact in the interface file! Otherwise it could lead to very subtle recompilation bugs if the dependency is not tracked and the module is updated. Therefore the best thing to do is just to make sure the file is loaded by calling the `loadSysInterface` function. This first checks the caches (like we did before) but then actually goes to find the interface on disk if it wasn't loaded. Fixes #22217 - - - - - ea25088d by lrzlin at 2022-12-08T22:46:06-05:00 Add initial support for LoongArch Architecture. - - - - - 9eb9d2f4 by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Update submodule mtl to 2.3.1, parsec to 3.1.15.1, haddock and Cabal to HEAD - - - - - 08d8fe2a by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Allow mtl-2.3 in hadrian - - - - - 3807a46c by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Support mtl-2.3 in check-exact - - - - - ef702a18 by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Fix tests - - - - - 3144e8ff by Sebastian Graf at 2022-12-08T22:47:22-05:00 Make (^) INLINE (#22324) So that we get to cancel away the allocation for the lazily used base. We can move `powImpl` (which *is* strict in the base) to the top-level so that we don't duplicate too much code and move the SPECIALISATION pragmas onto `powImpl`. The net effect of this change is that `(^)` plays along much better with inlining thresholds and loopification (#22227), for example in `x2n1`. Fixes #22324. - - - - - 1d3a8b8e by Matthew Pickering at 2022-12-08T22:47:59-05:00 Typeable: Fix module locations of some definitions in GHC.Types There was some confusion in Data.Typeable about which module certain wired-in things were defined in. Just because something is wired-in doesn't mean it comes from GHC.Prim, in particular things like LiftedRep and RuntimeRep are defined in GHC.Types and that's the end of the story. Things like Int#, Float# etc are defined in GHC.Prim as they have no Haskell definition site at all so we need to generate type representations for them (which live in GHC.Types). Fixes #22510 - - - - - 0f7588b5 by Sebastian Graf at 2022-12-08T22:48:34-05:00 Make `drop` and `dropWhile` fuse (#18964) I copied the fusion framework we have in place for `take`. T18964 asserts that we regress neither when fusion fires nor when it doesn't. Fixes #18964. - - - - - 26e71562 by Sebastian Graf at 2022-12-08T22:49:10-05:00 Do not strictify a DFun's parameter dictionaries (#22549) ... thus fixing #22549. The details are in the refurbished and no longer dead `Note [Do not strictify a DFun's parameter dictionaries]`. There's a regression test in T22549. - - - - - 36093407 by John Ericson at 2022-12-08T22:49:45-05:00 Delete `rts/package.conf.in` It is a relic of the Make build system. The RTS now uses a `package.conf` file generated the usual way by Cabal. - - - - - b0cc2fcf by Krzysztof Gogolewski at 2022-12-08T22:50:21-05:00 Fixes around primitive literals * The SourceText of primitive characters 'a'# did not include the #, unlike for other primitive literals 1#, 1##, 1.0#, 1.0##, "a"#. We can now remove the function pp_st_suffix, which was a hack to add the # back. * Negative primitive literals shouldn't use parentheses, as described in Note [Printing of literals in Core]. Added a testcase to T14681. - - - - - aacf616d by Bryan Richter at 2022-12-08T22:50:56-05:00 testsuite: Mark conc024 fragile on Windows - - - - - ed239a24 by Ryan Scott at 2022-12-09T09:42:16-05:00 Document TH splices' interaction with INCOHERENT instances Top-level declaration splices can having surprising interactions with `INCOHERENT` instances, as observed in #22492. This patch resolves #22492 by documenting this strange interaction in the GHC User's Guide. [ci skip] - - - - - 1023b432 by Mike Pilgrem at 2022-12-09T09:42:56-05:00 Fix #22300 Document GHC's extensions to valid whitespace - - - - - 79b0cec0 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Add support for environments that don't have setImmediate - - - - - 5b007ec5 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Fix bound thread status - - - - - 65335d10 by Matthew Pickering at 2022-12-09T20:15:45-05:00 Update containers submodule This contains a fix necessary for the multi-repl to work on GHC's code base where we try to load containers and template-haskell into the same session. - - - - - 4937c0bb by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-multi: Put interface files in separate directories Before we were putting all the interface files in the same directory which was leading to collisions if the files were called the same thing. - - - - - 8acb5b7b by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-toolargs: Add filepath to allowed repl targets - - - - - 5949d927 by Matthew Pickering at 2022-12-09T20:15:45-05:00 driver: Set correct UnitId when rehydrating modules We were not setting the UnitId before rehydrating modules which just led to us attempting to find things in the wrong HPT. The test for this is the hadrian-multi command (which is now added as a CI job). Fixes #22222 - - - - - ab06c0f0 by Matthew Pickering at 2022-12-09T20:15:45-05:00 ci: Add job to test hadrian-multi command I am not sure this job is good because it requires booting HEAD with HEAD, but it should be fine. - - - - - fac3e568 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hadrian: Update bootstrap plans to 9.2.* series and 9.4.* series. This updates the build plans for the most recent compiler versions, as well as fixing the hadrian-bootstrap-gen script to a specific GHC version. - - - - - 195b08b4 by Matthew Pickering at 2022-12-09T20:16:20-05:00 ci: Bump boot images to use ghc-9.4.3 Also updates the bootstrap jobs to test booting 9.2 and 9.4. - - - - - c658c580 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hlint: Removed redundant UnboxedSums pragmas UnboxedSums is quite confusingly implied by UnboxedTuples, alas, just the way it is. See #22485 - - - - - b3e98a92 by Oleg Grenrus at 2022-12-11T12:26:17-05:00 Add heqT, a kind-heterogeneous variant of heq CLC proposal https://github.com/haskell/core-libraries-committee/issues/99 - - - - - bfd7c1e6 by Andrew Lelechenko at 2022-12-11T12:26:55-05:00 Document that Bifunctor instances for tuples are lawful only up to laziness - - - - - 5d1a1881 by Bryan Richter at 2022-12-12T16:22:36-05:00 Mark T21336a fragile - - - - - c30accc2 by Matthew Pickering at 2022-12-12T16:23:11-05:00 Add test for #21476 This issues seems to have been fixed since the ticket was made, so let's add a test and move on. Fixes #21476 - - - - - e9d74a3e by Sebastian Graf at 2022-12-13T22:18:39-05:00 Respect -XStrict in the pattern-match checker (#21761) We were missing a call to `decideBangHood` in the pattern-match checker. There is another call in `matchWrapper.mk_eqn_info` which seems redundant but really is not; see `Note [Desugaring -XStrict matches in Pmc]`. Fixes #21761. - - - - - 884790e2 by Gergő Érdi at 2022-12-13T22:19:14-05:00 Fix loop in the interface representation of some `Unfolding` fields As discovered in #22272, dehydration of the unfolding info of a recursive definition used to involve a traversal of the definition itself, which in turn involves traversing the unfolding info. Hence, a loop. Instead, we now store enough data in the interface that we can produce the unfolding info without this traversal. See Note [Tying the 'CoreUnfolding' knot] for details. Fixes #22272 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 9f301189 by Alan Zimmerman at 2022-12-13T22:19:50-05:00 EPA: When splitting out header comments, keep ones for first decl Any comments immediately preceding the first declaration are no longer kept as header comments, but attach to the first declaration instead. - - - - - 8b1f1b45 by Sylvain Henry at 2022-12-13T22:20:28-05:00 JS: fix object file name comparison (#22578) - - - - - e9e161bb by Bryan Richter at 2022-12-13T22:21:03-05:00 configure: Bump min bootstrap GHC version to 9.2 - - - - - 75855643 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Don't enable TSAN in stage0 build - - - - - da7b51d8 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce blockConcat - - - - - 34f6b09c by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce MemoryOrderings - - - - - 43beaa7b by Ben Gamari at 2022-12-15T03:54:02-05:00 llvm: Respect memory specified orderings - - - - - 8faf74fc by Ben Gamari at 2022-12-15T03:54:02-05:00 Codegen/x86: Eliminate barrier for relaxed accesses - - - - - 6cc3944a by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Reduce some repetition - - - - - 6c9862c4 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Add syntax for ordered loads and stores - - - - - 748490d2 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Atomic load syntax Originally I had thought I would just use the `prim` call syntax instead of introducing new syntax for atomic loads. However, it turns out that `prim` call syntax tends to make things quite unreadable. This new syntax seems quite natural. - - - - - 28c6781a by Ben Gamari at 2022-12-15T03:54:02-05:00 codeGen: Introduce ThreadSanitizer instrumentation This introduces a new Cmm pass which instruments the program with ThreadSanitizer annotations, allowing full tracking of mutator memory accesses via TSAN. - - - - - d97aa311 by Ben Gamari at 2022-12-15T03:54:02-05:00 Hadrian: Drop TSAN_ENABLED define from flavour This is redundant since the TSANUtils.h already defines it. - - - - - 86974ef1 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Enable Cmm instrumentation in TSAN flavour - - - - - 93723290 by Ben Gamari at 2022-12-15T03:54:02-05:00 rts: Ensure that global regs are never passed as fun call args This is in general unsafe as they may be clobbered if they are mapped to caller-saved machine registers. See Note [Register parameter passing]. - - - - - 2eb0fb87 by Matthew Pickering at 2022-12-15T03:54:39-05:00 Package Imports: Get candidate packages also from re-exported modules Previously we were just looking at the direct imports to try and work out what a package qualifier could apply to but #22333 pointed out we also needed to look for reexported modules. Fixes #22333 - - - - - 552b7908 by Ben Gamari at 2022-12-15T03:55:15-05:00 compiler: Ensure that MutVar operations have necessary barriers Here we add acquire and release barriers in readMutVar# and writeMutVar#, which are necessary for soundness. Fixes #22468. - - - - - 933d61a4 by Simon Peyton Jones at 2022-12-15T03:55:51-05:00 Fix bogus test in Lint The Lint check for branch compatiblity within an axiom, in GHC.Core.Lint.compatible_branches was subtly different to the check made when contructing an axiom, in GHC.Core.FamInstEnv.compatibleBranches. The latter is correct, so I killed the former and am now using the latter. On the way I did some improvements to pretty-printing and documentation. - - - - - 03ed0b95 by Ryan Scott at 2022-12-15T03:56:26-05:00 checkValidInst: Don't expand synonyms when splitting sigma types Previously, the `checkValidInst` function (used when checking that an instance declaration is headed by an actual type class, not a type synonym) was using `tcSplitSigmaTy` to split apart the `forall`s and instance context. This is incorrect, however, as `tcSplitSigmaTy` expands type synonyms, which can cause instances headed by quantified constraint type synonyms to be accepted erroneously. This patch introduces `splitInstTyForValidity`, a variant of `tcSplitSigmaTy` specialized for validity checking that does _not_ expand type synonyms, and uses it in `checkValidInst`. Fixes #22570. - - - - - ed056bc3 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/Messages: Refactor This doesn't change behavior but makes the code a bit easier to follow. - - - - - 7356f8e0 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/ThreadPaused: Ordering fixes - - - - - 914f0025 by Ben Gamari at 2022-12-16T16:12:44-05:00 eventlog: Silence spurious data race - - - - - fbc84244 by Ben Gamari at 2022-12-16T16:12:44-05:00 Introduce SET_INFO_RELEASE for Cmm - - - - - 821b5472 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Use fences instead of explicit barriers - - - - - 2228c999 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/stm: Fix memory ordering in readTVarIO# See #22421. - - - - - 99269b9f by Ben Gamari at 2022-12-16T16:12:44-05:00 Improve heap memory barrier Note Also introduce MUT_FIELD marker in Closures.h to document mutable fields. - - - - - 70999283 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. - - - - - 98689f77 by Ben Gamari at 2022-12-16T16:12:44-05:00 ghc: Fix data race in dump file handling Previously the dump filename cache would use a non-atomic update which could potentially result in lost dump contents. Note that this is still a bit racy since the first writer may lag behind a later appending writer. - - - - - 605d9547 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. - - - - - 86f20258 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. - - - - - f8e901dc by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. - - - - - e0affaa9 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate access to capabilities array - - - - - 7ca683e4 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate sched_state - - - - - 1cf13bd0 by Ben Gamari at 2022-12-16T16:12:45-05:00 PrimOps: Fix benign MutVar race Relaxed ordering is fine here since the later CAS implies a release. - - - - - 3d2a7e08 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Style fix - - - - - 82c62074 by Ben Gamari at 2022-12-16T16:12:45-05:00 compiler: Use release store in eager blackholing - - - - - eb1a0136 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Fix ordering of makeStableName - - - - - ad0e260a by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Use ordered accesses instead of explicit barriers - - - - - a3eccf06 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Statically allocate capabilities This is a rather simplistic way of solving #17289. - - - - - 287fa3fb by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Ensure that all accesses to pending_sync are atomic - - - - - 351eae58 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Note race with wakeBlockingQueue - - - - - 5acf33dd by Andrew Lelechenko at 2022-12-16T16:13:22-05:00 Bump submodule directory to 1.3.8.0 and hpc to HEAD - - - - - 0dd95421 by Andrew Lelechenko at 2022-12-16T16:13:22-05:00 Accept allocations increase on Windows This is because of `filepath-1.4.100.0` and AFPP, causing increasing round-trips between lists and ByteArray. See #22625 for discussion. Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T10547 T12150 T12227 T12234 T12425 T13035 T13253 T13253-spj T13701 T13719 T15703 T16875 T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T21839r T5837 T6048 T9198 T9961 TcPlugin_RewritePerf hard_hole_fits - - - - - ef9ac9d2 by Cheng Shao at 2022-12-16T16:13:59-05:00 testsuite: Mark T9405 as fragile instead of broken on Windows It's starting to pass again, and the unexpected pass blocks CI. - - - - - 1f3abd85 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: remove obsolete commented code in wasm NCG It was just a temporary hack to workaround a bug in the relooper, that bug has been fixed long before the wasm backend is merged. - - - - - e3104eab by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add missing export list of GHC.CmmToAsm.Wasm.FromCmm Also removes some unreachable code here. - - - - - 1c6930bf by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: change fallback function signature to Cmm function signature in wasm NCG In the wasm NCG, when handling a `CLabel` of undefined function without knowing its function signature, we used to fallback to `() -> ()` which is accepted by `wasm-ld`. This patch changes it to the signature of Cmm functions, which equally works, but would be required when we emit tail call instructions. - - - - - 8a81d9d9 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add optional tail-call support in wasm NCG When the `-mtail-call` clang flag is passed at configure time, wasm tail-call extension is enabled, and the wasm NCG will emit `return_call`/`return_call_indirect` instructions to take advantage of it and avoid the `StgRun` trampoline overhead. Closes #22461. - - - - - d1431cc0 by Cheng Shao at 2022-12-17T08:07:15-05:00 base: add missing autoconf checks for waitpid/umask These are not present in wasi-libc. Required for fixing #22589 - - - - - da3f1e91 by Cheng Shao at 2022-12-17T08:07:51-05:00 compiler: make .wasm the default executable extension on wasm32 Following convention as in other wasm toolchains. Fixes #22594. - - - - - ad21f4ef by Cheng Shao at 2022-12-17T08:07:51-05:00 ci: support hello.wasm in ci.sh cross testing logic - - - - - 6fe2d778 by amesgen at 2022-12-18T19:33:49-05:00 Correct `exitWith` Haddocks The `IOError`-specific `catch` in the Prelude is long gone. - - - - - b3eacd64 by Ben Gamari at 2022-12-18T19:34:24-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 761c1f49 by Ben Gamari at 2022-12-18T19:35:00-05:00 rts/libdw: Silence uninitialized usage warnings As noted in #22538, previously some GCC versions warned that various locals in Libdw.c may be used uninitialized. Although this wasn't strictly true (since they were initialized in an inline assembler block) we fix this by providing explicit empty initializers. Fixes #22538 - - - - - 5e047eff by Matthew Pickering at 2022-12-20T15:12:04+00:00 testsuite: Mark T16392 as fragile on windows See #22649 - - - - - 703a4665 by M Farkas-Dyck at 2022-12-20T21:14:46-05:00 Scrub some partiality in `GHC.Cmm.Info.Build`: `doSRTs` takes a `[(CAFSet, CmmDecl)]` but truly wants a `[(CAFSet, CmmStatics)]`. - - - - - 9736ab74 by Matthew Pickering at 2022-12-20T21:15:22-05:00 packaging: Fix upload_ghc_libs.py script This change reflects the changes where .cabal files are now generated by hadrian rather than ./configure. Fixes #22518 - - - - - 7c6de18d by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Drop uses of AC_PROG_CC_C99 As noted in #22566, this macro is deprecated as of autoconf-2.70 `AC_PROG_CC` now sets `ac_cv_prog_cc_c99` itself. Closes #22566. - - - - - 36c5d98e by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Use AS_HELP_STRING instead of AC_HELP_STRING The latter has been deprecated. See #22566. - - - - - befe6ff8 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 GHCi.UI: fix various usages of head and tail - - - - - 666d0ba7 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 GHCi.UI: avoid head and tail in parseCallEscape and around - - - - - 5d96fd50 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 Make GHC.Driver.Main.hscTcRnLookupRdrName to return NonEmpty - - - - - 3ce2ab94 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Allow transformers-0.6 in ghc, ghci, ghc-bin and hadrian - - - - - 954de93a by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Update submodule haskeline to HEAD (to allow transformers-0.6) - - - - - cefbeec3 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Update submodule transformers to 0.6.0.4 - - - - - b4730b62 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Fix tests T13253 imports MonadTrans, which acquired a quantified constraint in transformers-0.6, thus increase in allocations Metric Increase: T13253 - - - - - 0be75261 by Simon Peyton Jones at 2022-12-21T06:18:32-05:00 Abstract over the right free vars Fix #22459, in two ways: (1) Make the Specialiser not create a bogus specialisation if it is presented by strangely polymorphic dictionary. See Note [Weird special case in SpecDict] in GHC.Core.Opt.Specialise (2) Be more careful in abstractFloats See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. So (2) stops creating the excessively polymorphic dictionary in abstractFloats, while (1) stops crashing if some other pass should nevertheless create a weirdly polymorphic dictionary. - - - - - df7bc6b3 by Ying-Ruei Liang (TheKK) at 2022-12-21T14:31:54-05:00 rts: explicitly store return value of ccall checkClosure to prevent type error (#22617) - - - - - e193e537 by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. - - - - - 3d55d8ab by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 - - - - - ceb2e9b9 by Ben Gamari at 2022-12-21T15:26:08-05:00 configure: Bump version to 9.6 - - - - - fb4d36c4 by Ben Gamari at 2022-12-21T15:27:49-05:00 base: Bump version to 4.18 Requires various submodule bumps. - - - - - 93ee7e90 by Ben Gamari at 2022-12-21T15:27:49-05:00 ghc-boot: Fix bootstrapping - - - - - fc3a2232 by Ben Gamari at 2022-12-22T13:45:06-05:00 Bump GHC version to 9.7 - - - - - 914f7fe3 by Andreas Klebinger at 2022-12-22T23:36:10-05:00 Don't consider large byte arrays/compact regions pinned. Workaround for #22255 which showed how treating large/compact regions as pinned could cause segfaults. - - - - - 32b32d7f by Matthew Pickering at 2022-12-22T23:36:46-05:00 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 - - - - - b3ddf803 by Ben Gamari at 2022-12-22T23:37:23-05:00 rts: Drop paths from configure from cabal file A long time ago we would rely on substitutions from the configure script to inject paths of the include and library directories of libffi and libdw. However, now these are instead handled inside Hadrian when calling Cabal's `configure` (see the uses of `cabalExtraDirs` in Hadrian's `Settings.Packages.packageArgs`). While the occurrences in the cabal file were redundant, they did no harm. However, since b5c714545abc5f75a1ffdcc39b4bfdc7cd5e64b4 they have no longer been interpolated. @mpickering noticed the suspicious uninterpolated occurrence of `@FFIIncludeDir@` in #22595, prompting this commit to finally remove them. - - - - - b2c7523d by Ben Gamari at 2022-12-22T23:37:59-05:00 Bump libffi-tarballs submodule We will now use libffi-3.4.4. - - - - - 3699a554 by Alan Zimmerman at 2022-12-22T23:38:35-05:00 EPA: Make EOF position part of AnnsModule Closes #20951 Closes #19697 - - - - - 99757ce8 by Sylvain Henry at 2022-12-22T23:39:13-05:00 JS: fix support for -outputdir (#22641) The `-outputdir` option wasn't correctly handled with the JS backend because the same code path was used to handle both objects produced by the JS backend and foreign .js files. Now we clearly distinguish the two in the pipeline, fixing the bug. - - - - - 02ed7d78 by Simon Peyton Jones at 2022-12-22T23:39:49-05:00 Refactor mkRuntimeError This patch fixes #22634. Because we don't have TYPE/CONSTRAINT polymorphism, we need two error functions rather than one. I took the opportunity to rname runtimeError to impossibleError, to line up with mkImpossibleExpr, and avoid confusion with the genuine runtime-error-constructing functions. - - - - - 35267f07 by Ben Gamari at 2022-12-22T23:40:32-05:00 base: Fix event manager shutdown race on non-Linux platforms During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this. - - - - - 317f45c1 by Simon Peyton Jones at 2022-12-22T23:41:07-05:00 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 - - - - - 14b2e3d3 by Ben Gamari at 2022-12-22T23:41:42-05:00 rts/m32: Fix sanity checking Previously we would attempt to clear pages which were marked as read-only. Fix this. - - - - - 16a1bcd1 by Matthew Pickering at 2022-12-23T09:15:24+00:00 ci: Move wasm pipelines into nightly rather than master See #22664 for the changes which need to be made to bring one of these back to the validate pipeline. - - - - - 18d2acd2 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. - - - - - 11241efa by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix segment list races - - - - - 602455c9 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. - - - - - 9d63b160 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. - - - - - 26837523 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that mutable fields have acquire barrier - - - - - 8093264a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. - - - - - 387d4fcc by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make segment state updates atomic - - - - - 543cae00 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. - - - - - c9936718 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. - - - - - 0cd31f7d by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. - - - - - d3fe110a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. - - - - - ab6cf893 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. - - - - - 36c9f23c by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). - - - - - aebef31c by doyougnu at 2022-12-23T19:10:09-05:00 add GHC.Utils.Binary.foldGet' and use for Iface A minor optimization to remove lazy IO and a lazy accumulator strictify foldGet' IFace.Binary: use strict foldGet' remove superfluous bang - - - - - 5eb357d9 by Ben Gamari at 2022-12-24T00:41:05-05:00 compiler: Ensure that GHC toolchain is first in search path As noted in #22561, it is important that GHC's toolchain look first for its own headers and libraries to ensure that the system's are not found instead. If this happens things can break in surprising ways (e.g. see #22561). - - - - - cbaebfb9 by Matthew Pickering at 2022-12-24T00:41:40-05:00 head.hackage: Use slow-validate bindist for linting jobs This enables the SLOW_VALIDATE env var for the linting head.hackage jobs, namely the jobs enabled manually, by the label or on the nightly build now use the deb10-numa-slow-validate bindist which has assertions enabled. See #22623 for a ticket which was found by using this configuration already! The head.hackage jobs triggered by upstream CI are now thusly: hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. Runs head.hackage with -dlint and a slow-validate bindist hackage-label-lint: Trigged on MRs with "user-facing" label, runs the slow-validate head.hackage build with -dlint. nightly-hackage-lint: Runs automatically on nightly pipelines with slow-validate + dlint config. nightly-hackage-perf: Runs automaticaly on nightly pipelines with release build and eventlogging enabled. release-hackage-lint: Runs automatically on release pipelines with -dlint on a release bindist. - - - - - f4850f36 by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Don't run abi-test-nightly on release jobs The test is not configured to get the correct dependencies for the release pipelines (and indeed stops the release pipeline being run at all) - - - - - c264b06b by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Run head.hackage jobs on upstream-testing branch rather than master This change allows less priviledged users to trigger head.hackage jobs because less permissions are needed to trigger jobs on the upstream-testing branch, which is not protected. There is a CI job which updates upstream-testing each hour to the state of the master branch so it should always be relatively up-to-date. - - - - - 63b97430 by Ben Gamari at 2022-12-24T00:42:16-05:00 llvmGen: Fix relaxed ordering Previously I used LLVM's `unordered` ordering for the C11 `relaxed` ordering. However, this is wrong and should rather use the LLVM `monotonic` ordering. Fixes #22640 - - - - - f42ba88f by Ben Gamari at 2022-12-24T00:42:16-05:00 gitlab-ci: Introduce aarch64-linux-llvm job This nightly job will ensure that we don't break the LLVM backend on AArch64/Linux by bootstrapping GHC. This would have caught #22640. - - - - - 6d62f6bf by Matthew Pickering at 2022-12-24T00:42:51-05:00 Store RdrName rather than OccName in Holes In #20472 it was pointed out that you couldn't defer out of scope but the implementation collapsed a RdrName into an OccName to stuff it into a Hole. This leads to the error message for a deferred qualified name dropping the qualification which affects the quality of the error message. This commit adds a bit more structure to a hole, so a hole can replace a RdrName without losing information about what that RdrName was. This is important when printing error messages. I also added a test which checks the Template Haskell deferral of out of scope qualified names works properly. Fixes #22130 - - - - - 3c3060e4 by Richard Eisenberg at 2022-12-24T17:34:19+00:00 Drop support for kind constraints. This implements proposal 547 and closes ticket #22298. See the proposal and ticket for motivation. Compiler perf improves a bit Metrics: compile_time/bytes allocated ------------------------------------- CoOpt_Singletons(normal) -2.4% GOOD T12545(normal) +1.0% T13035(normal) -13.5% GOOD T18478(normal) +0.9% T9872d(normal) -2.2% GOOD geo. mean -0.2% minimum -13.5% maximum +1.0% Metric Decrease: CoOpt_Singletons T13035 T9872d - - - - - 6d7d4393 by Ben Gamari at 2022-12-24T21:09:56-05:00 hadrian: Ensure that linker scripts are used when merging objects In #22527 @rui314 inadvertantly pointed out a glaring bug in Hadrian's implementation of the object merging rules: unlike the old `make` build system we utterly failed to pass the needed linker scripts. Fix this. - - - - - a5bd0eb8 by Andrew Lelechenko at 2022-12-24T21:10:34-05:00 Document infelicities of instance Ord Double and workarounds - - - - - 62b9a7b2 by Zubin Duggal at 2023-01-03T12:22:11+00:00 Force the Docs structure to prevent leaks in GHCi with -haddock without -fwrite-interface Involves adding many new NFData instances. Without forcing Docs, references to the TcGblEnv for each module are retained by the Docs structure. Usually these are forced when the ModIface is serialised but not when we aren't writing the interface. - - - - - 21bedd84 by Facundo Domínguez at 2023-01-03T23:27:30-05:00 Explain the auxiliary functions of permutations - - - - - 32255d05 by Matthew Pickering at 2023-01-04T11:58:42+00:00 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. - - - - - e640940c by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Fix computation of tables_next_to_code for outOfTreeCompiler This copy-pasto was introduced in de5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b - - - - - 15bee123 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 - - - - - fec6638e by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. - - - - - 3dc05726 by Matthew Pickering at 2023-01-04T11:58:42+00:00 check-exact: Fix build with -Werror - - - - - 53a6ae7a by Matthew Pickering at 2023-01-04T11:58:42+00:00 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 - - - - - 32e264c1 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 - - - - - be9dd9b0 by Matthew Pickering at 2023-01-04T11:58:42+00:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 - - - - - 00dc5106 by Matthew Pickering at 2023-01-04T14:32:45-05:00 sphinx: Use modern syntax for extlinks This fixes the following build error: ``` Command line: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build -b man -d /private/tmp/extra-dir-55768274273/.doctrees-man -n -w /private/tmp/extra-dir-55768274273/.log docs/users_guide /private/tmp/extra-dir-55768274273 ===> Command failed with error code: 2 Exception occurred: File "/opt/homebrew/Cellar/sphinx-doc/6.0.0/libexec/lib/python3.11/site-packages/sphinx/ext/extlinks.py", line 101, in role title = caption % part ~~~~~~~~^~~~~~ TypeError: not all arguments converted during string formatting ``` I tested on Sphinx-5.1.1 and Sphinx-6.0.0 Thanks for sterni for providing instructions about how to test using sphinx-6.0.0. Fixes #22690 - - - - - 541aedcd by Krzysztof Gogolewski at 2023-01-05T10:48:34-05:00 Misc cleanup - Remove unused uniques and hs-boot declarations - Fix types of seq and unsafeCoerce# - Remove FastString/String roundtrip in JS - Use TTG to enforce totality - Remove enumeration in Heap/Inspect; the 'otherwise' clause serves the primitive types well. - - - - - 22bb8998 by Alan Zimmerman at 2023-01-05T10:49:09-05:00 EPA: Do not collect comments from end of file In Parser.y semis1 production triggers for the virtual semi at the end of the file. This is detected by it being zero length. In this case, do not extend the span being used to gather comments, so any final comments are allocated at the module level instead. - - - - - 9e077999 by Vladislav Zavialov at 2023-01-05T23:01:55-05:00 HsToken in TypeArg (#19623) Updates the haddock submodule. - - - - - b2a2db04 by Matthew Pickering at 2023-01-05T23:02:30-05:00 Revert "configure: Drop uses of AC_PROG_CC_C99" This reverts commit 7c6de18dd3151ead954c210336728e8686c91de6. Centos7 using a very old version of the toolchain (autotools-2.69) where the behaviour of these macros has not yet changed. I am reverting this without haste as it is blocking the 9.6 branch. Fixes #22704 - - - - - 28f8c0eb by Luite Stegeman at 2023-01-06T18:16:24+09:00 Add support for sized literals in the bytecode interpreter. The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945 - - - - - ac39e8e9 by Matthew Pickering at 2023-01-06T13:47:00-05:00 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 - - - - - c306d939 by Matthew Pickering at 2023-01-06T22:08:53-05:00 ci: Upgrade darwin, windows and freebsd CI to use GHC-9.4.3 Fixes #22599 - - - - - 0db496ff by Matthew Pickering at 2023-01-06T22:08:53-05:00 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 2459c358 by Ben Gamari at 2023-01-06T22:09:29-05:00 rts: MUT_VAR is not a StgMutArrPtrs There was previously a comment claiming that the MUT_VAR closure type had the layout of StgMutArrPtrs. - - - - - 6206cb92 by Simon Peyton Jones at 2023-01-07T12:14:40-05:00 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 - - - - - a960ca81 by Matthew Pickering at 2023-01-07T12:15:15-05:00 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s - - - - - 73484710 by Matthew Pickering at 2023-01-07T12:15:15-05:00 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. - - - - - 8c0ea25f by Matthew Pickering at 2023-01-07T12:15:15-05:00 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes - - - - - 365b3045 by Matthew Pickering at 2023-01-09T02:36:20-05:00 Disable split sections on aarch64-deb10 build See #22722 Failure on this job: https://gitlab.haskell.org/ghc/ghc/-/jobs/1287852 ``` Unexpected failures: /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T10828.run T10828 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T13123.run T13123 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T20590.run T20590 [exit code non-0] (ext-interp) Appending 232 stats to file: /builds/ghc/ghc/performance-metrics.tsv ``` ``` Compile failed (exit code 1) errors were: data family D_0 a_1 :: * -> * data instance D_0 GHC.Types.Int GHC.Types.Bool :: * where DInt_2 :: D_0 GHC.Types.Int GHC.Types.Bool data E_3 where MkE_4 :: a_5 -> E_3 data Foo_6 a_7 b_8 where MkFoo_9, MkFoo'_10 :: a_11 -> Foo_6 a_11 b_12 newtype Bar_13 :: * -> GHC.Types.Bool -> * where MkBar_14 :: a_15 -> Bar_13 a_15 b_16 data T10828.T (a_0 :: *) where T10828.MkT :: forall (a_1 :: *) . a_1 -> a_1 -> T10828.T a_1 T10828.MkC :: forall (a_2 :: *) (b_3 :: *) . (GHC.Types.~) a_2 GHC.Types.Int => {T10828.foo :: a_2, T10828.bar :: b_3} -> T10828.T GHC.Types.Int T10828.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: (do TyConI dec <- runQ $ reify (mkName "T") runIO $ putStrLn (pprint dec) >> hFlush stdout d <- runQ $ [d| data T' a :: Type where MkT' :: a -> a -> T' a MkC' :: forall a b. (a ~ Int) => {foo :: a, bar :: b} -> T' Int |] runIO $ putStrLn (pprint d) >> hFlush stdout ....) *** unexpected failure for T10828(ext-interp) =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] Compile failed (exit code 1) errors were: T13123.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data GADT where MkGADT :: forall k proxy (a :: k). proxy a -> GADT |]) *** unexpected failure for T13123(ext-interp) =====> 7100 of 9215 [0, 2, 0] =====> 7100 of 9215 [0, 2, 0] =====> 7200 of 9215 [0, 2, 0] Compile failed (exit code 1) errors were: T20590.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data T where MkT :: forall a. a -> T |]) *** unexpected failure for T20590(ext-interp) ``` Looks fairly worrying to me. - - - - - 965a2735 by Alan Zimmerman at 2023-01-09T02:36:20-05:00 EPA: exact print HsDocTy To match ghc-exactprint https://github.com/alanz/ghc-exactprint/pull/121 - - - - - 5d65773e by John Ericson at 2023-01-09T20:39:27-05:00 Remove RTS hack for configuring See the brand new Note [Undefined symbols in the RTS] for additional details. - - - - - e3fff751 by Sebastian Graf at 2023-01-09T20:40:02-05:00 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite - - - - - d53f6f4d by Oleg Grenrus at 2023-01-09T21:11:02-05:00 Add safe list indexing operator: !? With Joachim's amendments. Implements https://github.com/haskell/core-libraries-committee/issues/110 - - - - - cfaf1ad7 by Nicolas Trangez at 2023-01-09T21:11:03-05:00 rts, tests: limit thread name length to 15 bytes On Linux, `pthread_setname_np` (or rather, the kernel) only allows for thread names up to 16 bytes, including the terminating null byte. This commit adds a note pointing this out in `createOSThread`, and fixes up two instances where a thread name of more than 15 characters long was used (in the RTS, and in a test-case). Fixes: #22366 Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/22366 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22366#note_460796 - - - - - 64286132 by Matthew Pickering at 2023-01-09T21:11:03-05:00 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 - - - - - 4724e8d1 by Matthew Pickering at 2023-01-09T21:11:04-05:00 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 - - - - - 2e926b88 by Georgi Lyubenov at 2023-01-09T21:11:07-05:00 Fix outdated link to Happy section on sequences - - - - - 146a1458 by Matthew Pickering at 2023-01-09T21:11:07-05:00 Revert "NCG(x86): Compile add+shift as lea if possible." This reverts commit 20457d775885d6c3df020d204da9a7acfb3c2e5a. See #22666 and #21777 - - - - - 6e6adbe3 by Jade Lovelace at 2023-01-11T00:55:30-05:00 Fix tcPluginRewrite example - - - - - faa57138 by Jade Lovelace at 2023-01-11T00:55:31-05:00 fix missing haddock pipe - - - - - 0470ea7c by Florian Weimer at 2023-01-11T00:56:10-05:00 m4/fp_leading_underscore.m4: Avoid implicit exit function declaration And switch to a new-style function definition. Fixes build issues with compilers that do not accept implicit function declarations. - - - - - b2857df4 by HaskellMouse at 2023-01-11T00:56:52-05:00 Added a new warning about compatibility with RequiredTypeArguments This commit introduces a new warning that indicates code incompatible with future extension: RequiredTypeArguments. Enabling this extension may break some code and the warning will help to make it compatible in advance. - - - - - 5f17e21a by Ben Gamari at 2023-01-11T00:57:27-05:00 testsuite: Drop testheapalloced.c As noted in #22414, this file (which appears to be a benchmark for characterising the one-step allocator's MBlock cache) is currently unreferenced. Remove it. Closes #22414. - - - - - bc125775 by Vladislav Zavialov at 2023-01-11T00:58:03-05:00 Introduce the TypeAbstractions language flag GHC Proposals #448 "Modern scoped type variables" and #425 "Invisible binders in type declarations" introduce a new language extension flag: TypeAbstractions. Part of the functionality guarded by this flag has already been implemented, namely type abstractions in constructor patterns, but it was guarded by a combination of TypeApplications and ScopedTypeVariables instead of a dedicated language extension flag. This patch does the following: * introduces a new language extension flag TypeAbstractions * requires TypeAbstractions for @a-syntax in constructor patterns instead of TypeApplications and ScopedTypeVariables * creates a User's Guide page for TypeAbstractions and moves the "Type Applications in Patterns" section there To avoid a breaking change, the new flag is implied by ScopedTypeVariables and is retroactively added to GHC2021. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 083f7015 by Krzysztof Gogolewski at 2023-01-11T00:58:38-05:00 Misc cleanup - Remove unused mkWildEvBinder - Use typeTypeOrConstraint - more symmetric and asserts that that the type is Type or Constraint - Fix escape sequences in Python; they raise a deprecation warning with -Wdefault - - - - - aed1974e by Richard Eisenberg at 2023-01-11T08:30:42+00:00 Refactor the treatment of loopy superclass dicts This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows. - - - - - 300bcc15 by HaskellMouse at 2023-01-11T13:43:36-05:00 Parse qualified terms in type signatures This commit allows qualified terms in type signatures to pass the parser and to be cathced by renamer with more informative error message. Adds a few tests. Fixes #21605 - - - - - 964284fc by Simon Peyton Jones at 2023-01-11T13:44:12-05:00 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. - - - - - f7ceafc9 by Krzysztof Gogolewski at 2023-01-11T22:36:59-05:00 Add 'docWithStyle' to improve codegen This new combinator docWithStyle :: IsOutput doc => doc -> (PprStyle -> SDoc) -> doc let us remove the need for code to be polymorphic in HDoc when not used in code style. Metric Decrease: ManyConstructors T13035 T1969 - - - - - b3be0d18 by Simon Peyton Jones at 2023-01-11T22:37:35-05:00 Fix finaliseArgBoxities for OPAQUE function We never do worker wrapper for OPAQUE functions, so we must zap the unboxing info during strictness analysis. This patch fixes #22502 - - - - - db11f358 by Ben Gamari at 2023-01-12T07:49:04-05:00 Revert "rts: Drop racy assertion" The logic here was inverted. Reverting the commit to avoid confusion when examining the commit history. This reverts commit b3eacd64fb36724ed6c5d2d24a81211a161abef1. - - - - - 3242139f by Ben Gamari at 2023-01-12T07:49:04-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 9ffd5d57 by Ben Gamari at 2023-01-12T07:49:41-05:00 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. - - - - - 905d0b6e by Sebastian Graf at 2023-01-12T15:51:47-05:00 Fix contification with stable unfoldings (#22428) Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with a `JoinArity` that reflects the number of join point binders around the body for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by `occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`. I adjusted `Note [Join points and unfoldings/rules]` and `Note [Adjusting right-hand sides]` to account for the new machinery. I also wrote a new `Note [Join arity prediction based on joinRhsArity]` and refer to it when we combine `TailUsageDetails` for a recursive RHS. I also renamed * `occAnalLam` to `occAnalLamTail` * `adjustRhsUsage` to `adjustTailUsage` * a few other less important functions and properly documented the that each call of `occAnalLamTail` must pair up with `adjustTailUsage`. I removed `Note [Unfoldings and join points]` because it was redundant with `Note [Occurrences in stable unfoldings]`. While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed `NodeDetails` called `SimpleNodeDetails`. Fixes #22428. The refactoring seems to have quite beneficial effect on ghc/alloc performance: ``` CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2% T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6% T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2% T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0% T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5% T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6% T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9% T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD geo. mean -0.6% minimum -2.4% maximum -0.0% ``` Metric Decrease: CoOpt_Read T10421 T12150 T12425 T13056 T18698a T18698b T21839c T21839r T9961 - - - - - a1491c87 by Andreas Klebinger at 2023-01-12T15:52:23-05:00 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. - - - - - 8acfe930 by Cheng Shao at 2023-01-12T15:53:00-05:00 Change MSYSTEM to CLANG64 uniformly - - - - - 73bc162b by M Farkas-Dyck at 2023-01-12T15:53:42-05:00 Make `GHC.Tc.Errors.Reporter` take `NonEmpty ErrorItem` rather than `[ErrorItem]`, which lets us drop some panics. Also use the `BasicMismatch` constructor rather than `mkBasicMismatchMsg`, which lets us drop the "-Wno-incomplete-record-updates" flag. - - - - - 1b812b69 by Oleg Grenrus at 2023-01-12T15:54:21-05:00 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general - - - - - c79b2b65 by Matthew Pickering at 2023-01-12T15:54:58-05:00 Don't run hadrian-multi on fast-ci label Fixes #22667 - - - - - 9a3d6add by Andrew Lelechenko at 2023-01-13T00:46:36-05:00 Bump submodule bytestring to 0.11.4.0 Metric Decrease: T21839c T21839r - - - - - df33c13c by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Bump Darwin bootstrap toolchain This updates the bootstrap compiler on Darwin from 8.10.7 to 9.2.5, ensuring that we have the fix for #21964. - - - - - 756a66ec by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Pass -w to cabal update Due to cabal#8447, cabal-install 3.8.1.0 requires a compiler to run `cabal update`. - - - - - 1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump hsc2hs submodule - - - - - d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump process submodule - - - - - 84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: Bump DOCKER_REV - - - - - d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: enable xz parallel compression for x64 jobs - - - - - d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: use in-image emsdk for js jobs - - - - - 93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings - Add a ghc environment including prebuilt dependencies to the nix-shell. Get rid of the ad hoc cabal cache and all dependencies are now downloaded from the nixos binary cache. - Make gen_ci.hs a cabal package with HLS integration, to make future hacking of gen_ci.hs easier. - Fix some ghc/hlint warnings after I got HLS to work. - For the lint-ci-config job, do a shallow clone to save a few minutes of unnecessary git checkout time. - - - - - 8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: source the toolchain env file in wasm jobs - - - - - 87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: add wasm ci jobs via gen_ci.hs - There is one regular wasm job run in validate pipelines - Additionally, int-native/unreg wasm jobs run in nightly/release pipelines Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml. - - - - - b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00 wasm ci: Remove wasm release jobs This removes the wasm release jobs, as we do not yet intend to distribute these binaries. - - - - - 496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. - - - - - 7a9a1042 by Andreas Klebinger at 2023-01-16T20:48:19-05:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 33b58f77 by sheaf at 2023-01-16T20:48:57-05:00 Hadrian: generalise &%> to avoid warnings This patch introduces a more general version of &%> that works with general traversable shapes, instead of lists. This allows us to pass along the information that the length of the list of filepaths passed to the function exactly matches the length of the input list of filepath patterns, avoiding pattern match warnings. Fixes #22430 - - - - - 8c7a991c by Andreas Klebinger at 2023-01-16T20:49:34-05:00 Add regression test for #22611. A case were a function used to fail to specialize, but now does. - - - - - 6abea760 by Andreas Klebinger at 2023-01-16T20:50:10-05:00 Mark maximumBy/minimumBy as INLINE. The RHS was too large to inline which often prevented the overhead of the Maybe from being optimized away. By marking it as INLINE we can eliminate the overhead of both the maybe and are able to unpack the accumulator when possible. Fixes #22609 - - - - - 99d151bb by Matthew Pickering at 2023-01-16T20:50:50-05:00 ci: Bump CACHE_REV so that ghc-9.6 branch and HEAD have different caches Having the same CACHE_REV on both branches leads to issues where the darwin toolchain is different on ghc-9.6 and HEAD which leads to long darwin build times. In general we should ensure that each branch has a different CACHE_REV. - - - - - 6a5845fb by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in source-tarball job This fixes errors of the form: ``` fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc inferred 9.7.20230113 checking for GHC Git commit id... fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc ``` - - - - - 4afb952c by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't build aarch64-deb10-llvm job on release pipelines Closes #22721 - - - - - 8039feb9 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in test-bootstrap job - - - - - 0b358d0c by Matthew Pickering at 2023-01-16T20:51:25-05:00 rel_eng: Add release engineering scripts into ghc tree It is better to keep these scripts in the tree as they depend on the CI configuration and so on. By keeping them in tree we can keep them up-to-date as the CI config changes and also makes it easier to backport changes to the release script between release branches in future. The final motivation is that it makes generating GHCUp metadata possible. - - - - - 28cb2ed0 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't use complicated image or clone in not-interruptible job This job exists only for the meta-reason of not allowing nightly pipelines to be cancelled. It was taking two minutes to run as in order to run "true" we would also clone the whole GHC repo. - - - - - eeea59bb by Matthew Pickering at 2023-01-16T20:51:26-05:00 Add scripts to generate ghcup metadata on nightly and release pipelines 1. A python script in .gitlab/rel_eng/mk-ghcup-metadata which generates suitable metadata for consumption by GHCUp for the relevant pipelines. - The script generates the metadata just as the ghcup maintainers want, without taking into account platform/library combinations. It is updated manually when the mapping changes. - The script downloads the bindists which ghcup wants to distribute, calculates the hash and generates the yaml in the correct structure. - The script is documented in the .gitlab/rel_eng/mk-ghcup-metadata/README.mk file 1a. The script requires us to understand the mapping from platform -> job. To choose the preferred bindist for each platform the .gitlab/gen_ci.hs script is modified to allow outputting a metadata file which answers the question about which job produces the bindist which we want to distribute to users for a specific platform. 2. Pipelines to run on nightly and release jobs to generate metadata - ghcup-metadata-nightly: Generates metadata which points directly to artifacts in the nightly job. - ghcup-metadata-release: Generates metadata suitable for inclusion directly in ghcup by pointing to the downloads folder where the bindist will be uploaded to. 2a. Trigger jobs which test the generated metadata in the downstream `ghccup-ci` repo. See that repo for documentation about what is tested and how but essentially we test in a variety of clean images that ghcup can download and install the bindists we say exist in our metadata. - - - - - 97bd4d8c by Andrew Lelechenko at 2023-01-16T20:52:04-05:00 Bump submodule parsec to 3.1.16.1 - - - - - 97ac8230 by Alan Zimmerman at 2023-01-16T20:52:39-05:00 EPA: Add annotation for 'type' in DataDecl Closes #22765 - - - - - dbbab95d by Ben Gamari at 2023-01-17T06:36:06-05:00 compiler: Small optimisation of assertM In #22739 @AndreasK noticed that assertM performed the action to compute the asserted predicate regardless of whether DEBUG is enabled. This is inconsistent with the other assertion operations and general convention. Fix this. Closes #22739. - - - - - fc02f3bb by Viktor Dukhovni at 2023-01-17T06:36:47-05:00 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 - - - - - 003b6d44 by Simon Peyton Jones at 2023-01-17T16:33:05-05:00 Document the semantics of pattern bindings a bit better This MR is in response to the discussion on #22719 - - - - - f4d50baf by Vladislav Zavialov at 2023-01-17T16:33:41-05:00 Hadrian: fix warnings (#22783) This change fixes the following warnings when building Hadrian: src/Hadrian/Expression.hs:38:10: warning: [-Wredundant-constraints] src/Hadrian/Expression.hs:84:13: warning: [-Wtype-equality-requires-operators] src/Hadrian/Expression.hs:84:21: warning: [-Wtype-equality-requires-operators] src/Hadrian/Haskell/Cabal/Parse.hs:67:1: warning: [-Wunused-imports] - - - - - 06036d93 by Sylvain Henry at 2023-01-18T01:55:10-05:00 testsuite: req_smp --> req_target_smp, req_ghc_smp See #22630 and !9552 This commit: - splits req_smp into req_target_smp and req_ghc_smp - changes the testsuite driver to calculate req_ghc_smp - changes a handful of tests to use req_target_smp instead of req_smp - changes a handful of tests to use req_host_smp when needed The problem: - the problem this solves is the ambiguity surrounding req_smp - on master req_smp was used to express the constraint that the program being compiled supports smp _and_ that the host RTS (i.e., the RTS used to compile the program) supported smp. Normally that is fine, but in cross compilation this is not always the case as was discovered in #22630. The solution: - Differentiate the two constraints: - use req_target_smp to say the RTS the compiled program is linked with (and the platform) supports smp - use req_host_smp to say the RTS the host is linked with supports smp WIP: fix req_smp (target vs ghc) add flag to separate bootstrapper split req_smp -> req_target_smp and req_ghc_smp update tests smp flags cleanup and add some docstrings only set ghc_with_smp to bootstrapper on S1 or CC Only set ghc_with_smp to bootstrapperWithSMP of when testing stage 1 and cross compiling test the RTS in config/ghc not hadrian re-add ghc_with_smp fix and align req names fix T11760 to use req_host_smp test the rts directly, avoid python 3.5 limitation test the compiler in a try block align out of tree and in tree withSMP flags mark failing tests as host req smp testsuite: req_host_smp --> req_ghc_smp Fix ghc vs host, fix ghc_with_smp leftover - - - - - ee9b78aa by Krzysztof Gogolewski at 2023-01-18T01:55:45-05:00 Use -Wdefault when running Python testdriver (#22727) - - - - - e9c0537c by Vladislav Zavialov at 2023-01-18T01:56:22-05:00 Enable -Wstar-is-type by default (#22759) Following the plan in GHC Proposal #143 "Remove the * kind syntax", which states: In the next release (or 3 years in), enable -fwarn-star-is-type by default. The "next release" happens to be 9.6.1 I also moved the T21583 test case from should_fail to should_compile, because the only reason it was failing was -Werror=compat in our test suite configuration. - - - - - 4efee43d by Ryan Scott at 2023-01-18T01:56:59-05:00 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. - - - - - f891a442 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. - - - - - b13c6ea5 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. - - - - - c45a5fff by Cheng Shao at 2023-01-18T07:28:37-05:00 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. - - - - - b4c14c4b by Luite Stegeman at 2023-01-18T14:21:42-05:00 Add PrimCallConv support to GHCi This adds support for calling Cmm code from bytecode using the native calling convention, allowing modules that use `foreign import prim` to be loaded and debugged in GHCi. This patch introduces a new `PRIMCALL` bytecode instruction and a helper stack frame `stg_primcall`. The code is based on the existing functionality for dealing with unboxed tuples in bytecode, which has been generalised to handle arbitrary calls. Fixes #22051 - - - - - d0a63ef8 by Adam Gundry at 2023-01-18T14:22:26-05:00 Refactor warning flag parsing to add missing flags This adds `-Werror=<group>` and `-fwarn-<group>` flags for warning groups as well as individual warnings. Previously these were defined on an ad hoc basis so for example we had `-Werror=compat` but not `-Werror=unused-binds`, whereas we had `-fwarn-unused-binds` but not `-fwarn-compat`. Fixes #22182. - - - - - 7ed1b8ef by Adam Gundry at 2023-01-18T14:22:26-05:00 Minor corrections to comments - - - - - 5389681e by Adam Gundry at 2023-01-18T14:22:26-05:00 Revise warnings documentation in user's guide - - - - - ab0d5cda by Adam Gundry at 2023-01-18T14:22:26-05:00 Move documentation of deferred type error flags out of warnings section - - - - - eb5a6b91 by John Ericson at 2023-01-18T22:24:10-05:00 Give the RTS it's own configure script Currently it doesn't do much anything, we are just trying to introduce it without breaking the build. Later, we will move functionality from the top-level configure script over to it. We need to bump Cabal for https://github.com/haskell/cabal/pull/8649; to facilitate and existing hack of skipping some configure checks for the RTS we now need to skip just *part* not *all* of the "post configure" hook, as running the configure script (which we definitely want to do) is also implemented as part of the "post configure" hook. But doing this requires exposing functionality that wasn't exposed before. - - - - - 32ab07bf by Andrew Lelechenko at 2023-01-18T22:24:51-05:00 ghc package does not have to depend on terminfo - - - - - 981ff7c4 by Andrew Lelechenko at 2023-01-18T22:24:51-05:00 ghc-pkg does not have to depend on terminfo - - - - - f058e367 by Ben Gamari at 2023-01-18T22:25:27-05:00 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. - - - - - 154889db by Ryan Scott at 2023-01-18T22:26:03-05:00 Add regression test for #22151 Issue #22151 was coincidentally fixed in commit aed1974e92366ab8e117734f308505684f70cddf (`Refactor the treatment of loopy superclass dicts`). This adds a regression test to ensure that the issue remains fixed. Fixes #22151. - - - - - 14b5982a by Andrei Borzenkov at 2023-01-18T22:26:43-05:00 Fix printing of promoted MkSolo datacon (#22785) Problem: In 2463df2f, the Solo data constructor was renamed to MkSolo, and Solo was turned into a pattern synonym for backwards compatibility. Since pattern synonyms can not be promoted, the old code that pretty-printed promoted single-element tuples started producing ill-typed code: t :: Proxy ('Solo Int) This fails with "Pattern synonym ‘Solo’ used as a type" The solution is to track the distinction between type constructors and data constructors more carefully when printing single-element tuples. - - - - - 1fe806d3 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add hi_core flavour transformer The hi_core flavour transformer enables -fwrite-if-simplified-core for stage1 libraries, which emit core into interface files to make it possible to restart code generation. Building boot libs with it makes it easier to use GHC API to prototype experimental backends that needs core/stg at link time. - - - - - 317cad26 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add missing docs for recently added flavour transformers - - - - - 658f4446 by Ben Gamari at 2023-01-23T04:49:23-05:00 gitlab-ci: Add Rocky8 jobs Addresses #22268. - - - - - a83ec778 by Vladislav Zavialov at 2023-01-23T04:49:58-05:00 Set "since: 9.8" for TypeAbstractions and -Wterm-variable-capture These flags did not make it into the 9.6 release series, so the "since" annotations must be corrected. - - - - - fec7c2ea by Alan Zimmerman at 2023-01-23T04:50:33-05:00 EPA: Add SourceText to HsOverLabel To be able to capture string literals with possible escape codes as labels. Close #22771 - - - - - 3efd1e99 by Ben Gamari at 2023-01-23T04:51:08-05:00 template-haskell: Bump version to 2.20.0.0 Updates `text` and `exceptions` submodules for bounds bumps. Addresses #22767. - - - - - 0900b584 by Cheng Shao at 2023-01-23T04:51:45-05:00 hadrian: disable alloca for in-tree GMP on wasm32 When building in-tree GMP for wasm32, disable its alloca usage, since it may potentially cause stack overflow (e.g. #22602). - - - - - db0f1bfd by Cheng Shao at 2023-01-23T04:52:21-05:00 Bump process submodule Includes a critical fix for wasm32, see https://github.com/haskell/process/pull/272 for details. Also changes the existing cross test to include process stuff and avoid future regression here. - - - - - 9222b167 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Fix subdir for windows bindist - - - - - 9a9bec57 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Remove viPostRemove field from generated metadata This has been removed from the downstream metadata. - - - - - 82884ce0 by Simon Peyton Jones at 2023-01-23T04:53:32-05:00 Fix #22742 runtimeRepLevity_maybe was panicing unnecessarily; and the error printing code made use of the case when it should return Nothing rather than panicing. For some bizarre reason perf/compiler/T21839r shows a 10% bump in runtime peak-megagbytes-used, on a single architecture (alpine). See !9753 for commentary, but I'm going to accept it. Metric Increase: T21839r - - - - - 2c6deb18 by Bryan Richter at 2023-01-23T14:12:22+02:00 codeowners: Add Ben, Matt, and Bryan to CI - - - - - eee3bf05 by Matthew Craven at 2023-01-23T21:46:41-05:00 Do not collect compile-time metrics for T21839r ...the testsuite doesn't handle this properly since it also collects run-time metrics. Compile-time metrics for this test are already tracked via T21839c. Metric Decrease: T21839r - - - - - 1d1dd3fb by Matthew Pickering at 2023-01-24T05:37:52-05:00 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 - - - - - 7bfb30f9 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 - - - - - 69500dd4 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 - - - - - 336b2b1c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 - - - - - 6469fea7 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 - - - - - 06cc0a95 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 - - - - - 4fe9eaff by Matthew Pickering at 2023-01-24T05:37:52-05:00 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 - - - - - ada29f5c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p - - - - - be701cc6 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. - - - - - 34d2d463 by Krzysztof Gogolewski at 2023-01-24T05:38:32-05:00 Fix Lint check for duplicate external names Lint was checking for duplicate external names by calling removeDups, which needs a comparison function that is passed to Data.List.sortBy. But the comparison was not a valid ordering - it returned LT if one of the names was not external. For example, the previous implementation won't find a duplicate in [M.x, y, M.x]. Instead, we filter out non-external names before looking for duplicates. - - - - - 1c050ed2 by Matthew Pickering at 2023-01-24T05:39:08-05:00 Add test for T22671 This was fixed by b13c6ea5 Closes #22671 - - - - - 05e6a2d9 by Tom Ellis at 2023-01-24T12:10:52-05:00 Clarify where `f` is defined - - - - - d151546e by Cheng Shao at 2023-01-24T12:11:29-05:00 CmmToC: fix CmmRegOff for 64-bit register on a 32-bit target We used to print the offset value to a platform word sized integer. This is incorrect when the offset is negative (e.g. output of cmm constant folding) and the register is 64-bit but on a 32-bit target, and may lead to incorrect runtime result (e.g. #22607). The fix is simple: just treat it as a proper MO_Add, with the correct width info inferred from the register itself. Metric Increase: T12707 T13379 T4801 T5321FD T5321Fun - - - - - e5383a29 by Wander Hillen at 2023-01-24T20:02:26-05:00 Allow waiting for timerfd to be interrupted during rts shutdown - - - - - 1957eda1 by Ryan Scott at 2023-01-24T20:03:01-05:00 Restore Compose's Read/Show behavior to match Read1/Show1 instances Fixes #22816. - - - - - 30972827 by Matthew Pickering at 2023-01-25T03:54:14-05:00 docs: Update INSTALL.md Removes references to make. Fixes #22480 - - - - - bc038c3b by Cheng Shao at 2023-01-25T03:54:50-05:00 compiler: fix handling of MO_F_Neg in wasm NCG In the wasm NCG, we used to compile MO_F_Neg to 0.0-x. It was an oversight, there actually exists f32.neg/f64.neg opcodes in the wasm spec and those should be used instead! The old behavior almost works, expect when GHC compiles the -0.0 literal, which will incorrectly become 0.0. - - - - - e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. - - - - - 48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. - - - - - 288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. - - - - - 2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00 configure: support "windows" as an OS - - - - - 13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00 Fix in-scope set in specImports Nothing deep here; I had failed to bring some floated dictionary binders into scope. Exposed by -fspecialise-aggressively Fixes #22715. - - - - - b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00 ci: Disable HLint job due to excessive runtime The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91 Now the CI job will build the stage0 compiler before it generates the necessary RTS headers. We either need to: * Fix the linting rules so they take much less time * Revert the commit * Remove the linting of base from the hlint job * Remove the hlint job This is highest priority as it is affecting all CI pipelines. For now I am just disabling the job because there are many more pressing matters at hand. Ticket #22830 - - - - - 1bd32a35 by Sylvain Henry at 2023-01-26T12:34:21-05:00 Factorize hptModulesBelow Create and use moduleGraphModulesBelow in GHC.Unit.Module.Graph that doesn't need anything from the driver to be used. - - - - - 1262d3f8 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 - - - - - e27eb80c by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 - - - - - 3d004d5a by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 - - - - - f2a0fea0 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 - - - - - 5640cb1d by Sylvain Henry at 2023-01-26T12:35:36-05:00 Hadrian: fix doc generation Was missing dependencies on files generated by templates (e.g. ghc.cabal) - - - - - 3e827c3f by Richard Eisenberg at 2023-01-26T20:06:53-05:00 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. Close #22519. - - - - - b3ef5c89 by doyougnu at 2023-01-26T20:07:48-05:00 tryFillBuffer: strictify more speculative bangs - - - - - d0d7ba0f by Vladislav Zavialov at 2023-01-26T20:08:25-05:00 base: NoImplicitPrelude in Data.Void and Data.Kind This change removes an unnecessary dependency on Prelude from two modules in the base package. - - - - - fa1db923 by Matthew Pickering at 2023-01-26T20:09:00-05:00 ci: Add ubuntu18_04 nightly and release jobs This adds release jobs for ubuntu18_04 which uses glibc 2.27 which is older than the 2.28 which is used by Rocky8 bindists. Ticket #22268 - - - - - 807310a1 by Matthew Pickering at 2023-01-26T20:09:00-05:00 rel-eng: Add missing rocky8 bindist We intend to release rocky8 bindist so the fetching script needs to know about them. - - - - - c7116b10 by Ben Gamari at 2023-01-26T20:09:35-05:00 base: Make changelog proposal references more consistent Addresses #22773. - - - - - 6932cfc7 by Sylvain Henry at 2023-01-26T20:10:27-05:00 Fix spurious change from !9568 - - - - - e480fbc2 by Ben Gamari at 2023-01-27T05:01:24-05:00 rts: Use C11-compliant static assertion syntax Previously we used `static_assert` which is only available in C23. By contrast, C11 only provides `_Static_assert`. Fixes #22777 - - - - - 2648c09c by Andrei Borzenkov at 2023-01-27T05:02:07-05:00 Replace errors from badOrigBinding with new one (#22839) Problem: in 02279a9c the type-level [] syntax was changed from a built-in name to an alias for the GHC.Types.List constructor. badOrigBinding assumes that if a name is not built-in then it must have come from TH quotation, but this is not necessarily the case with []. The outdated assumption in badOrigBinding leads to incorrect error messages. This code: data [] Fails with "Cannot redefine a Name retrieved by a Template Haskell quote: []" Unfortunately, there is not enough information in RdrName to directly determine if the name was constructed via TH or by the parser, so this patch changes the error message instead. It unifies TcRnIllegalBindingOfBuiltIn and TcRnNameByTemplateHaskellQuote into a new error TcRnBindingOfExistingName and changes its wording to avoid guessing the origin of the name. - - - - - 545bf8cf by Matthew Pickering at 2023-01-27T14:58:53+00:00 Revert "base: NoImplicitPrelude in Data.Void and Data.Kind" Fixes CI errors of the form. ``` ===> Command failed with error code: 1 ghc: panic! (the 'impossible' happened) GHC version 9.7.20230127: lookupGlobal Failed to load interface for ‘GHC.Num.BigNat’ There are files missing in the ‘ghc-bignum’ package, try running 'ghc-pkg check'. Use -v (or `:set -v` in ghci) to see a list of the files searched for. Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Tc/Utils/Env.hs:154:32 in ghc:GHC.Tc.Utils.Env CallStack (from HasCallStack): panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` This reverts commit d0d7ba0fb053ebe7f919a5932066fbc776301ccd. The module now lacks a dependency on GHC.Num.BigNat which it implicitly depends on. It is causing all CI jobs to fail so we revert without haste whilst the patch can be fixed. Fixes #22848 - - - - - 638277ba by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Detect family instance orphans correctly We were treating a type-family instance as a non-orphan if there was a type constructor on its /right-hand side/ that was local. Boo! Utterly wrong. With this patch, we correctly check the /left-hand side/ instead! Fixes #22717 - - - - - 46a53bb2 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Report family instance orphans correctly This fixes the fact that we were not reporting orphan family instances at all. The fix here is easy, but touches a bit of code. I refactored the code to be much more similar to the way that class instances are done: - Add a fi_orphan field to FamInst, like the is_orphan field in ClsInst - Make newFamInst initialise this field, just like newClsInst - And make newFamInst report a warning for an orphan, just like newClsInst - I moved newFamInst from GHC.Tc.Instance.Family to GHC.Tc.Utils.Instantiate, just like newClsInst. - I added mkLocalFamInst to FamInstEnv, just like mkLocalClsInst in InstEnv - TcRnOrphanInstance and SuggestFixOrphanInstance are now parametrised over class instances vs type/data family instances. Fixes #19773 - - - - - faa300fb by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in STG This patch removes some orphan instances in the STG namespace by introducing the GHC.Stg.Lift.Types module, which allows various type family instances to be moved to GHC.Stg.Syntax, avoiding orphan instances. - - - - - 0f25a13b by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in the parser This moves Anno instances for PatBuilder from GHC.Parser.PostProcess to GHC.Parser.Types to avoid orphans. - - - - - 15750d33 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Accept an orphan declaration (sadly) This accepts the orphan type family instance type instance DsForeignHook = ... in GHC.HsToCore.Types. See Note [The Decoupling Abstract Data Hack] in GHC.Driver.Hooks - - - - - c9967d13 by Zubin Duggal at 2023-01-27T23:55:31-05:00 bindist configure: Fail if find not found (#22691) - - - - - ad8cfed4 by John Ericson at 2023-01-27T23:56:06-05:00 Put hadrian bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. - - - - - d0ddc01b by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Introduce threaded2_sanity way Incredibly, we previously did not have a single way which would test the threaded RTS with multiple capabilities and the sanity-checker enabled. - - - - - 38ad8351 by Ben Gamari at 2023-01-27T23:56:42-05:00 rts: Relax Messages assertion `doneWithMsgThrowTo` was previously too strict in asserting that the `Message` is locked. Specifically, it failed to consider that the `Message` may not be locked if we are deleting all threads during RTS shutdown. - - - - - a9fe81af by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Fix race in UnliftedTVar2 Previously UnliftedTVar2 would fail when run with multiple capabilities (and possibly even with one capability) as it would assume that `killThread#` would immediately kill the "increment" thread. Also, refactor the the executable to now succeed with no output and fails with an exit code. - - - - - 8519af60 by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Make listThreads more robust Previously it was sensitive to the labels of threads which it did not create (e.g. the IO manager event loop threads). Fix this. - - - - - 55a81995 by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix non-atomic mutation of enabled_capabilities - - - - - b5c75f1d by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix C++ compilation issues Make the RTS compilable with a C++ compiler by inserting necessary casts. - - - - - c261b62f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix typo "tracingAddCapabilities" was mis-named - - - - - 77fdbd3f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Drop long-dead fallback definitions for INFINITY & NAN These are no longer necessary since we now compile as C99. - - - - - 56c1bd98 by Ben Gamari at 2023-01-28T02:57:59-05:00 Revert "CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043)" This reverts commit 99aca26b652603bc62953157a48e419f737d352d. - - - - - b3a3534b by nineonine at 2023-01-28T02:57:59-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043. - - - - - 082b7d43 by Oleg Grenrus at 2023-01-28T02:58:38-05:00 Add Foldable1 Solo instance - - - - - 50b1e2e8 by Andrei Borzenkov at 2023-01-28T02:59:18-05:00 Convert diagnostics in GHC.Rename.Bind to proper TcRnMessage (#20115) I removed all occurrences of TcRnUnknownMessage in GHC.Rename.Bind module. Instead, these TcRnMessage messages were introduced: TcRnMultipleFixityDecls TcRnIllegalPatternSynonymDecl TcRnIllegalClassBiding TcRnOrphanCompletePragma TcRnEmptyCase TcRnNonStdGuards TcRnDuplicateSigDecl TcRnMisplacedSigDecl TcRnUnexpectedDefaultSig TcRnBindInBootFile TcRnDuplicateMinimalSig - - - - - 3330b819 by Matthew Pickering at 2023-01-28T02:59:54-05:00 hadrian: Fix library-dirs, dynamic-library-dirs and static-library-dirs in inplace .conf files Previously we were just throwing away the contents of the library-dirs fields but really we have to do the same thing as for include-dirs, relativise the paths into the current working directory and maintain any extra libraries the user has specified. Now the relevant section of the rts.conf file looks like: ``` library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib library-dirs-static: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib dynamic-library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib ``` Fixes #22209 - - - - - c9ad8852 by Andrew Lelechenko at 2023-01-28T03:00:33-05:00 Document differences between Data.{Monoid,Semigroup}.{First,Last} - - - - - 7e11c6dc by Cheng Shao at 2023-01-28T03:01:09-05:00 compiler: fix subword literal narrowing logic in the wasm NCG This patch fixes the W8/W16 literal narrowing logic in the wasm NCG, which used to lower it to something like i32.const -1, without properly zeroing-out the unused higher bits. Fixes #22608. - - - - - 6ea2aa02 by Cheng Shao at 2023-01-28T03:01:46-05:00 compiler: fix lowering of CmmBlock in the wasm NCG The CmmBlock datacon was not handled in lower_CmmLit, since I thought it would have been eliminated after proc-point splitting. Turns out it still occurs in very rare occasions, and this patch is needed to fix T9329 for wasm. - - - - - 2b62739d by Andrew Lelechenko at 2023-01-28T17:16:11-05:00 Assorted changes to avoid Data.List.{head,tail} - - - - - 78c07219 by Cheng Shao at 2023-01-28T17:16:48-05:00 compiler: properly handle ForeignHints in the wasm NCG Properly handle ForeignHints of ccall arguments/return value, insert sign extends and truncations when handling signed subwords. Fixes #22852. - - - - - 8bed166b by Ben Gamari at 2023-01-30T05:06:26-05:00 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. - - - - - da468391 by Cheng Shao at 2023-01-30T05:07:03-05:00 compiler: fix data section alignment in the wasm NCG Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size. - - - - - 08ba8720 by Andreas Klebinger at 2023-01-30T21:18:45-05:00 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- - - - - - 20598ef6 by Ryan Scott at 2023-01-30T21:19:20-05:00 Handle `type data` properly in tyThingParent_maybe Unlike most other data constructors, data constructors declared with `type data` are represented in `TyThing`s as `ATyCon` rather than `ADataCon`. The `ATyCon` case in `tyThingParent_maybe` previously did not consider the possibility of the underlying `TyCon` being a promoted data constructor, which led to the oddities observed in #22817. This patch adds a dedicated special case in `tyThingParent_maybe`'s `ATyCon` case for `type data` data constructors to fix these oddities. Fixes #22817. - - - - - 2f145052 by Ryan Scott at 2023-01-30T21:19:56-05:00 Fix two bugs in TypeData TH reification This patch fixes two issues in the way that `type data` declarations were reified with Template Haskell: * `type data` data constructors are now properly reified using `DataConI`. This is accomplished with a special case in `reifyTyCon`. Fixes #22818. * `type data` type constructors are now reified in `reifyTyCon` using `TypeDataD` instead of `DataD`. Fixes #22819. - - - - - d0f34f25 by Simon Peyton Jones at 2023-01-30T21:20:35-05:00 Take account of loop breakers in specLookupRule The key change is that in GHC.Core.Opt.Specialise.specLookupRule we were using realIdUnfolding, which ignores the loop-breaker flag. When given a loop breaker, rule matching therefore looped infinitely -- #22802. In fixing this I refactored a bit. * Define GHC.Core.InScopeEnv as a data type, and use it. (Previously it was a pair: hard to grep for.) * Put several functions returning an IdUnfoldingFun into GHC.Types.Id, namely idUnfolding alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun and use them. (The are all loop-breaker aware.) - - - - - de963cb6 by Matthew Pickering at 2023-01-30T21:21:11-05:00 ci: Remove FreeBSD job from release pipelines We no longer attempt to build or distribute this release - - - - - f26d27ec by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Add check to make sure that release jobs are downloaded by fetch-gitlab This check makes sure that if a job is a prefixed by "release-" then the script downloads it and understands how to map the job name to the platform. - - - - - 7619c0b4 by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Fix the name of the ubuntu-* jobs These were not uploaded for alpha1 Fixes #22844 - - - - - 68eb8877 by Matthew Pickering at 2023-01-30T21:21:11-05:00 gen_ci: Only consider release jobs for job metadata In particular we do not have a release job for FreeBSD so the generation of the platform mapping was failing. - - - - - b69461a0 by Jason Shipman at 2023-01-30T21:21:50-05:00 User's guide: Clarify overlapping instance candidate elimination This commit updates the user's guide section on overlapping instance candidate elimination to use "or" verbiage instead of "either/or" in regards to the current pair of candidates' being overlappable or overlapping. "Either IX is overlappable, or IY is overlapping" can cause confusion as it suggests "Either IX is overlappable, or IY is overlapping, but not both". This was initially discussed on this Discourse topic: https://discourse.haskell.org/t/clarification-on-overlapping-instance-candidate-elimination/5677 - - - - - 7cbdaad0 by Matthew Pickering at 2023-01-31T07:53:53-05:00 Fixes for cabal-reinstall CI job * Allow filepath to be reinstalled * Bump some version bounds to allow newer versions of libraries * Rework testing logic to avoid "install --lib" and package env files Fixes #22344 - - - - - fd8f32bf by Cheng Shao at 2023-01-31T07:54:29-05:00 rts: prevent potential divide-by-zero when tickInterval=0 This patch fixes a few places in RtsFlags.c that may result in divide-by-zero error when tickInterval=0, which is the default on wasm. Fixes #22603. - - - - - 085a6db6 by Joachim Breitner at 2023-01-31T07:55:05-05:00 Update note at beginning of GHC.Builtin.NAmes some things have been renamed since it was written, it seems. - - - - - 7716cbe6 by Cheng Shao at 2023-01-31T07:55:41-05:00 testsuite: use tgamma for cg007 gamma is a glibc-only deprecated function, use tgamma instead. It's required for fixing cg007 when testing the wasm unregisterised codegen. - - - - - 19c1fbcd by doyougnu at 2023-01-31T13:08:03-05:00 InfoTableProv: ShortText --> ShortByteString - - - - - 765fab98 by doyougnu at 2023-01-31T13:08:03-05:00 FastString: add fastStringToShorText - - - - - a83c810d by Simon Peyton Jones at 2023-01-31T13:08:38-05:00 Improve exprOkForSpeculation for classops This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord - - - - - f83374f8 by Krzysztof Gogolewski at 2023-01-31T13:09:14-05:00 Support "unusable UNPACK pragma" warning with -O0 Fixes #11270 - - - - - a2d814dc by Ben Gamari at 2023-01-31T13:09:50-05:00 configure: Always create the VERSION file Teach the `configure` script to create the `VERSION` file. This will serve as the stable interface to allow the user to determine the version number of a working tree. Fixes #22322. - - - - - 5618fc21 by sheaf at 2023-01-31T15:51:06-05:00 Cmm: track the type of global registers This patch tracks the type of Cmm global registers. This is needed in order to lint uses of polymorphic registers, such as SIMD vector registers that can be used both for floating-point and integer values. This changes allows us to refactor VanillaReg to not store VGcPtr, as that information is instead stored in the type of the usage of the register. Fixes #22297 - - - - - 78b99430 by sheaf at 2023-01-31T15:51:06-05:00 Revert "Cmm Lint: relax SIMD register assignment check" This reverts commit 3be48877, which weakened a Cmm Lint check involving SIMD vectors. Now that we keep track of the type a global register is used at, we can restore the original stronger check. - - - - - be417a47 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. - - - - - 30989d13 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. - - - - - 7566fd9d by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. - - - - - 2cb500a5 by Ben Gamari at 2023-01-31T15:51:45-05:00 testsuite: Add regression test for #22798 - - - - - 03d693b2 by Ben Gamari at 2023-01-31T15:52:32-05:00 Revert "Hadrian: fix doc generation" This is too large of a hammer. This reverts commit 5640cb1d84d3cce4ce0a9e90d29b2b20d2b38c2f. - - - - - f838815c by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Sphinx docs require templated cabal files The package-version discovery logic in `doc/users_guide/package_versions.py` uses packages' cabal files to determine package versions. Teach Sphinx about these dependencies in cases where the cabal files are generated by templates. - - - - - 2e48c19a by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Refactor templating logic This refactors Hadrian's autoconf-style templating logic to be explicit about which interpolation variables should be substituted in which files. This clears the way to fix #22714 without incurring rule cycles. - - - - - 93f0e3c4 by Ben Gamari at 2023-01-31T15:52:33-05:00 hadrian: Substitute LIBRARY_*_VERSION variables This teaches Hadrian to substitute the `LIBRARY_*_VERSION` variables in `libraries/prologue.txt`, fixing #22714. Fixes #22714. - - - - - 22089f69 by Ben Gamari at 2023-01-31T20:46:27-05:00 Bump transformers submodule to 0.6.0.6 Fixes #22862. - - - - - f0eefa3c by Cheng Shao at 2023-01-31T20:47:03-05:00 compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCG Currently, the wasm NCG has an implicit assumption: all CmmSwitch scrutinees are 32-bit integers. This is not always true; #22864 is one counter-example with a 64-bit scrutinee. This patch fixes the logic by explicitly converting the scrutinee to a word that can be used as a br_table operand. Fixes #22871. Also includes a regression test. - - - - - 9f95db54 by Simon Peyton Jones at 2023-02-01T08:55:08+00:00 Improve treatment of type applications in patterns This patch fixes a subtle bug in the typechecking of type applications in patterns, e.g. f (MkT @Int @a x y) = ... See Note [Type applications in patterns] in GHC.Tc.Gen.Pat. This fixes #19847, #22383, #19577, #21501 - - - - - 955a99ea by Simon Peyton Jones at 2023-02-01T12:31:23-05:00 Treat existentials correctly in dubiousDataConInstArgTys Consider (#22849) data T a where MkT :: forall k (t::k->*) (ix::k). t ix -> T @k a Then dubiousDataConInstArgTys MkT [Type, Foo] should return [Foo (ix::Type)] NOT [Foo (ix::k)] A bit of an obscure case, but it's an outright bug, and the fix is easy. - - - - - 0cc16aaf by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump supported LLVM range from 10 through 15 to 11 through 16 LLVM 15 turns on the new pass manager by default, which we have yet to migrate to so for new we pass the `-enable-new-pm-0` flag in our llvm-passes flag. LLVM 11 was the first version to support the `-enable-new-pm` flag so we bump the lowest supported version to 11. Our CI jobs are using LLVM 12 so they should continue to work despite this bump to the lower bound. Fixes #21936 - - - - - f94f1450 by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump DOCKER_REV to use alpine image without LLVM installed alpine_3_12 only supports LLVM 10, which is now outside the supported version range. - - - - - 083e26ed by Matthew Pickering at 2023-02-01T17:43:21-05:00 Remove tracing OPTIONS_GHC These were accidentally left over from !9542 - - - - - 354aa47d by Teo Camarasu at 2023-02-01T17:44:00-05:00 doc: fix gcdetails_block_fragmentation_bytes since annotation - - - - - 61ce5bf6 by Jaro Reinders at 2023-02-02T00:15:30-05:00 compiler: Implement higher order patterns in the rule matcher This implements proposal 555 and closes ticket #22465. See the proposal and ticket for motivation. The core changes of this patch are in the GHC.Core.Rules.match function and they are explained in the Note [Matching higher order patterns]. - - - - - 394b91ce by doyougnu at 2023-02-02T00:16:10-05:00 CI: JavaScript backend runs testsuite This MR runs the testsuite for the JS backend. Note that this is a temporary solution until !9515 is merged. Key point: The CI runs hadrian on the built cross compiler _but not_ on the bindist. Other Highlights: - stm submodule gets a bump to mark tests as broken - several tests are marked as broken or are fixed by adding more - conditions to their test runner instance. List of working commit messages: CI: test cross target _and_ emulator CI: JS: Try run testsuite with hadrian JS.CI: cleanup and simplify hadrian invocation use single bracket, print info JS CI: remove call to test_compiler from hadrian don't build haddock JS: mark more tests as broken Tracked in https://gitlab.haskell.org/ghc/ghc/-/issues/22576 JS testsuite: don't skip sum_mod test Its expected to fail, yet we skipped it which automatically makes it succeed leading to an unexpected success, JS testsuite: don't mark T12035j as skip leads to an unexpected pass JS testsuite: remove broken on T14075 leads to unexpected pass JS testsuite: mark more tests as broken JS testsuite: mark T11760 in base as broken JS testsuite: mark ManyUnbSums broken submodules: bump process and hpc for JS tests Both submodules has needed tests skipped or marked broken for th JS backend. This commit now adds these changes to GHC. See: HPC: https://gitlab.haskell.org/hpc/hpc/-/merge_requests/21 Process: https://github.com/haskell/process/pull/268 remove js_broken on now passing tests separate wasm and js backend ci test: T11760: add threaded, non-moving only_ways test: T10296a add req_c T13894: skip for JS backend tests: jspace, T22333: mark as js_broken(22573) test: T22513i mark as req_th stm submodule: mark stm055, T16707 broken for JS tests: js_broken(22374) on unpack_sums_6, T12010 dont run diff on JS CI, cleanup fixup: More CI cleanup fix: align text to master fix: align exceptions submodule to master CI: Bump DOCKER_REV Bump to ci-images commit that has a deb11 build with node. Required for !9552 testsuite: mark T22669 as js_skip See #22669 This test tests that .o-boot files aren't created when run in using the interpreter backend. Thus this is not relevant for the JS backend. testsuite: mark T22671 as broken on JS See #22835 base.testsuite: mark Chan002 fragile for JS see #22836 revert: submodule process bump bump stm submodule New hash includes skips for the JS backend. testsuite: mark RnPatternSynonymFail broken on JS Requires TH: - see !9779 - and #22261 compiler: GHC.hs ifdef import Utils.Panic.Plain - - - - - 1ffe770c by Cheng Shao at 2023-02-02T09:40:38+00:00 docs: 9.6 release notes for wasm backend - - - - - 0ada4547 by Matthew Pickering at 2023-02-02T11:39:44-05:00 Disable unfolding sharing for interface files with core definitions Ticket #22807 pointed out that the RHS sharing was not compatible with -fignore-interface-pragmas because the flag would remove unfoldings from identifiers before the `extra-decls` field was populated. For the 9.6 timescale the only solution is to disable this sharing, which will make interface files bigger but this is acceptable for the first release of `-fwrite-if-simplified-core`. For 9.8 it would be good to fix this by implementing #20056 due to the large number of other bugs that would fix. I also improved the error message in tc_iface_binding to avoid the "no match in record selector" error but it should never happen now as the entire sharing logic is disabled. Also added the currently broken test for #22807 which could be fixed by !6080 Fixes #22807 - - - - - 7e2d3eb5 by lrzlin at 2023-02-03T05:23:27-05:00 Enable tables next to code for LoongArch64 - - - - - 2931712a by Wander Hillen at 2023-02-03T05:24:06-05:00 Move pthread and timerfd ticker implementations to separate files - - - - - 41c4baf8 by Ben Gamari at 2023-02-03T05:24:44-05:00 base: Fix Note references in GHC.IO.Handle.Types - - - - - 31358198 by Andrew Lelechenko at 2023-02-03T05:25:22-05:00 Bump submodule containers to 0.6.7 Metric Decrease: ManyConstructors T10421 T12425 T12707 T13035 T13379 T15164 T1969 T783 T9198 T9961 WWRec - - - - - 8feb9301 by Ben Gamari at 2023-02-03T05:25:59-05:00 gitlab-ci: Eliminate redundant ghc --info output Previously ci.sh would emit the output of `ghc --info` every time it ran when using the nix toolchain. This produced a significant amount of noise. See #22861. - - - - - de1d1512 by Ryan Scott at 2023-02-03T14:07:30-05:00 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` - - - - - 48e39195 by Tamar Christina at 2023-02-03T14:07:30-05:00 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. - - - - - b2bb3e62 by Ben Gamari at 2023-02-03T14:07:30-05:00 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - bf3f88a1 by Andreas Klebinger at 2023-02-03T14:08:07-05:00 Fix CallerCC potentially shadowing other cost centres. Add a CallerCC cost centre flavour for cost centres added by the CallerCC pass. This avoids potential accidental shadowing between CCs added by user annotations and ones added by CallerCC. - - - - - faea4bcd by j at 2023-02-03T14:08:47-05:00 Disable several ignore-warning flags in genapply. - - - - - 25537dfd by Ben Gamari at 2023-02-04T04:12:57-05:00 Revert "Use fix-sized bit-fiddling primops for fixed size boxed types" This reverts commit 4512ad2d6a8e65ea43c86c816411cb13b822f674. This was never applied to master/9.6 originally. (cherry picked from commit a44bdc2720015c03d57f470b759ece7fab29a57a) - - - - - 7612dc71 by Krzysztof Gogolewski at 2023-02-04T04:13:34-05:00 Minor refactor * Introduce refactorDupsOn f = refactorDups (comparing f) * Make mkBigTupleCase and coreCaseTuple monadic. Every call to those functions was preceded by calling newUniqueSupply. * Use mkUserLocalOrCoVar, which is equivalent to combining mkLocalIdOrCoVar with mkInternalName. - - - - - 5a54ac0b by Andrew Lelechenko at 2023-02-04T18:48:32-05:00 Fix colors in emacs terminal - - - - - 3c0f0c6d by Andrew Lelechenko at 2023-02-04T18:49:11-05:00 base changelog: move entries which were not backported to ghc-9.6 to base-4.19 section - - - - - b18fbf52 by Josh Meredith at 2023-02-06T07:47:57+00:00 Update JavaScript fileStat to match Emscripten layout - - - - - 6636b670 by Sylvain Henry at 2023-02-06T09:43:21-05:00 JS: replace "js" architecture with "javascript" Despite Cabal supporting any architecture name, `cabal --check` only supports a few built-in ones. Sadly `cabal --check` is used by Hackage hence using any non built-in name in a package (e.g. `arch(js)`) is rejected and the package is prevented from being uploaded on Hackage. Luckily built-in support for the `javascript` architecture was added for GHCJS a while ago. In order to allow newer `base` to be uploaded on Hackage we make the switch from `js` to `javascript` architecture. Fixes #22740. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 77a8234c by Luite Stegeman at 2023-02-06T09:43:59-05:00 Fix marking async exceptions in the JS backend Async exceptions are posted as a pair of the exception and the thread object. This fixes the marking pass to correctly follow the two elements of the pair. Potentially fixes #22836 - - - - - 3e09cf82 by Jan Hrček at 2023-02-06T09:44:38-05:00 Remove extraneous word in Roles user guide - - - - - b17fb3d9 by sheaf at 2023-02-07T10:51:33-05:00 Don't allow . in overloaded labels This patch removes . from the list of allowed characters in a non-quoted overloaded label, as it was realised this steals syntax, e.g. (#.). Users who want this functionality will have to add quotes around the label, e.g. `#"17.28"`. Fixes #22821 - - - - - 5dce04ee by romes at 2023-02-07T10:52:10-05:00 Update kinds in comments in GHC.Core.TyCon Use `Type` instead of star kind (*) Fix comment with incorrect kind * to have kind `Constraint` - - - - - 92916194 by Ben Gamari at 2023-02-07T10:52:48-05:00 Revert "Use fix-sized equality primops for fixed size boxed types" This reverts commit 024020c38126f3ce326ff56906d53525bc71690c. This was never applied to master/9.6 originally. See #20405 for why using these primops is a bad idea. (cherry picked from commit b1d109ad542e4c37ae5af6ace71baf2cb509d865) - - - - - c1670c6b by Sylvain Henry at 2023-02-07T21:25:18-05:00 JS: avoid head/tail and unpackFS - - - - - a9912de7 by Krzysztof Gogolewski at 2023-02-07T21:25:53-05:00 testsuite: Fix Python warnings (#22856) - - - - - 9ee761bf by sheaf at 2023-02-08T14:40:40-05:00 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 - - - - - 7eac2468 by Matthew Pickering at 2023-02-08T14:41:17-05:00 Revert "Don't keep exit join points so much" This reverts commit caced75765472a1a94453f2e5a439dba0d04a265. It seems the patch "Don't keep exit join points so much" is causing wide-spread regressions in the bytestring library benchmarks. If I revert it then the 9.6 numbers are better on average than 9.4. See https://gitlab.haskell.org/ghc/ghc/-/issues/22893#note_479525 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T12150 T13386 T13719 T21839c T3294 parsing001 ------------------------- - - - - - 633f2799 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: remove config.use_threads This patch simplifies the testsuite driver by removing the use_threads config field. It's just a degenerate case of threads=1. - - - - - ca6673e3 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: use concurrent.futures.ThreadPoolExecutor in the driver The testsuite driver used to create one thread per test case, and explicitly use semaphore and locks for rate limiting and synchronization. This is a bad practice in any language, and occasionally may result in livelock conditions (e.g. #22889). This patch uses concurrent.futures.ThreadPoolExecutor for scheduling test case runs, which is simpler and more robust. - - - - - f22cce70 by Alan Zimmerman at 2023-02-08T18:42:51-05:00 EPA: Comment between module and where should be in header comments Do not apply the heuristic to associate a comment with a prior declaration for the first declaration in the file. Closes #22919 - - - - - d69ecac2 by Josh Meredith at 2023-02-09T03:24:05-05:00 JS generated refs: update testsuite conditions - - - - - 2ea1a6bc by sheaf at 2023-02-09T03:24:44-05:00 Bump transformers to 0.6.1.0 This allows us to avoid orphans for Foldable1 instances, fixing #22898. Updates transformers submodule. - - - - - d9d0c28d by konsumlamm at 2023-02-09T14:07:48-05:00 Update `Data.List.singleton` doc comment - - - - - fe9cd6ef by Ben Gamari at 2023-02-09T14:08:23-05:00 gitlab-template: Emphasize `user facing` label My sense is that the current mention of the ~"user facing" label is overlooked by many MR authors. Let's move this point up in the list to make it more likely that it is seen. Also rephrase some of the points. - - - - - e45eb828 by Simon Peyton Jones at 2023-02-10T06:51:28-05:00 Refactor the simplifier a bit to fix #22761 The core change in this commit, which fixes #22761, is that * In a Core rule, ru_rhs is always occ-analysed. This means adding a couple of calls to occurAnalyseExpr when building a Rule, in * GHC.Core.Rules.mkRule * GHC.Core.Opt.Simplify.Iteration.simplRules But diagosing the bug made me stare carefully at the code of the Simplifier, and I ended up doing some only-loosely-related refactoring. * I think that RULES could be lost because not every code path did addBndrRules * The code around lambdas was very convoluted It's mainly moving deck chairs around, but I like it more now. - - - - - 11e0cacb by Rebecca Turner at 2023-02-10T06:52:09-05:00 Detect the `mold` linker Enables support for the `mold` linker by rui314. - - - - - 59556235 by parsonsmatt at 2023-02-10T09:53:11-05:00 Add Lift instance for Fixed - - - - - c44e5f30 by Sylvain Henry at 2023-02-10T09:53:51-05:00 Testsuite: decrease length001 timeout for JS (#22921) - - - - - 133516af by Zubin Duggal at 2023-02-10T09:54:27-05:00 compiler: Use NamedFieldPuns for `ModIface_` and `ModIfaceBackend` `NFData` instances This is a minor refactor that makes it easy to add and remove fields from `ModIface_` and `ModIfaceBackend`. Also change the formatting to make it clear exactly which fields are fully forced with `rnf` - - - - - 1e9eac1c by Matthew Pickering at 2023-02-13T11:36:41+01:00 Refresh profiling docs I went through the whole of the profiling docs and tried to amend them to reflect current best practices and tooling. In particular I removed some old references to tools such as hp2any and replaced them with references to eventlog2html. - - - - - da208b9a by Matthew Pickering at 2023-02-13T11:36:41+01:00 docs: Add section about profiling and foreign calls Previously there was no documentation for how foreign calls interacted with the profiler. This can be quite confusing for users so getting it into the user guide is the first step to a potentially better solution. See the ticket for more insightful discussion. Fixes #21764 - - - - - 081640f1 by Andrew Lelechenko at 2023-02-13T12:51:52-05:00 Document that -fproc-alignment was introduced only in GHC 8.6 - - - - - 16adc349 by Sven Tennie at 2023-02-14T11:26:31-05:00 Add clangd flag to include generated header files This enables clangd to correctly check C files that import Rts.h. (The added include directory contains ghcautoconf.h et. al.) - - - - - c399ccd9 by amesgen at 2023-02-14T11:27:14-05:00 Mention new `Foreign.Marshal.Pool` implementation in User's Guide - - - - - b9282cf7 by Ben Gamari at 2023-02-14T11:27:50-05:00 upload_ghc_libs: More control over which packages to operate on Here we add a `--skip` flag to `upload_ghc_libs`, making it easier to limit which packages to upload. This is often necessary when one package is not uploadable (e.g. see #22740). - - - - - aa3a262d by PHO at 2023-02-14T11:28:29-05:00 Assume platforms support rpaths if they use either ELF or Mach-O Not only Linux, Darwin, and FreeBSD support rpaths. Determine the usability of rpaths based on the object format, not on OS. - - - - - 47716024 by PHO at 2023-02-14T11:29:09-05:00 RTS linker: Improve compatibility with NetBSD 1. Hint address to NetBSD mmap(2) has a different semantics from that of Linux. When a hint address is provided, mmap(2) searches for a free region at or below the hint but *never* above it. This means we can't reliably search for free regions incrementally on the userland, especially when ASLR is enabled. Let the kernel do it for us if we don't care where the mapped address is going to be. 2. NetBSD not only hates to map pages as rwx, but also disallows to switch pages from rw- to r-x unless the intention is declared when pages are initially requested. This means we need a new MemoryAccess mode for pages that are going to be changed to r-x. - - - - - 11de324a by Li-yao Xia at 2023-02-14T11:29:49-05:00 base: Move changelog entry to its place - - - - - 75930424 by Ben Gamari at 2023-02-14T11:30:27-05:00 nativeGen/AArch64: Emit Atomic{Read,Write} inline Previously the AtomicRead and AtomicWrite operations were emitted as out-of-line calls. However, these tend to be very important for performance, especially the RELAXED case (which only exists for ThreadSanitizer checking). Fixes #22115. - - - - - d6411d6c by Andreas Klebinger at 2023-02-14T11:31:04-05:00 Fix some correctness issues around tag inference when targeting the bytecode generator. * Let binders are now always assumed untagged for bytecode. * Imported referenced are now always assumed to be untagged for bytecode. Fixes #22840 - - - - - 9fb4ca89 by sheaf at 2023-02-14T11:31:49-05:00 Introduce warning for loopy superclass solve Commit aed1974e completely re-engineered the treatment of loopy superclass dictionaries in instance declarations. Unfortunately, it has the potential to break (albeit in a rather minor way) user code. To alleviate migration concerns, this commit re-introduces the old behaviour. Any reliance on this old behaviour triggers a warning, controlled by `-Wloopy-superclass-solve`. The warning text explains that GHC might produce bottoming evidence, and provides a migration strategy. This allows us to provide a graceful migration period, alerting users when they are relying on this unsound behaviour. Fixes #22912 #22891 #20666 #22894 #22905 - - - - - 1928c7f3 by Cheng Shao at 2023-02-14T11:32:26-05:00 rts: make it possible to change mblock size on 32-bit targets The MBLOCK_SHIFT macro must be the single source of truth for defining the mblock size, and changing it should only affect performance, not correctness. This patch makes it truly possible to reconfigure mblock size, at least on 32-bit targets, by fixing places which implicitly relied on the previous MBLOCK_SHIFT constant. Fixes #22901. - - - - - 78aa3b39 by Simon Hengel at 2023-02-14T11:33:06-05:00 Update outdated references to notes - - - - - e8baecd2 by meooow25 at 2023-02-14T11:33:49-05:00 Documentation: Improve Foldable1 documentation * Explain foldrMap1, foldlMap1, foldlMap1', and foldrMap1' in greater detail, the text is mostly adapted from documentation of Foldable. * Describe foldr1, foldl1, foldl1' and foldr1' in terms of the above functions instead of redoing the full explanation. * Small updates to documentation of fold1, foldMap1 and toNonEmpty, again adapting from Foldable. * Update the foldMap1 example to lists instead of Sum since this is recommended for lazy right-associative folds. Fixes #22847 - - - - - 85a1a575 by romes at 2023-02-14T11:34:25-05:00 fix: Mark ghci Prelude import as implicit Fixes #22829 In GHCi, we were creating an import declaration for Prelude but we were not setting it as an implicit declaration. Therefore, ghci's import of Prelude triggered -Wmissing-import-lists. Adds regression test T22829 to testsuite - - - - - 3b019a7a by Cheng Shao at 2023-02-14T11:35:03-05:00 compiler: fix generateCgIPEStub for no-tables-next-to-code builds generateCgIPEStub already correctly implements the CmmTick finding logic for when tables-next-to-code is on/off, but it used the wrong predicate to decide when to switch between the two. Previously it switches based on whether the codegen is unregisterised, but there do exist registerised builds that disable tables-next-to-code! This patch corrects that problem. Fixes #22896. - - - - - 08c0822c by doyougnu at 2023-02-15T00:16:39-05:00 docs: release notes, user guide: add js backend Follow up from #21078 - - - - - 79d8fd65 by Bryan Richter at 2023-02-15T00:17:15-05:00 Allow failure in nightly-x86_64-linux-deb10-no_tntc-validate See #22343 - - - - - 9ca51f9e by Cheng Shao at 2023-02-15T00:17:53-05:00 rts: add the rts_clearMemory function This patch adds the rts_clearMemory function that does its best to zero out unused RTS memory for a wasm backend use case. See the comment above rts_clearMemory() prototype declaration for more detailed explanation. Closes #22920. - - - - - 26df73fb by Oleg Grenrus at 2023-02-15T22:20:57-05:00 Add -single-threaded flag to force single threaded rts This is the small part of implementing https://github.com/ghc-proposals/ghc-proposals/pull/240 - - - - - 631c6c72 by Cheng Shao at 2023-02-16T06:43:09-05:00 docs: add a section for the wasm backend Fixes #22658 - - - - - 1878e0bd by Bryan Richter at 2023-02-16T06:43:47-05:00 tests: Mark T12903 fragile everywhere See #21184 - - - - - b9420eac by Bryan Richter at 2023-02-16T06:43:47-05:00 Mark all T5435 variants as fragile See #22970. - - - - - df3d94bd by Sylvain Henry at 2023-02-16T06:44:33-05:00 Testsuite: mark T13167 as fragile for JS (#22921) - - - - - 324e925b by Sylvain Henry at 2023-02-16T06:45:15-05:00 JS: disable debugging info for heap objects - - - - - 518af814 by Josh Meredith at 2023-02-16T10:16:32-05:00 Factor JS Rts generation for h$c{_,0,1,2} into h$c{n} and improve name caching - - - - - 34cd308e by Ben Gamari at 2023-02-16T10:17:08-05:00 base: Note move of GHC.Stack.CCS.whereFrom to GHC.InfoProv in changelog Fixes #22883. - - - - - 12965aba by Simon Peyton Jones at 2023-02-16T10:17:46-05:00 Narrow the dont-decompose-newtype test Following #22924 this patch narrows the test that stops us decomposing newtypes. The key change is the use of noGivenNewtypeReprEqs in GHC.Tc.Solver.Canonical.canTyConApp. We went to and fro on the solution, as you can see in #22924. The result is carefully documented in Note [Decomoposing newtype equalities] On the way I had revert most of commit 3e827c3f74ef76d90d79ab6c4e71aa954a1a6b90 Author: Richard Eisenberg <rae at cs.brynmawr.edu> Date: Mon Dec 5 10:14:02 2022 -0500 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. It turns out that (a) 3e827c3f makes GHC behave worse on some recursive newtypes (see one of the tests on this commit) (b) the finer-grained test (namely noGivenNewtypeReprEqs) renders 3e827c3f unnecessary - - - - - 5b038888 by Andrew Lelechenko at 2023-02-16T10:18:24-05:00 Documentation: add an example of SPEC usage - - - - - 681e0e8c by sheaf at 2023-02-16T14:09:56-05:00 No default finalizer exception handler Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680 - - - - - b3ac17ad by Matthew Pickering at 2023-02-16T14:10:31-05:00 unicode: Don't inline bitmap in generalCategory generalCategory contains a huge literal string but is marked INLINE, this will duplicate the string into any use site of generalCategory. In particular generalCategory is used in functions like isSpace and the literal gets inlined into this function which makes it massive. https://github.com/haskell/core-libraries-committee/issues/130 Fixes #22949 ------------------------- Metric Decrease: T4029 T18304 ------------------------- - - - - - 8988eeef by sheaf at 2023-02-16T20:32:27-05:00 Expand synonyms in RoughMap We were failing to expand type synonyms in the function GHC.Core.RoughMap.typeToRoughMatchLookupTc, even though the RoughMap infrastructure crucially relies on type synonym expansion to work. This patch adds the missing type-synonym expansion. Fixes #22985 - - - - - 3dd50e2f by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Add test artifact Add the released testsuite tarball to the generated ghcup metadata. - - - - - c6a967d9 by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Use Ubuntu and Rocky bindists Prefer to use the Ubuntu 20.04 and 18.04 binary distributions on Ubuntu and Linux Mint. Prefer to use the Rocky 8 binary distribution on unknown distributions. - - - - - be0b7209 by Matthew Pickering at 2023-02-17T09:37:16+00:00 Add INLINABLE pragmas to `generic*` functions in Data.OldList These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129 - - - - - a203ad85 by Sylvain Henry at 2023-02-17T15:59:16-05:00 Merge libiserv with ghci `libiserv` serves no purpose. As it depends on `ghci` and doesn't have more dependencies than the `ghci` package, its code could live in the `ghci` package too. This commit also moves most of the code from the `iserv` program into the `ghci` package as well so that it can be reused. This is especially useful for the implementation of TH for the JS backend (#22261, !9779). - - - - - 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Andrew Lelechenko at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Andrew Lelechenko at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Andrew Lelechenko at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Andrew Lelechenko at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Andrew Lelechenko at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Andrew Lelechenko at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Andrew Lelechenko at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Andrew Lelechenko at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Andrew Lelechenko at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Andrew Lelechenko at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Andrew Lelechenko at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 57277662 by sheaf at 2023-04-29T20:23:06+02:00 Add the Unsatisfiable class This commit implements GHC proposal #433, adding the Unsatisfiable class to the GHC.TypeError module. This provides an alternative to TypeError for which error reporting is more predictable: we report it when we are reporting unsolved Wanted constraints. Fixes #14983 #16249 #16906 #18310 #20835 - - - - - 00a8a5ff by Torsten Schmits at 2023-04-30T03:45:09-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 931c8d82 by Ben Orchard at 2023-05-03T20:16:18-04:00 Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - f3460845 by Andrew Lelechenko at 2023-05-03T20:16:57-04:00 Document instances of Double - - - - - 1e9caa1a by Sylvain Henry at 2023-05-03T20:17:37-04:00 Bump Cabal submodule (#22356) - - - - - 4eafb52a by sheaf at 2023-05-03T20:18:16-04:00 Don't forget to check the parent in an export list Commit 3f374399 introduced a bug which caused us to forget to include the parent of an export item of the form T(..) (that is, IEThingAll) when checking for duplicate exports. Fixes #23318 - - - - - 8fde4ac8 by amesgen at 2023-05-03T20:18:57-04:00 Fix unlit path in cross bindists - - - - - 8cc9a534 by Matthew Pickering at 2023-05-04T14:58:14-04:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 3fdb18f8 by romes at 2023-05-04T14:58:14-04:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 6689c9c6 by romes at 2023-05-04T14:58:14-04:00 Validate compatibility of ghcs when loading plugins Ensure, when loading plugins, that the ghc the plugin depends on is the ghc loading the plugin -- otherwise fail to load the plugin. Progress towards #20742. - - - - - db4be339 by romes at 2023-05-04T14:58:14-04:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 944a9b94 by Matthew Pickering at 2023-05-04T14:58:14-04:00 Use hash-unit-ids in release jobs Includes fix upload_ghc_libs glob - - - - - 116d7312 by Josh Meredith at 2023-05-04T14:58:51-04:00 JS: fix bounds checking (Issue 23123) * For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. * Range-based operations must also check both the start and end of the range for bounds * All indicies are valid for ranges of size zero, since they are essentially no-ops * For cases of ByteArray accesses (e.g. read as Int), the end index is (i * sizeof(type) + sizeof(type) - 1), while the previous implementation uses (i + sizeof(type) - 1). In the Int32 example, this is (i * 4 + 3) * IndexByteArrayOp_Word8As* primitives use byte array indicies (unlike the previous point), but now check both start and end indicies * Byte array copies now check if the arrays are the same by identity and then if the ranges overlap. - - - - - 2d5c1dde by Sylvain Henry at 2023-05-04T14:58:51-04:00 Fix remaining issues with bound checking (#23123) While fixing these I've also changed the way we store addresses into ByteArray#. Addr# are composed of two parts: a JavaScript array and an offset (32-bit number). Suppose we want to store an Addr# in a ByteArray# foo at offset i. Before this patch, we were storing both fields as a tuple in the "arr" array field: foo.arr[i] = [addr_arr, addr_offset]; Now we only store the array part in the "arr" field and the offset directly in the array: foo.dv.setInt32(i, addr_offset): foo.arr[i] = addr_arr; It avoids wasting space for the tuple. - - - - - 98c5ee45 by Luite Stegeman at 2023-05-04T14:59:31-04:00 JavaScript: Correct arguments to h$appendToHsStringA fixes #23278 - - - - - ca611447 by Josh Meredith at 2023-05-04T15:00:07-04:00 base/encoding: add an allocations performance test (#22946) - - - - - e3ddf58d by Krzysztof Gogolewski at 2023-05-04T15:00:44-04:00 linear types: Don't add external names to the usage env This has no observable effect, but avoids storing useless data. - - - - - b3226616 by Andrei Borzenkov at 2023-05-04T15:01:25-04:00 Improved documentation for the Data.OldList.nub function There was recomentation to use map head . group . sort instead of nub function, but containers library has more suitable and efficient analogue - - - - - e8b72ff6 by Ryan Scott at 2023-05-04T15:02:02-04:00 Fix type variable substitution in gen_Newtype_fam_insts Previously, `gen_Newtype_fam_insts` was substituting the type variable binders of a type family instance using `substTyVars`, which failed to take type variable dependencies into account. There is similar code in `GHC.Tc.TyCl.Class.tcATDefault` that _does_ perform this substitution properly, so this patch: 1. Factors out this code into a top-level `substATBndrs` function, and 2. Uses `substATBndrs` in `gen_Newtype_fam_insts`. Fixes #23329. - - - - - 275836d2 by Torsten Schmits at 2023-05-05T08:43:02+00:00 Add structured error messages for GHC.Rename.Utils Tracking ticket: #20115 MR: !10350 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 983ce558 by Oleg Grenrus at 2023-05-05T13:11:29-04:00 Use TemplateHaskellQuotes in TH.Syntax to construct Names - - - - - a5174a59 by Matthew Pickering at 2023-05-05T18:42:31-04:00 driver: Use hooks from plugin_hsc_env This fixes a bug in oneshot mode where hooks modified in a plugin wouldn't be used in oneshot mode because we neglected to use the right hsc_env. This was observed by @csabahruska. - - - - - 18a7d03d by Aaron Allen at 2023-05-05T18:42:31-04:00 Rework plugin initialisation points In general this patch pushes plugin initialisation points to earlier in the pipeline. As plugins can modify the `HscEnv`, it's imperative that the plugins are initialised as soon as possible and used thereafter. For example, there are some new tests which modify hsc_logger and other hooks which failed to fire before (and now do) One consequence of this change is that the error for specifying the usage of a HPT plugin from the command line has changed, because it's now attempted to be loaded at initialisation rather than causing a cyclic module import. Closes #21279 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 6e776ed3 by Matthew Pickering at 2023-05-05T18:42:31-04:00 docs: Add Note [Timing of plugin initialization] - - - - - e1df8511 by Matthew Pickering at 2023-05-05T18:43:07-04:00 Incrementally update ghcup metadata in ghc/ghcup-metadata This job paves the way for distributing nightly builds * A new repo https://gitlab.haskell.org/ghc/ghcup-metadata stores the metadata on the "updates" branch. * Each night this metadata is downloaded and the nightly builds are appended to the end of the metadata. * The update job only runs on the scheduled nightly pipeline, not just when NIGHTLY=1. Things which are not done yet * Modify the retention policy for nightly jobs * Think about building release flavour compilers to distribute nightly. Fixes #23334 - - - - - 8f303d27 by Rodrigo Mesquita at 2023-05-05T22:04:31-04:00 docs: Remove mentions of ArrayArray# from unlifted FFI section Fixes #23277 - - - - - 994bda56 by Torsten Schmits at 2023-05-05T22:05:12-04:00 Add structured error messages for GHC.Rename.Module Tracking ticket: #20115 MR: !10361 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. Only addresses the single warning missing from the previous MR. - - - - - 3e3a6be4 by Ben Gamari at 2023-05-08T12:15:19+00:00 rts: Fix data-race in hs_init_ghc As noticed by @Terrorjack, `hs_init_ghc` previously used non-atomic increment/decrement on the RTS's initialization count. This may go wrong in a multithreaded program which initializes the runtime multiple times. Closes #22756. - - - - - 78c8dc50 by Torsten Schmits at 2023-05-08T21:41:51-04:00 Add structured error messages for GHC.IfaceToCore Tracking ticket: #20114 MR: !10390 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 0e2df4c9 by Bryan Richter at 2023-05-09T12:03:35+03:00 Fix up rules for ghcup-metadata-nightly-push - - - - - b970e64f by Ben Gamari at 2023-05-09T08:41:33-04:00 testsuite: Add test for atomicSwapIORef - - - - - 81cfefd2 by Ben Gamari at 2023-05-09T08:41:53-04:00 compiler: Implement atomicSwapIORef with xchg As requested by @treeowl in CLC#139. - - - - - 6b29154d by Ben Gamari at 2023-05-09T08:41:53-04:00 Make atomicSwapMutVar# an inline primop - - - - - 64064cfe by doyougnu at 2023-05-09T18:40:01-04:00 JS: add GHC.JS.Optimizer, remove RTS.Printer, add Linker.Opt This MR changes some simple optimizations and is a first step in re-architecting the JS backend pipeline to add the optimizer. In particular it: - removes simple peep hole optimizations from `GHC.StgToJS.Printer` and removes that module - adds module `GHC.JS.Optimizer` - defines the same peep hole opts that were removed only now they are `Syntax -> Syntax` transformations rather than `Syntax -> JS code` optimizations - hooks the optimizer into code gen - adds FuncStat and ForStat constructors to the backend. Working Ticket: - #22736 Related MRs: - MR !10142 - MR !10000 ------------------------- Metric Decrease: CoOpt_Read ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T12707 T13253 T13253-spj T15164 T17516 T18140 T18282 T18698a T18698b T18923 T1969 T19695 T20049 T3064 T5321FD T5321Fun T783 T9198 T9233 T9630 ------------------------- - - - - - 6738c01d by Krzysztof Gogolewski at 2023-05-09T18:40:38-04:00 Add a regression test for #21050 - - - - - b2cdb7da by Ben Gamari at 2023-05-09T18:41:14-04:00 nonmoving: Account for mutator allocations in bytes_allocated Previously we failed to account direct mutator allocations into the nonmoving heap against the mutator's allocation limit and `cap->total_allocated`. This only manifests during CAF evaluation (since we allocate the CAF's blackhole directly into the nonmoving heap). Fixes #23312. - - - - - 0657b482 by Sven Tennie at 2023-05-09T22:22:42-04:00 Adjust AArch64 stackFrameHeaderSize The prologue of each stack frame are the saved LR and FP registers, 8 byte each. I.e. the size of the stack frame header is 2 * 8 byte. - - - - - 7788c09c by konsumlamm at 2023-05-09T22:23:23-04:00 Make `(&)` representation polymorphic in the return type - - - - - b3195922 by Ben Gamari at 2023-05-10T05:06:45-04:00 ghc-prim: Generalize keepAlive#/touch# in state token type Closes #23163. - - - - - 1e6861dd by Cheng Shao at 2023-05-10T05:07:25-04:00 Bump hsc2hs submodule Fixes #22981. - - - - - 0a513952 by Ben Gamari at 2023-05-11T04:10:17-04:00 base: Export GHC.Conc.Sync.fromThreadId Closes #22706. - - - - - 29be39ba by Matthew Pickering at 2023-05-11T04:10:54-04:00 Build vanilla alpine bindists We currently attempt to build and distribute fully static alpine bindists (ones which could be used on any linux platform) but most people who use the alpine bindists want to use alpine to build their own static applications (for which a fully static bindist is not necessary). We should build and distribute these bindists for these users whilst the fully-static bindist is still unusable. Fixes #23349 - - - - - 40c7daed by Simon Peyton Jones at 2023-05-11T04:11:30-04:00 Look both ways when looking for quantified equalities When looking up (t1 ~# t2) in the quantified constraints, check both orientations. Forgetting this led to #23333. - - - - - c17bb82f by Rodrigo Mesquita at 2023-05-11T04:12:07-04:00 Move "target has RTS linker" out of settings We move the "target has RTS linker" information out of configure into a predicate in GHC, and remove this option from the settings file where it is unnecessary -- it's information statically known from the platform. Note that previously we would consider `powerpc`s and `s390x`s other than `powerpc-ibm-aix*` and `s390x-ibm-linux` to have an RTS linker, but the RTS linker supports neither platform. Closes #23361 - - - - - bd0b056e by Krzysztof Gogolewski at 2023-05-11T04:12:44-04:00 Add a test for #17284 Since !10123 we now reject this program. - - - - - 630b1fea by Andrew Lelechenko at 2023-05-11T04:13:24-04:00 Document unlawfulness of instance Num Fixed Fixes #22712 - - - - - 87eebf98 by sheaf at 2023-05-11T11:55:22-04:00 Add fused multiply-add instructions This patch adds eight new primops that fuse a multiplication and an addition or subtraction: - `{fmadd,fmsub,fnmadd,fnmsub}{Float,Double}#` fmadd x y z is x * y + z, computed with a single rounding step. This patch implements code generation for these primops in the following backends: - X86, AArch64 and PowerPC NCG, - LLVM - C WASM uses the C implementation. The primops are unsupported in the JavaScript backend. The following constant folding rules are also provided: - compute a * b + c when a, b, c are all literals, - x * y + 0 ==> x * y, - ±1 * y + z ==> z ± y and x * ±1 + z ==> z ± x. NB: the constant folding rules incorrectly handle signed zero. This is a known limitation with GHC's floating-point constant folding rules (#21227), which we hope to resolve in the future. - - - - - ad16a066 by Krzysztof Gogolewski at 2023-05-11T11:55:59-04:00 Add a test for #21278 - - - - - 05cea68c by Matthew Pickering at 2023-05-11T11:56:36-04:00 rts: Refine memory retention behaviour to account for pinned/compacted objects When using the copying collector there is still a lot of data which isn't copied (such as pinned, compacted, large objects etc). The logic to decide how much memory to retain didn't take into account that these wouldn't be copied. Therefore we pessimistically retained 2* the amount of memory for these blocks even though they wouldn't be copied by the collector. The solution is to split up the heap into two parts, the parts which will be copied and the parts which won't be copied. Then the appropiate factor is applied to each part individually (2 * for copying and 1.2 * for not copying). The T23221 test demonstrates this improvement with a program which first allocates many unpinned ByteArray# followed by many pinned ByteArray# and observes the difference in the ultimate memory baseline between the two. There are some charts on #23221. Fixes #23221 - - - - - 1bb24432 by Cheng Shao at 2023-05-11T11:57:15-04:00 hadrian: fix no_dynamic_libs flavour transformer This patch fixes the no_dynamic_libs flavour transformer and make fully_static reuse it. Previously building with no_dynamic_libs fails since ghc program is still dynamic and transitively brings in dyn ways of rts which are produced by no rules. - - - - - 0ed493a3 by Josh Meredith at 2023-05-11T23:08:27-04:00 JS: refactor jsSaturate to return a saturated JStat (#23328) - - - - - a856d98e by Pierre Le Marre at 2023-05-11T23:09:08-04:00 Doc: Fix out-of-sync using-optimisation page - Make explicit that default flag values correspond to their -O0 value. - Fix -fignore-interface-pragmas, -fstg-cse, -fdo-eta-reduction, -fcross-module-specialise, -fsolve-constant-dicts, -fworker-wrapper. - - - - - c176ad18 by sheaf at 2023-05-12T06:10:57-04:00 Don't panic in mkNewTyConRhs This function could come across invalid newtype constructors, as we only perform validity checking of newtypes once we are outside the knot-tied typechecking loop. This patch changes this function to fake up a stub type in the case of an invalid newtype, instead of panicking. This patch also changes "checkNewDataCon" so that it reports as many errors as possible at once. Fixes #23308 - - - - - ab63daac by Krzysztof Gogolewski at 2023-05-12T06:11:38-04:00 Allow Core optimizations when interpreting bytecode Tracking ticket: #23056 MR: !10399 This adds the flag `-funoptimized-core-for-interpreter`, permitting use of the `-O` flag to enable optimizations when compiling with the interpreter backend, like in ghci. - - - - - c6cf9433 by Ben Gamari at 2023-05-12T06:12:14-04:00 hadrian: Fix mention of non-existent removeFiles function Previously Hadrian's bindist Makefile referred to a `removeFiles` function that was previously defined by the `make` build system. Since the `make` build system is no longer around, this function is now undefined. Naturally, make being make, this appears to be silently ignored instead of producing an error. Fix this by rewriting it to `rm -f`. Closes #23373. - - - - - eb60ec18 by Andrew Lelechenko at 2023-05-12T06:12:54-04:00 Mention new implementation of GHC.IORef.atomicSwapIORef in the changelog - - - - - aa84cff4 by Teo Camarasu at 2023-05-12T19:27:23-04:00 rts: Ensure non-moving gc is not running when pausing - - - - - 5ad776ab by Teo Camarasu at 2023-05-12T19:27:23-04:00 rts: Teach listAllBlocks about nonmoving heap List all blocks on the non-moving heap. Resolves #22627 - - - - - d683b2e5 by Krzysztof Gogolewski at 2023-05-12T19:28:00-04:00 Fix coercion optimisation for SelCo (#23362) setNominalRole_maybe is supposed to output a nominal coercion. In the SelCo case, it was not updating the stored role to Nominal, causing #23362. - - - - - 59aa4676 by Alexis King at 2023-05-12T19:28:47-04:00 hadrian: Fix linker script flag for MergeObjects builder This fixes what appears to have been a typo in !9530. The `-t` flag just enables tracing on all versions of `ld` I’ve looked at, while `-T` is used to specify a linker script. It seems that this worked anyway for some reason on some `ld` implementations (perhaps because they automatically detect linker scripts), but the missing `-T` argument causes `gold` to complain. - - - - - 4bf9fa0f by Adam Gundry at 2023-05-12T23:49:49-04:00 Less coercion optimization for non-newtype axioms See Note [Push transitivity inside newtype axioms only] for an explanation of the change here. This change substantially improves the performance of coercion optimization for programs involving transitive type family reductions. ------------------------- Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12545 T13386 T15703 T5030 T8095 ------------------------- - - - - - dc0c9574 by Adam Gundry at 2023-05-12T23:49:49-04:00 Move checkAxInstCo to GHC.Core.Lint A consequence of the previous change is that checkAxInstCo is no longer called during coercion optimization, so it can be moved back where it belongs. Also includes some edits to Note [Conflict checking with AxiomInstCo] as suggested by @simonpj. - - - - - 8b9b7dbc by Simon Peyton Jones at 2023-05-12T23:50:25-04:00 Use the eager unifier in the constraint solver This patch continues the refactoring of the constraint solver described in #23070. The Big Deal in this patch is to call the regular, eager unifier from the constraint solver, when we want to create new equalities. This replaces the existing, unifyWanted which amounted to yet-another-unifier, so it reduces duplication of a rather subtle piece of technology. See * Note [The eager unifier] in GHC.Tc.Utils.Unify * GHC.Tc.Solver.Monad.wrapUnifierTcS I did lots of other refactoring along the way * I simplified the treatment of right hand sides that contain CoercionHoles. Now, a constraint that contains a hetero-kind CoercionHole is non-canonical, and cannot be used for rewriting or unification alike. This required me to add the ch_hertero_kind flag to CoercionHole, with consequent knock-on effects. See wrinkle (2) of `Note [Equalities with incompatible kinds]` in GHC.Tc.Solver.Equality. * I refactored the StopOrContinue type to add StartAgain, so that after a fundep improvement (for example) we can simply start the pipeline again. * I got rid of the unpleasant (and inefficient) rewriterSetFromType/Co functions. With Richard I concluded that they are never needed. * I discovered Wrinkle (W1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint, and therefore now prioritise non-rewritten equalities. Quite a few error messages change, I think always for the better. Compiler runtime stays about the same, with one outlier: a 17% improvement in T17836 Metric Decrease: T17836 T18223 - - - - - 5cad28e7 by Bartłomiej Cieślar at 2023-05-12T23:51:06-04:00 Cleanup of dynflags override in export renaming The deprecation warnings are normally emitted whenever the name's GRE is being looked up, which calls the GHC.Rename.Env.addUsedGRE function. We do not want those warnings to be emitted when renaming export lists, so they are artificially turned off by removing all warning categories from DynFlags at the beginning of GHC.Tc.Gen.Export.rnExports. This commit removes that dependency by unifying the function used for GRE lookup in lookup_ie to lookupGreAvailRn and disabling the call to addUsedGRE in said function (the warnings are also disabled in a call to lookupSubBndrOcc_helper in lookupChildrenExport), as per #17957. This commit also changes the setting for whether to warn about deprecated names in addUsedGREs to be an explicit enum instead of a boolean. - - - - - d85ed900 by Alexis King at 2023-05-13T08:45:18-04:00 Use a uniform return convention in bytecode for unary results fixes #22958 - - - - - 8a0d45f7 by Andrew Lelechenko at 2023-05-13T08:45:58-04:00 Add more instances for Compose: Enum, Bounded, Num, Real, Integral See https://github.com/haskell/core-libraries-committee/issues/160 for discussion - - - - - 902f0730 by Simon Peyton Jones at 2023-05-13T14:58:34-04:00 Make GHC.Types.Id.Make.shouldUnpackTy a bit more clever As #23307, GHC.Types.Id.Make.shouldUnpackTy was leaving money on the table, failing to unpack arguments that are perfectly unpackable. The fix is pretty easy; see Note [Recursive unboxing] - - - - - a5451438 by sheaf at 2023-05-13T14:59:13-04:00 Fix bad multiplicity role in tyConAppFunCo_maybe The function tyConAppFunCo_maybe produces a multiplicity coercion for the multiplicity argument of the function arrow, except that it could be at the wrong role if asked to produce a representational coercion. We fix this by using the 'funRole' function, which computes the right roles for arguments to the function arrow TyCon. Fixes #23386 - - - - - 5b9e9300 by sheaf at 2023-05-15T11:26:59-04:00 Turn "ambiguous import" error into a panic This error should never occur, as a lookup of a type or data constructor should never be ambiguous. This is because a single module cannot export multiple Names with the same OccName, as per item (1) of Note [Exporting duplicate declarations] in GHC.Tc.Gen.Export. This code path was intended to handle duplicate record fields, but the rest of the code had since been refactored to handle those in a different way. We also remove the AmbiguousImport constructor of IELookupError, as it is no longer used. Fixes #23302 - - - - - e305e60c by M Farkas-Dyck at 2023-05-15T11:27:41-04:00 Unbreak some tests with latest GNU grep, which now warns about stray '\'. Confusingly, the testsuite mangled the error to say "stray /". We also migrate some tests from grep to grep -E, as it seems the author actually wanted an "POSIX extended" (a.k.a. sane) regex. Background: POSIX specifies 2 "regex" syntaxen: "basic" and "extended". Of these, only "extended" syntax is actually a regular expression. Furthermore, "basic" syntax is inconsistent in its use of the '\' character — sometimes it escapes a regex metacharacter, but sometimes it unescapes it, i.e. it makes an otherwise normal character become a metacharacter. This baffles me and it seems also the authors of these tests. Also, the regex(7) man page (at least on Linux) says "basic" syntax is obsolete. Nearly all modern tools and libraries are consistent in this use of the '\' character (of which many use "extended" syntax by default). - - - - - 5ae81842 by sheaf at 2023-05-15T14:49:17-04:00 Improve "ambiguous occurrence" error messages This error was sometimes a bit confusing, especially when data families were involved. This commit improves the general presentation of the "ambiguous occurrence" error, and adds a bit of extra context in the case of data families. Fixes #23301 - - - - - 2f571afe by Sylvain Henry at 2023-05-15T14:50:07-04:00 Fix GHCJS OS platform (fix #23346) - - - - - 86aae570 by Oleg Grenrus at 2023-05-15T14:50:43-04:00 Split DynFlags structure into own module This will allow to make command line parsing to depend on diagnostic system (which depends on dynflags) - - - - - fbe3fe00 by Josh Meredith at 2023-05-15T18:01:43-04:00 Replace the implementation of CodeBuffers with unboxed types - - - - - 21f3aae7 by Josh Meredith at 2023-05-15T18:01:43-04:00 Use unboxed codebuffers in base Metric Decrease: encodingAllocations - - - - - 18ea2295 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Weak pointer cleanups Various stylistic cleanups. No functional changes. - - - - - c343112f by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Don't force debug output to stderr Previously `+RTS -Dw -l` would emit debug output to the eventlog while `+RTS -l -Dw` would emit it to stderr. This was because the parser for `-D` would unconditionally override the debug output target. Now we instead only do so if no it is currently `TRACE_NONE`. - - - - - a5f5f067 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Forcibly flush eventlog on barf Previously we would attempt to flush via `endEventLogging` which can easily deadlock, e.g., if `barf` fails during GC. Using `flushEventLog` directly may result in slightly less consistent eventlog output (since we don't take all capabilities before flushing) but avoids deadlocking. - - - - - 73b1e87c by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Assert that pointers aren't cleared by -DZ This turns many segmentation faults into much easier-to-debug assertion failures by ensuring that LOOKS_LIKE_*_PTR checks recognize bit-patterns produced by `+RTS -DZ` clearing as invalid pointers. This is a bit ad-hoc but this is the debug runtime. - - - - - 37fb61d8 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Introduce printGlobalThreads - - - - - 451d65a6 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Don't sanity-check StgTSO.global_link See Note [Avoid dangling global_link pointers]. Fixes #19146. - - - - - d69cbd78 by sheaf at 2023-05-15T18:03:00-04:00 Split up tyThingToIfaceDecl from GHC.Iface.Make This commit moves tyThingToIfaceDecl and coAxiomToIfaceDecl from GHC.Iface.Make into GHC.Iface.Decl. This avoids GHC.Types.TyThing.Ppr, which needs tyThingToIfaceDecl, transitively depending on e.g. GHC.Iface.Load and GHC.Tc.Utils.Monad. - - - - - 4d29ecdf by sheaf at 2023-05-15T18:03:00-04:00 Migrate errors to diagnostics in GHC.Tc.Module This commit migrates the errors in GHC.Tc.Module to use the new diagnostic infrastructure. It required a significant overhaul of the compatibility checks between an hs-boot or signature module and its implementation; we now use a Writer monad to accumulate errors; see the BootMismatch datatype in GHC.Tc.Errors.Types, with its panoply of subtypes. For the sake of readability, several local functions inside the 'checkBootTyCon' function were split off into top-level functions. We split off GHC.Types.HscSource into a "boot or sig" vs "normal hs file" datatype, as this mirrors the logic in several other places where we want to treat hs-boot and hsig files in a similar fashion. This commit also refactors the Backpack checks for type synonyms implementing abstract data, to correctly reject implementations that contain qualified or quantified types (this fixes #23342 and #23344). - - - - - d986c98e by Rodrigo Mesquita at 2023-05-16T00:14:04-04:00 configure: Drop unused AC_PROG_CPP In configure, we were calling `AC_PROG_CPP` but never making use of the $CPP variable it sets or reads. The issue is $CPP will show up in the --help output of configure, falsely advertising a configuration option that does nothing. The reason we don't use the $CPP variable is because HS_CPP_CMD is expected to be a single command (without flags), but AC_PROG_CPP, when CPP is unset, will set said variable to something like `/usr/bin/gcc -E`. Instead, we configure HS_CPP_CMD through $CC. - - - - - a8f0435f by Cheng Shao at 2023-05-16T00:14:42-04:00 rts: fix --disable-large-address-space This patch moves ACQUIRE_ALLOC_BLOCK_SPIN_LOCK/RELEASE_ALLOC_BLOCK_SPIN_LOCK from Storage.h to HeapAlloc.h. When --disable-large-address-space is passed to configure, the code in HeapAlloc.h makes use of these two macros. Fixes #23385. - - - - - bdb93cd2 by Oleg Grenrus at 2023-05-16T07:59:21+03:00 Add -Wmissing-role-annotations Implements #22702 - - - - - 41ecfc34 by Ben Gamari at 2023-05-16T07:28:15-04:00 base: Export {get,set}ExceptionFinalizer from System.Mem.Weak As proposed in CLC Proposal #126 [1]. [1]: https://github.com/haskell/core-libraries-committee/issues/126 - - - - - 67330303 by Ben Gamari at 2023-05-16T07:28:16-04:00 base: Introduce printToHandleFinalizerExceptionHandler - - - - - 5e3f9bb5 by Josh Meredith at 2023-05-16T13:59:22-04:00 JS: Implement h$clock_gettime in the JavaScript RTS (#23360) - - - - - 90e69d5d by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation for SourceText SourceText is serialized along with INLINE pragmas into interface files. Many of these SourceTexts are identical, for example "{-# INLINE#". When deserialized, each such SourceText was previously expanded out into a [Char], which is highly wasteful of memory, and each such instance of the text would allocate an independent list with its contents as deserializing breaks any sharing that might have existed. Instead, we use a `FastString` to represent these, so that each instance unique text will be interned and stored in a memory efficient manner. - - - - - b70bc690 by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation/FastStrings for `SourceNote`s `SourceNote`s should not be stored as [Char] as this is highly wasteful and in certain scenarios can be highly duplicated. Metric Decrease: hard_hole_fits - - - - - 6231a126 by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation for UsageFile (#22744) Use FastString to store filepaths in interface files, as this data is highly redundant so we want to share all instances of filepaths in the compiler session. - - - - - 47a58150 by Zubin Duggal at 2023-05-16T14:00:00-04:00 testsuite: add test for T22744 This test checks for #22744 by compiling 100 modules which each have a dependency on 1000 distinct external files. Previously, when loading these interfaces from disk, each individual instance of a filepath in the interface will would be allocated as an individual object on the heap, meaning we have heap objects for 100*1000 files, when there are only 1000 distinct files we care about. This test checks this by first compiling the module normally, then measuring the peak memory usage in a no-op recompile, as the recompilation checking will force the allocation of all these filepaths. - - - - - 0451bdc9 by Ben Gamari at 2023-05-16T21:31:40-04:00 users guide: Add glossary Currently this merely explains the meaning of "technology preview" in the context of released features. - - - - - 0ba52e4e by Ben Gamari at 2023-05-16T21:31:40-04:00 Update glossary.rst - - - - - 3d23060c by Ben Gamari at 2023-05-16T21:31:40-04:00 Use glossary directive - - - - - 2972fd66 by Sylvain Henry at 2023-05-16T21:32:20-04:00 JS: fix getpid (fix #23399) - - - - - 5fe1d3e6 by Matthew Pickering at 2023-05-17T21:42:00-04:00 Use setSrcSpan rather than setLclEnv in solveForAll In subsequent MRs (#23409) we want to remove the TcLclEnv argument from a CtLoc. This MR prepares us for that by removing the one place where the entire TcLclEnv is used, by using it more precisely to just set the contexts source location. Fixes #23390 - - - - - 385edb65 by Torsten Schmits at 2023-05-17T21:42:40-04:00 Update the users guide paragraph on -O in GHCi In relation to #23056 - - - - - 87626ef0 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Add test for #13660 - - - - - 9eef53b1 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Move implementation of GHC.Foreign to GHC.Internal - - - - - 174ea2fa by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Introduce {new,with}CStringLen0 These are useful helpers for implementing the internal-NUL code unit check needed to fix #13660. - - - - - a46ced16 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Clean up documentation - - - - - b98d99cc by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Ensure that FilePaths don't contain NULs POSIX filepaths may not contain the NUL octet but previously we did not reject such paths. This could be exploited by untrusted input to cause discrepancies between various `FilePath` queries and the opened filename. For instance, `readFile "hello.so\x00.txt"` would open the file `"hello.so"` yet `takeFileExtension` would return `".txt"`. The same argument applies to Windows FilePaths Fixes #13660. - - - - - 7ae45459 by Simon Peyton Jones at 2023-05-18T15:19:29-04:00 Allow the demand analyser to unpack tuple and equality dictionaries Addresses #23398. The demand analyser usually does not unpack class dictionaries: see Note [Do not unbox class dictionaries] in GHC.Core.Opt.DmdAnal. This patch makes an exception for tuple dictionaries and equality dictionaries, for reasons explained in wrinkles (DNB1) and (DNB2) of the above Note. Compile times fall by 0.1% for some reason (max 0.7% on T18698b). - - - - - b53a9086 by Greg Steuck at 2023-05-18T15:20:08-04:00 Use a simpler and more portable construct in ld.ldd check printf '%q\n' is a bash extension which led to incorrectly failing an ld.lld test on OpenBSD which uses pdksh as /bin/sh - - - - - dd5710af by Torsten Schmits at 2023-05-18T15:20:50-04:00 Update the warning about interpreter optimizations to reflect that they're not incompatible anymore, but guarded by a flag - - - - - 4f6dd999 by Matthew Pickering at 2023-05-18T15:21:26-04:00 Remove stray dump flags in GHC.Rename.Names - - - - - 4bca0486 by Oleg Grenrus at 2023-05-19T11:51:33+03:00 Make Warn = Located DriverMessage This change makes command line argument parsing use diagnostic framework for producing warnings. - - - - - 525ed554 by Simon Peyton Jones at 2023-05-19T10:09:15-04:00 Type inference for data family newtype instances This patch addresses #23408, a tricky case with data family newtype instances. Consider type family TF a where TF Char = Bool data family DF a newtype instance DF Bool = MkDF Int and [W] Int ~R# DF (TF a), with a Given (a ~# Char). We must fully rewrite the Wanted so the tpye family can fire; that wasn't happening. - - - - - c6fb6690 by Peter Trommler at 2023-05-20T03:16:08-04:00 testsuite: fix predicate on rdynamic test Test rdynamic requires dynamic linking support, which is orthogonal to RTS linker support. Change the predicate accordingly. Fixes #23316 - - - - - 735d504e by Matthew Pickering at 2023-05-20T03:16:44-04:00 docs: Use ghc-ticket directive where appropiate in users guide Using the directive automatically formats and links the ticket appropiately. - - - - - b56d7379 by Sylvain Henry at 2023-05-22T14:21:22-04:00 NCG: remove useless .align directive (#20758) - - - - - 15b93d2f by Simon Peyton Jones at 2023-05-22T14:21:58-04:00 Add test for #23156 This program had exponential typechecking time in GHC 9.4 and 9.6 - - - - - 2b53f206 by Greg Steuck at 2023-05-22T20:23:11-04:00 Revert "Change hostSupportsRPaths to report False on OpenBSD" This reverts commit 1e0d8fdb55a38ece34fa6cf214e1d2d46f5f5bf2. - - - - - 882e43b7 by Greg Steuck at 2023-05-22T20:23:11-04:00 Disable T17414 on OpenBSD Like on other systems it's not guaranteed that there's sufficient space in /tmp to write 2G out. - - - - - 9d531f9a by Greg Steuck at 2023-05-22T20:23:11-04:00 Bring back getExecutablePath to getBaseDir on OpenBSD Fix #18173 - - - - - 9db0eadd by Krzysztof Gogolewski at 2023-05-22T20:23:47-04:00 Add an error origin for impedance matching (#23427) - - - - - 33cf4659 by Ben Gamari at 2023-05-23T03:46:20-04:00 testsuite: Add tests for #23146 Both lifted and unlifted variants. - - - - - 76727617 by Ben Gamari at 2023-05-23T03:46:21-04:00 codeGen: Fix some Haddocks - - - - - 33a8c348 by Ben Gamari at 2023-05-23T03:46:21-04:00 codeGen: Give proper LFInfo to datacon wrappers As noted in `Note [Conveying CAF-info and LFInfo between modules]`, when importing a binding from another module we must ensure that it gets the appropriate `LambdaFormInfo` if it is in WHNF to ensure that references to it are tagged correctly. However, the implementation responsible for doing this, `GHC.StgToCmm.Closure.mkLFImported`, only dealt with datacon workers and not wrappers. This lead to the crash of this program in #23146: module B where type NP :: [UnliftedType] -> UnliftedType data NP xs where UNil :: NP '[] module A where import B fieldsSam :: NP xs -> NP xs -> Bool fieldsSam UNil UNil = True x = fieldsSam UNil UNil Due to its GADT nature, `UNil` produces a trivial wrapper $WUNil :: NP '[] $WUNil = UNil @'[] @~(<co:1>) which is referenced in the RHS of `A.x`. Due to the above-mentioned bug in `mkLFImported`, the references to `$WUNil` passed to `fieldsSam` were not tagged. This is problematic as `fieldsSam` expected its arguments to be tagged as they are unlifted. The fix is straightforward: extend the logic in `mkLFImported` to cover (nullary) datacon wrappers as well as workers. This is safe because we know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). Thanks to @MangoIV for the great ticket and @alt-romes for his minimization and help debugging. Fixes #23146. - - - - - 2fc18e9e by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 0598f7f0 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 12294b22 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Update Note [Core letrec invariant] Authored by @simonpj - - - - - e93ab972 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Rename mkLFImported to importedIdLFInfo The `mkLFImported` sounded too much like a constructor of sorts, when really it got the `LFInfo` of an imported Id from its `lf_info` field when this existed, and otherwise returned a conservative estimate of that imported Id's LFInfo. This in contrast to functions such as `mkLFReEntrant` which really are about constructing an `LFInfo`. - - - - - e54d9259 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Enforce invariant on typePrimRepArgs in the types As part of the documentation effort in !10165 I came across this invariant on 'typePrimRepArgs' which is easily expressed at the type-level through a NonEmpty list. It allowed us to remove one panic. - - - - - b8fe6a0c by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Merge outdated Note [Data con representation] into Note [Data constructor representation] Introduce new Note [Constructor applications in STG] to better support the merge, and reference it from the relevant bits in the STG syntax. - - - - - e1590ddc by Simon Peyton Jones at 2023-05-23T03:46:57-04:00 Add the SolverStage monad This refactoring makes a substantial improvement in the structure of the type-checker's constraint solver: #23070. Specifically: * Introduced the SolverStage monad. See GHC.Tc.Solver.Monad Note [The SolverStage monad] * Make each solver pipeline (equalities, dictionaries, irreds etc) deal with updating the inert set, as a separate SolverStage. There is sometimes special stuff to do, and it means that each full pipeline can have type SolverStage Void, indicating that they never return anything. * Made GHC.Tc.Solver.Equality.zonkEqTypes into a SolverStage. Much nicer. * Combined the remnants of GHC.Tc.Solver.Canonical and GHC.Tc.Solver.Interact into a new module GHC.Tc.Solver.Solve. (Interact and Canonical are removed.) * Gave the same treatment to dictionary and irred constraints as I have already done for equality constraints: * New types (akin to EqCt): IrredCt and DictCt * Ct is now just a simple sum type data Ct = CDictCan DictCt | CIrredCan IrredCt | CEqCan EqCt | CQuantCan QCInst | CNonCanonical CtEvidence * inert_dicts can now have the better type DictMap DictCt, instead of DictMap Ct; and similarly inert_irreds. * Significantly simplified the treatment of implicit parameters. Previously we had a number of special cases * interactGivenIP, an entire function * special case in maybeKickOut * special case in findDict, when looking up dictionaries But actually it's simpler than that. When adding a new Given, implicit parameter constraint to the InertSet, we just need to kick out any existing inert constraints that mention that implicit parameter. The main work is done in GHC.Tc.Solver.InertSet.delIPDict, along with its auxiliary GHC.Core.Predicate.mentionsIP. See Note [Shadowing of implicit parameters] in GHC.Tc.Solver.Dict. * Add a new fast-path in GHC.Tc.Errors.Hole.tcCheckHoleFit. See Note [Fast path for tcCheckHoleFit]. This is a big win in some cases: test hard_hole_fits gets nearly 40% faster (at compile time). * Add a new fast-path for solving /boxed/ equality constraints (t1 ~ t2). See Note [Solving equality classes] in GHC.Tc.Solver.Dict. This makes a big difference too: test T17836 compiles 40% faster. * Implement the PermissivePlan of #23413, which concerns what happens with insoluble Givens. Our previous treatment was wildly inconsistent as that ticket pointed out. A part of this, I simplified GHC.Tc.Validity.checkAmbiguity: now we simply don't run the ambiguity check at all if -XAllowAmbiguousTypes is on. Smaller points: * In `GHC.Tc.Errors.misMatchOrCND` instead of having a special case for insoluble /occurs/ checks, broaden in to all insouluble constraints. Just generally better. See Note [Insoluble mis-match] in that module. As noted above, compile time perf gets better. Here are the changes over 0.5% on Fedora. (The figures are slightly larger on Windows for some reason.) Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -0.9% MultiLayerModulesTH_OneShot(normal) +0.5% T11822(normal) -0.6% T12227(normal) -1.8% GOOD T12545(normal) -0.5% T13035(normal) -0.6% T15703(normal) -1.4% GOOD T16875(normal) -0.5% T17836(normal) -40.7% GOOD T17836b(normal) -12.3% GOOD T17977b(normal) -0.5% T5837(normal) -1.1% T8095(normal) -2.7% GOOD T9020(optasm) -1.1% hard_hole_fits(normal) -37.0% GOOD geo. mean -1.3% minimum -40.7% maximum +0.5% Metric Decrease: T12227 T15703 T17836 T17836b T8095 hard_hole_fits LargeRecord T9198 T13035 - - - - - 6abf3648 by Simon Peyton Jones at 2023-05-23T03:46:57-04:00 Avoid an assertion failure in abstractFloats The function GHC.Core.Opt.Simplify.Utils.abstractFloats was carelessly calling lookupIdSubst_maybe on a CoVar; but a precondition of the latter is being given an Id. In fact it's harmless to call it on a CoVar, but still, the precondition on lookupIdSubst_maybe makes sense, so I added a test for CoVars. This avoids a crash in a DEBUG compiler, but otherwise has no effect. Fixes #23426. - - - - - 838aaf4b by hainq at 2023-05-24T12:41:19-04:00 Migrate errors in GHC.Tc.Validity This patch migrates the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It adds the constructors: - TcRnSimplifiableConstraint - TcRnArityMismatch - TcRnIllegalInstanceDecl, with sub-datatypes for HasField errors and fundep coverage condition errors. - - - - - 8539764b by Krzysztof Gogolewski at 2023-05-24T12:41:56-04:00 linear lint: Add missing processing of DEFAULT In this correct program f :: a %1 -> a f x = case x of x { _DEFAULT -> x } after checking the alternative we weren't popping the case binder 'x' from the usage environment, which meant that the lambda-bound 'x' was counted twice: in the scrutinee and (incorrectly) in the alternative. In fact, we weren't checking the usage of 'x' at all. Now the code for handling _DEFAULT is similar to the one handling data constructors. Fixes #23025. - - - - - ae683454 by Matthew Pickering at 2023-05-24T12:42:32-04:00 Remove outdated "Don't check hs-boot type family instances too early" note This note was introduced in 25b70a29f623 which delayed performing some consistency checks for type families. However, the change was reverted later in 6998772043a7f0b0360116eb5ffcbaa5630b21fb but the note was not removed. I found it confusing when reading to code to try and work out what special behaviour there was for hs-boot files (when in-fact there isn't any). - - - - - 44af57de by Matthew Pickering at 2023-05-24T12:43:08-04:00 rts: Define ticky macro stubs These macros have long been undefined which has meant we were missing reporting these allocations in ticky profiles. The most critical missing definition was TICK_ALLOC_HEAP_NOCTR which was missing all the RTS calls to allocate, this leads to a the overall ALLOC_RTS_tot number to be severaly underreported. Of particular interest though is the ALLOC_STACK_ctr and ALLOC_STACK_tot counters which are useful to tracking stack allocations. Fixes #23421 - - - - - b2dabe3a by Matthew Pickering at 2023-05-24T12:43:08-04:00 rts: ticky: Rename TICK_ALLOC_HEAP_NOCTR to TICK_ALLOC_RTS This macro increments the ALLOC_HEAP_tot and ALLOC_HEAP_ctr so it makes more sense to name it after that rather than the suffix NOCTR, whose meaning has been lost to the mists of time. - - - - - eac4420a by Ben Gamari at 2023-05-24T12:43:45-04:00 users guide: A few small mark-up fixes - - - - - a320ca76 by Rodrigo Mesquita at 2023-05-24T12:44:20-04:00 configure: Fix support check for response files. In failing to escape the '-o' in '-o\nconftest\nconftest.o\n' argument to printf, the writing of the arguments response file always failed. The fix is to pass the arguments after `--` so that they are treated positional arguments rather than flags to printf. Closes #23435 - - - - - f21ce0e4 by mangoiv at 2023-05-24T12:45:00-04:00 [feat] add .direnv to the .gitignore file - - - - - 36d5944d by Andrew Lelechenko at 2023-05-24T20:58:34-04:00 Add Data.List.unsnoc See https://github.com/haskell/core-libraries-committee/issues/165 for discussion - - - - - c0f2f9e3 by Bartłomiej Cieślar at 2023-05-24T20:59:14-04:00 Fix crash in backpack signature merging with -ddump-rn-trace In some cases, backpack signature merging could crash in addUsedGRE when -ddump-rn-trace was enabled, as pretty-printing the GREInfo would cause unavailable interfaces to be loaded. This commit fixes that issue by not pretty-printing the GREInfo in addUsedGRE when -ddump-rn-trace is enabled. Fixes #23424 Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - 5a07d94a by Krzysztof Gogolewski at 2023-05-25T03:30:20-04:00 Add a regression test for #13981 The panic was fixed by 6998772043a7f0b. Fixes #13981. - - - - - 182df90e by Krzysztof Gogolewski at 2023-05-25T03:30:57-04:00 Add a test for #23355 It was fixed by !10061, so I'm adding it in the same group. - - - - - 1b31b039 by uhbif19 at 2023-05-25T12:08:28+02:00 Migrate errors in GHC.Rename.Splice GHC.Rename.Pat This commit migrates the errors in GHC.Rename.Splice and GHC.Rename.Pat to use the new diagnostic infrastructure. - - - - - 56abe494 by sheaf at 2023-05-25T12:09:55+02:00 Common up Template Haskell errors in TcRnMessage This commit commons up the various Template Haskell errors into a single constructor, TcRnTHError, of TcRnMessage. - - - - - a487ba9e by Krzysztof Gogolewski at 2023-05-25T14:35:56-04:00 Enable ghci tests for unboxed tuples The tests were originally skipped because ghci used not to support unboxed tuples/sums. - - - - - dc3422d4 by Matthew Pickering at 2023-05-25T18:57:19-04:00 rts: Build ticky GHC with single-threaded RTS The threaded RTS allows you to use ticky profiling but only for the counters in the generated code. The counters used in the C portion of the RTS are disabled. Updating the counters is also racy using the threaded RTS which can lead to misleading or incorrect ticky results. Therefore we change the hadrian flavour to build using the single-threaded RTS (mainly in order to get accurate C code counter increments) Fixes #23430 - - - - - fbc8e04e by sheaf at 2023-05-25T18:58:00-04:00 Propagate long-distance info in generated code When desugaring generated pattern matches, we skip pattern match checks. However, this ended up also discarding long-distance information, which might be needed for user-written sub-expressions. Example: ```haskell okay (GADT di) cd = let sr_field :: () sr_field = case getFooBar di of { Foo -> () } in case cd of { SomeRec _ -> SomeRec sr_field } ``` With sr_field a generated FunBind, we still want to propagate the outer long-distance information from the GADT pattern match into the checks for the user-written RHS of sr_field. Fixes #23445 - - - - - f8ced241 by Matthew Pickering at 2023-05-26T15:26:21-04:00 Introduce GHCiMessage to wrap GhcMessage By introducing a wrapped message type we can control how certain messages are printed in GHCi (to add extra information for example) - - - - - 58e554c1 by Matthew Pickering at 2023-05-26T15:26:22-04:00 Generalise UnknownDiagnostic to allow embedded diagnostics to access parent diagnostic options. * Split default diagnostic options from Diagnostic class into HasDefaultDiagnosticOpts class. * Generalise UnknownDiagnostic to allow embedded diagnostics to access options. The principle idea here is that when wrapping an error message (such as GHCMessage to make GHCiMessage) then we need to also be able to lift the configuration when overriding how messages are printed (see load' for an example). - - - - - b112546a by Matthew Pickering at 2023-05-26T15:26:22-04:00 Allow API users to wrap error messages created during 'load' This allows API users to configure how messages are rendered when they are emitted from the load function. For an example see how 'loadWithCache' is used in GHCi. - - - - - 2e4cf0ee by Matthew Pickering at 2023-05-26T15:26:22-04:00 Abstract cantFindError and turn Opt_BuildingCabal into a print-time option * cantFindError is abstracted so that the parts which mention specific things about ghc/ghci are parameters. The intention being that GHC/GHCi can specify the right values to put here but otherwise display the same error message. * The BuildingCabalPackage argument from GenericMissing is removed and turned into a print-time option. The reason for the error is not dependent on whether `-fbuilding-cabal-package` is passed, so we don't want to store that in the error message. - - - - - 34b44f7d by Matthew Pickering at 2023-05-26T15:26:22-04:00 error messages: Don't display ghci specific hints for missing packages Tickets like #22884 suggest that it is confusing that GHC used on the command line can suggest options which only work in GHCi. This ticket uses the error message infrastructure to override certain error messages which displayed GHCi specific information so that this information is only showed when using GHCi. The main annoyance is that we mostly want to display errors in the same way as before, but with some additional information. This means that the error rendering code has to be exported from the Iface/Errors/Ppr.hs module. I am unsure about whether the approach taken here is the best or most maintainable solution. Fixes #22884 - - - - - 05a1b626 by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Don't override existing metadata if version already exists. If a nightly pipeline runs twice for some reason for the same version then we really don't want to override an existing entry with new bindists. This could cause ABI compatability issues for users or break ghcup's caching logic. - - - - - fcbcb3cc by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Use proper API url for bindist download Previously we were using links from the web interface, but it's more robust and future-proof to use the documented links to the artifacts. https://docs.gitlab.com/ee/api/job_artifacts.html - - - - - 5b59c8fe by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Set Nightly and LatestNightly tags The latest nightly release needs the LatestNightly tag, and all other nightly releases need the Nightly tag. Therefore when the metadata is updated we need to replace all LatestNightly with Nightly.` - - - - - 914e1468 by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Download nightly metadata for correct date The metadata now lives in https://gitlab.haskell.org/ghc/ghcup-metadata with one metadata file per year. When we update the metadata we download and update the right file for the current year. - - - - - 16cf7d2e by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Download metadata and update for correct year something about pipeline date - - - - - 14792c4b by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Don't skip CI On a push we now have a CI job which updates gitlab pages with the metadata files. - - - - - 1121bdd8 by Matthew Pickering at 2023-05-26T15:26:59-04:00 ghcup-metadata: Add --date flag to specify the release date The ghcup-metadata now has a viReleaseDay field which needs to be populated with the day of the release. - - - - - bc478bee by Matthew Pickering at 2023-05-26T15:26:59-04:00 ghcup-metadata: Add dlOutput field ghcup now requires us to add this field which specifies where it should download the bindist to. See https://gitlab.haskell.org/ghc/ghcup-metadata/-/issues/1 for some more discussion. - - - - - 2bdbd9da by Josh Meredith at 2023-05-26T15:27:35-04:00 JS: Convert rendering to use HLine instead of SDoc (#22455) - - - - - abd9e37c by Norman Ramsey at 2023-05-26T15:28:12-04:00 testsuite: add WasmControlFlow test This patch adds the WasmControlFlow test to test the wasm backend's relooper component. - - - - - 07f858eb by Sylvain Henry at 2023-05-26T15:28:53-04:00 Factorize getLinkDeps Prepare reuse of getLinkDeps for TH implementation in the JS backend (cf #22261 and review of !9779). - - - - - fad9d092 by Oleg Grenrus at 2023-05-27T13:38:08-04:00 Change GHC.Driver.Session import to .DynFlags Also move targetPlatform selector Plenty of GHC needs just DynFlags. Even more can be made to use .DynFlags if more selectors is migrated. This is a low hanging fruit. - - - - - 69fdbece by Alan Zimmerman at 2023-05-27T13:38:45-04:00 EPA: Better fix for #22919 The original fix for #22919 simply removed the ability to match up prior comments with the first declaration in the file. Restore it, but add a check that the comment is on a single line, by ensuring that it comes immediately prior to the next thing (comment or start of declaration), and that the token preceding it is not on the same line. closes #22919 - - - - - 0350b186 by Josh Meredith at 2023-05-29T12:46:27+00:00 Remove JavaScriptFFI from --supported-extensions for non-JS targets (#11214) - - - - - b4816919 by Matthew Pickering at 2023-05-30T17:07:43-04:00 testsuite: Pass -kb16k -kc128k for performance tests Setting a larger stack chunk size gives a greater protection from stack thrashing (where the repeated overflow/underflow allocates a lot of stack chunks which sigificantly impact allocations). This stabilises some tests against differences cause by more things being pushed onto the stack. The performance tests are generally testing work done by the compiler, using allocation as a proxy, so removing/stabilising the allocations due to the stack gives us more stable tests which are also more sensitive to actual changes in compiler performance. The tests which increase are ones where we compile a lot of modules, and for each module we spawn a thread to compile the module in. Therefore increasing these numbers has a multiplying effect on these tests because there are many more stacks which we can increase in size. The most significant improvements though are cases such as T8095 which reduce significantly in allocations (30%). This isn't a performance improvement really but just helps stabilise the test against this threshold set by the defaults. Fixes #23439 ------------------------- Metric Decrease: InstanceMatching T14683 T8095 T9872b_defer T9872d T9961 hie002 T19695 T3064 Metric Increase: MultiLayerModules T13701 T14697 ------------------------- - - - - - 6629f1c5 by Ben Gamari at 2023-05-30T17:08:20-04:00 Move via-C flags into GHC These were previously hardcoded in configure (with no option for overriding them) and simply passed onto ghc through the settings file. Since configure already guarantees gcc supports those flags, we simply move them into GHC. - - - - - 981e5e11 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00 Allow CPR on unrestricted constructors Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will allow CPR to handle `Ur`, in particular. - - - - - bf9344d2 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00 Push coercions across multiplicity boundaries Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will avoid preventing inlinings and reductions and make linear programs more efficient. - - - - - d56dd695 by sheaf at 2023-05-31T11:37:12-04:00 Data.Bag: add INLINEABLE to polymorphic functions This commit allows polymorphic methods in GHC.Data.Bag to be specialised, avoiding having to pass explicit dictionaries when they are instantiated with e.g. a known monad. - - - - - 5366cd35 by sheaf at 2023-05-31T11:37:12-04:00 Split off TcBinderStack into its own module This commit splits off TcBinderStack into its own module, to avoid module cycles: we might want to refer to it without also pulling in the TcM monad. - - - - - 09d4d307 by sheaf at 2023-05-31T11:37:12-04:00 Split off TcRef into its own module This helps avoid pull in the full TcM monad when we just want access to mutable references in the typechecker. This facilitates later patches which introduce a slimmed down TcM monad for zonking. - - - - - 88cc19b3 by sheaf at 2023-05-31T11:37:12-04:00 Introduce Codensity monad The Codensity monad is useful to write state-passing computations in continuation-passing style, e.g. to implement a State monad as continuation-passing style over a Reader monad. - - - - - f62d8195 by sheaf at 2023-05-31T11:37:12-04:00 Restructure the zonker This commit splits up the zonker into a few separate components, described in Note [The structure of the zonker] in `GHC.Tc.Zonk.Type`. 1. `GHC.Tc.Zonk.Monad` introduces a pared-down `TcM` monad, `ZonkM`, which has enough information for zonking types. This allows us to refactor `ErrCtxt` to use `ZonkM` instead of `TcM`, which guarantees we don't throw an error while reporting an error. 2. `GHC.Tc.Zonk.Env` is the new home of `ZonkEnv`, and also defines two zonking monad transformers, `ZonkT` and `ZonkBndrT`. `ZonkT` is a reader monad transformer over `ZonkEnv`. `ZonkBndrT m` is the codensity monad over `ZonkT m`. `ZonkBndrT` is used for computations that accumulate binders in the `ZonkEnv`. 3. `GHC.Tc.Zonk.TcType` contains the code for zonking types, for use in the typechecker. It uses the `ZonkM` monad. 4. `GHC.Tc.Zonk.Type` contains the code for final zonking to `Type`, which has been refactored to use `ZonkTcM = ZonkT TcM` and `ZonkBndrTcM = ZonkBndrT TcM`. Allocations slightly decrease on the whole due to using continuation-passing style instead of manual state passing of ZonkEnv in the final zonking to Type. ------------------------- Metric Decrease: T4029 T8095 T14766 T15304 hard_hole_fits RecordUpdPerf Metric Increase: T10421 ------------------------- - - - - - 70526f5b by mimi.vx at 2023-05-31T11:37:53-04:00 Update rdt-theme to latest upstream version Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/23444 - - - - - f3556d6c by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Restructure IPE buffer layout Reference ticket #21766 This commit restructures IPE buffer list entries to not contain references to their corresponding info tables. IPE buffer list nodes now point to two lists of equal length, one holding the list of info table pointers and one holding the corresponding entries for each info table. This will allow the entry data to be compressed without losing the references to the info tables. - - - - - 5d1f2411 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add IPE compression to configure Reference ticket #21766 Adds an `--enable-ipe-data-compreesion` flag to the configure script which will check for libzstd and set the appropriate flags to allow for IPE data compression in the compiler - - - - - b7a640ac by Finley McIlwaine at 2023-06-01T04:53:12-04:00 IPE data compression Reference ticket #21766 When IPE data compression is enabled, compress the emitted IPE buffer entries and decompress them in the RTS. - - - - - 5aef5658 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix libzstd detection in configure and RTS Ensure that `HAVE_LIBZSTD` gets defined to either 0 or 1 in all cases and properly check that before IPE data decompression in the RTS. See ticket #21766. - - - - - 69563c97 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add note describing IPE data compression See ticket #21766 - - - - - 7872e2b6 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix byte order of IPE data, fix IPE tests Make sure byte order of written IPE buffer entries matches target. Make sure the IPE-related tests properly access the fields of IPE buffer entry nodes with the new IPE layout. This commit also introduces checks to avoid importing modules if IPE compression is not enabled. See ticket #21766. - - - - - 0e85099b by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix IPE data decompression buffer allocation Capacity of buffers allocated for decompressed IPE data was incorrect due to a misuse of the `ZSTD_findFrameCompressedSize` function. Fix by always storing decompressed size of IPE data in IPE buffer list nodes and using `ZSTD_findFrameCompressedSize` to determine the size of the compressed data. See ticket #21766 - - - - - a0048866 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add optional dependencies to ./configure output Changes the configure script to indicate whether libnuma, libzstd, or libdw are being used as dependencies due to their optional features being enabled. - - - - - 09d93bd0 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add IPE-enabled builds to CI - Adds an IPE job to the CI pipeline which is triggered by the ~IPE label - Introduces CI logic to enable IPE data compression - Enables uncompressed IPE data on debug CI job - Regenerates jobs.yaml MR https://gitlab.haskell.org/ghc/ci-images/-/merge_requests/112 on the images repository is meant to ensure that the proper images have libzstd-dev installed. - - - - - 3ded9a1c by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Update user's guide and release notes, small fixes Add mention of IPE data compression to user's guide and the release notes for 9.8.1. Also note the impact compression has on binary size in both places. Change IpeBufferListNode compression check so only the value `1` indicates compression. See ticket #21766 - - - - - 41b41577 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Remove IPE enabled builds from CI We don't need to explicitly specify the +ipe transformer to test IPE data since there are tests which manually enable IPE information. This commit does leave zstd IPE data compression enabled on the debian CI jobs. - - - - - 982bef3a by Krzysztof Gogolewski at 2023-06-01T04:53:49-04:00 Fix build with 9.2 GHC.Tc.Zonk.Type uses an equality constraint. ghc.nix currently provides 9.2. - - - - - 1c96bc3d by Krzysztof Gogolewski at 2023-06-01T10:56:11-04:00 Output Lint errors to stderr instead of stdout This is a continuation of 7b095b99, which fixed warnings but not errors. Refs #13342 - - - - - 8e81f140 by sheaf at 2023-06-01T10:56:51-04:00 Refactor lookupExactOrOrig & friends This refactors the panoply of renamer lookup functions relating to lookupExactOrOrig to more graciously handle Exact and Orig names. In particular, we avoid the situation in which we would add Exact/Orig GREs to the tcg_used_gres field, which could cause a panic in bestImport like in #23240. Fixes #23428 - - - - - 5d415bfd by Krzysztof Gogolewski at 2023-06-01T10:57:31-04:00 Use the one-shot trick for UM and RewriteM functors As described in Note [The one-shot state monad trick], we shouldn't use derived Functor instances for monads using one-shot. This was done for most of them, but UM and RewriteM were missed. - - - - - 2c38551e by Krzysztof Gogolewski at 2023-06-01T10:58:08-04:00 Fix testsuite skipping Lint setTestOpts() is used to modify the test options for an entire .T file, rather than a single test. If there was a test using collect_compiler_stats, all of the tests in the same file had lint disabled. Fixes #21247 - - - - - 00a1e50b by Krzysztof Gogolewski at 2023-06-01T10:58:44-04:00 Add testcases for already fixed #16432 They were fixed by 40c7daed0. Fixes #16432 - - - - - f6e060cc by Krzysztof Gogolewski at 2023-06-02T09:07:25-04:00 cleanup: Remove unused field from SelfBoot It is no longer needed since Note [Extra dependencies from .hs-boot files] was deleted in 6998772043. I've also added tildes to Note headers, otherwise they're not detected by the linter. - - - - - 82eacab6 by sheaf at 2023-06-02T09:08:01-04:00 Delete GHC.Tc.Utils.Zonk This module was split up into GHC.Tc.Zonk.Type and GHC.Tc.Zonk.TcType in commit f62d8195, but I forgot to delete the original module - - - - - 4a4eb761 by Ben Gamari at 2023-06-02T23:53:21-04:00 base: Add build-order import of GHC.Types in GHC.IO.Handle.Types For reasons similar to those described in Note [Depend on GHC.Num.Integer]. Fixes #23411. - - - - - f53ac0ae by Sylvain Henry at 2023-06-02T23:54:01-04:00 JS: fix and enhance non-minimized code generation (#22455) Flag -ddisable-js-minimizer was producing invalid code. Fix that and also a few other things to generate nicer JS code for debugging. The added test checks that we don't regress when using the flag. - - - - - f7744e8e by Andrey Mokhov at 2023-06-03T16:49:44-04:00 [hadrian] Fix multiline synopsis rendering - - - - - b2c745db by Andrew Lelechenko at 2023-06-03T16:50:23-04:00 Elaborate on performance properties of Data.List.++ - - - - - 7cd8a61e by Matthew Pickering at 2023-06-05T11:46:23+01:00 Big TcLclEnv and CtLoc refactoring The overall goal of this refactoring is to reduce the dependency footprint of the parser and syntax tree. Good reasons include: - Better module graph parallelisability - Make it easier to migrate error messages without introducing module loops - Philosophically, there's not reason for the AST to depend on half the compiler. One of the key edges which added this dependency was > GHC.Hs.Expr -> GHC.Tc.Types (TcLclEnv) As this in turn depending on TcM which depends on HscEnv and so on. Therefore the goal of this patch is to move `TcLclEnv` out of `GHC.Tc.Types` so that `GHC.Hs.Expr` can import TcLclEnv without incurring a huge dependency chain. The changes in this patch are: * Move TcLclEnv from GHC.Tc.Types to GHC.Tc.Types.LclEnv * Create new smaller modules for the types used in TcLclEnv New Modules: - GHC.Tc.Types.ErrCtxt - GHC.Tc.Types.BasicTypes - GHC.Tc.Types.TH - GHC.Tc.Types.LclEnv - GHC.Tc.Types.CtLocEnv - GHC.Tc.Errors.Types.PromotionErr Removed Boot File: - {-# SOURCE #-} GHC.Tc.Types * Introduce TcLclCtxt, the part of the TcLclEnv which doesn't participate in restoreLclEnv. * Replace TcLclEnv in CtLoc with specific CtLocEnv which is defined in GHC.Tc.Types.CtLocEnv. Use CtLocEnv in Implic and CtLoc to record the location of the implication and constraint. By splitting up TcLclEnv from GHC.Tc.Types we allow GHC.Hs.Expr to no longer depend on the TcM monad and all that entails. Fixes #23389 #23409 - - - - - 3d8d39d1 by Matthew Pickering at 2023-06-05T11:46:23+01:00 Remove dependency of GHC.Tc.Utils.TcType on GHC.Driver.Session This removes the usage of DynFlags from Tc.Utils.TcType so that it no longer depends on GHC.Driver.Session. In general we don't want anything which is a dependency of Language.Haskell.Syntax to depend on GHC.Driver.Session and removing this edge gets us closer to that goal. - - - - - 18db5ada by Matthew Pickering at 2023-06-05T11:46:23+01:00 Move isIrrefutableHsPat to GHC.Rename.Utils and rename to isIrrefutableHsPatRn This removes edge from GHC.Hs.Pat to GHC.Driver.Session, which makes Language.Haskell.Syntax end up depending on GHC.Driver.Session. - - - - - 12919dd5 by Matthew Pickering at 2023-06-05T11:46:23+01:00 Remove dependency of GHC.Tc.Types.Constraint on GHC.Driver.Session - - - - - eb852371 by Matthew Pickering at 2023-06-05T11:46:24+01:00 hole fit plugins: Split definition into own module The hole fit plugins are defined in terms of TcM, a type we want to avoid depending on from `GHC.Tc.Errors.Types`. By moving it into its own module we can remove this dependency. It also simplifies the necessary boot file. - - - - - 9e5246d7 by Matthew Pickering at 2023-06-05T11:46:24+01:00 Move GHC.Core.Opt.CallerCC Types into separate module This allows `GHC.Driver.DynFlags` to depend on these types without depending on CoreM and hence the entire simplifier pipeline. We can also remove a hs-boot file with this change. - - - - - 52d6a7d7 by Matthew Pickering at 2023-06-05T11:46:24+01:00 Remove unecessary SOURCE import - - - - - 698d160c by Matthew Pickering at 2023-06-05T11:46:24+01:00 testsuite: Accept new output for CountDepsAst and CountDepsParser tests These are in a separate commit as the improvement to these tests is the cumulative effect of the previous set of patches rather than just the responsibility of the last one in the patchset. - - - - - 58ccf02e by sheaf at 2023-06-05T16:00:47-04:00 TTG: only allow VarBind at GhcTc The VarBind constructor of HsBind is only used at the GhcTc stage. This commit makes that explicit by setting the extension field of VarBind to be DataConCantHappen at all other stages. This allows us to delete a dead code path in GHC.HsToCore.Quote.rep_bind, and remove some panics. - - - - - 54b83253 by Matthew Craven at 2023-06-06T12:59:25-04:00 Generate Addr# access ops programmatically The existing utils/genprimopcode/gen_bytearray_ops.py was relocated and extended for this purpose. Additionally, hadrian now knows about this script and uses it when generating primops.txt - - - - - ecadbc7e by Matthew Pickering at 2023-06-06T13:00:01-04:00 ghcup-metadata: Only add Nightly tag when replacing LatestNightly Previously we were always adding the Nightly tag, but this led to all the previous builds getting an increasing number of nightly tags over time. Now we just add it once, when we remove the LatestNightly tag. - - - - - 4aea0a72 by Vladislav Zavialov at 2023-06-07T12:06:46+02:00 Invisible binders in type declarations (#22560) This patch implements @k-binders introduced in GHC Proposal #425 and guarded behind the TypeAbstractions extension: type D :: forall k j. k -> j -> Type data D @k @j a b = ... ^^ ^^ To represent the new syntax, we modify LHsQTyVars as follows: - hsq_explicit :: [LHsTyVarBndr () pass] + hsq_explicit :: [LHsTyVarBndr (HsBndrVis pass) pass] HsBndrVis is a new data type that records the distinction between type variable binders written with and without the @ sign: data HsBndrVis pass = HsBndrRequired | HsBndrInvisible (LHsToken "@" pass) The rest of the patch updates GHC, template-haskell, and haddock to handle the new syntax. Parser: The PsErrUnexpectedTypeAppInDecl error message is removed. The syntax it used to reject is now permitted. Renamer: The @ sign does not affect the scope of a binder, so the changes to the renamer are minimal. See rnLHsTyVarBndrVisFlag. Type checker: There are three code paths that were updated to deal with the newly introduced invisible type variable binders: 1. checking SAKS: see kcCheckDeclHeader_sig, matchUpSigWithDecl 2. checking CUSK: see kcCheckDeclHeader_cusk 3. inference: see kcInferDeclHeader, rejectInvisibleBinders Helper functions bindExplicitTKBndrs_Q_Skol and bindExplicitTKBndrs_Q_Tv are generalized to work with HsBndrVis. Updates the haddock submodule. Metric Increase: MultiLayerModulesTH_OneShot Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - b7600997 by Josh Meredith at 2023-06-07T13:10:21-04:00 JS: clean up FFI 'fat arrow' calls in base:System.Posix.Internals (#23481) - - - - - e5d3940d by Sebastian Graf at 2023-06-07T18:01:28-04:00 Update CODEOWNERS - - - - - 960ef111 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Remove IPE enabled builds from CI" This reverts commit 41b41577c8a28c236fa37e8f73aa1c6dc368d951. - - - - - bad1c8cc by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Update user's guide and release notes, small fixes" This reverts commit 3ded9a1cd22f9083f31bc2f37ee1b37f9d25dab7. - - - - - 12726d90 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add IPE-enabled builds to CI" This reverts commit 09d93bd0305b0f73422ce7edb67168c71d32c15f. - - - - - dbdd989d by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add optional dependencies to ./configure output" This reverts commit a00488665cd890a26a5564a64ba23ff12c9bec58. - - - - - 240483af by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix IPE data decompression buffer allocation" This reverts commit 0e85099b9316ee24565084d5586bb7290669b43a. - - - - - 9b8c7dd8 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix byte order of IPE data, fix IPE tests" This reverts commit 7872e2b6f08ea40d19a251c4822a384d0b397327. - - - - - 3364379b by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add note describing IPE data compression" This reverts commit 69563c97396b8fde91678fae7d2feafb7ab9a8b0. - - - - - fda30670 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix libzstd detection in configure and RTS" This reverts commit 5aef5658ad5fb96bac7719710e0ea008bf7b62e0. - - - - - 1cbcda9a by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "IPE data compression" This reverts commit b7a640acf7adc2880e5600d69bcf2918fee85553. - - - - - fb5e99aa by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add IPE compression to configure" This reverts commit 5d1f2411f4becea8650d12d168e989241edee186. - - - - - 2cdcb3a5 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Restructure IPE buffer layout" This reverts commit f3556d6cefd3d923b36bfcda0c8185abb1d11a91. - - - - - 2b0c9f5e by Simon Peyton Jones at 2023-06-08T07:52:34+00:00 Don't report redundant Givens from quantified constraints This fixes #23323 See (RC4) in Note [Tracking redundant constraints] - - - - - 567b32e1 by David Binder at 2023-06-08T18:41:29-04:00 Update the outdated instructions in HACKING.md on how to compile GHC - - - - - 2b1a4abe by Ryan Scott at 2023-06-09T07:56:58-04:00 Restore mingwex dependency on Windows This partially reverts some of the changes in !9475 to make `base` and `ghc-prim` depend on the `mingwex` library on Windows. It also restores the RTS's stubs for `mingwex`-specific symbols such as `_lock_file`. This is done because the C runtime provides `libmingwex` nowadays, and moreoever, not linking against `mingwex` requires downstream users to link against it explicitly in difficult-to-predict circumstances. Better to always link against `mingwex` and prevent users from having to do the guesswork themselves. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10360#note_495873 for the discussion that led to this. - - - - - 28954758 by Ryan Scott at 2023-06-09T07:56:58-04:00 RtsSymbols.c: Remove mingwex symbol stubs As of !9475, the RTS now links against `ucrt` instead of `msvcrt` on Windows, which means that the RTS no longer needs to declare stubs for the `__mingw_*` family of symbols. Let's remove these stubs to avoid confusion. Fixes #23309. - - - - - 3ab0155b by Ryan Scott at 2023-06-09T07:57:35-04:00 Consistently use validity checks for TH conversion of data constructors We were checking that TH-spliced data declarations do not look like this: ```hs data D :: Type = MkD Int ``` But we were only doing so for `data` declarations' data constructors, not for `newtype`s, `data instance`s, or `newtype instance`s. This patch factors out the necessary validity checks into its own `cvtDataDefnCons` function and uses it in all of the places where it needs to be. Fixes #22559. - - - - - a24b83dd by Matthew Pickering at 2023-06-09T15:19:00-04:00 Fix behaviour of -keep-tmp-files when used in OPTIONS_GHC pragma This fixes the behaviour of -keep-tmp-files when used in an OPTIONS_GHC pragma for files with module level scope. Instead of simple not deleting the files, we also need to remove them from the TmpFs so they are not deleted later on when all the other files are deleted. There are additional complications because you also need to remove the directory where these files live from the TmpFs so we don't try to delete those later either. I added two tests. 1. Tests simply that -keep-tmp-files works at all with a single module and --make mode. 2. The other tests that temporary files are deleted for other modules which don't enable -keep-tmp-files. Fixes #23339 - - - - - dcf32882 by Matthew Pickering at 2023-06-09T15:19:00-04:00 withDeferredDiagnostics: When debugIsOn, write landmine into IORef to catch use-after-free. Ticket #23305 reports an error where we were attempting to use the logger which was created by withDeferredDiagnostics after its scope had ended. This problem would have been caught by this patch and a validate build: ``` +*** Exception: Use after free +CallStack (from HasCallStack): + error, called at compiler/GHC/Driver/Make.hs:<line>:<column> in <package-id>:GHC.Driver.Make ``` This general issue is tracked by #20981 - - - - - 432c736c by Matthew Pickering at 2023-06-09T15:19:00-04:00 Don't return complete HscEnv from upsweep By returning a complete HscEnv from upsweep the logger (as introduced by withDeferredDiagnostics) was escaping the scope of withDeferredDiagnostics and hence we were losing error messages. This is reminiscent of #20981, which also talks about writing errors into messages after their scope has ended. See #23305 for details. - - - - - 26013cdc by Alexander McKenna at 2023-06-09T15:19:41-04:00 Dump `SpecConstr` specialisations separately Introduce a `-ddump-spec-constr` flag which debugs specialisations from `SpecConstr`. These are no longer shown when you use `-ddump-spec`. - - - - - 4639100b by Matthew Pickering at 2023-06-09T18:50:43-04:00 Add role annotations to SNat, SSymbol and SChar Ticket #23454 explained it was possible to implement unsafeCoerce because SNat was lacking a role annotation. As these are supposed to be singleton types but backed by an efficient representation the correct annotation is nominal to ensure these kinds of coerces are forbidden. These annotations were missed from https://github.com/haskell/core-libraries-committee/issues/85 which was implemented in 532de36870ed9e880d5f146a478453701e9db25d. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/170 Fixes #23454 - - - - - 9c0dcff7 by Matthew Pickering at 2023-06-09T18:51:19-04:00 Remove non-existant bytearray-ops.txt.pp file from ghc.cabal.in This broke the sdist generation. Fixes #23489 - - - - - 273ff0c7 by David Binder at 2023-06-09T18:52:00-04:00 Regression test T13438 is no longer marked as "expect_broken" in the testsuite driver. - - - - - b84a2900 by Andrei Borzenkov at 2023-06-10T08:27:28-04:00 Fix -Wterm-variable-capture scope (#23434) -Wterm-variable-capture wasn't accordant with type variable scoping in associated types, in type classes. For example, this code produced the warning: k = 12 class C k a where type AT a :: k -> Type I solved this issue by reusing machinery of newTyVarNameRn function that is accordand with associated types: it does lookup for each free type variable when we are in the type class context. And in this patch I use result of this work to make sure that -Wterm-variable-capture warns only on implicitly quantified type variables. - - - - - 9d1a8d87 by Jorge Mendes at 2023-06-10T08:28:10-04:00 Remove redundant case statement in rts/js/mem.js. - - - - - a1f350e2 by Oleg Grenrus at 2023-06-13T09:42:16-04:00 Change WarningWithFlag to plural WarningWithFlags Resolves #22825 Now each diagnostic can name multiple different warning flags for its reason. There is currently one use case: missing signatures. Currently we need to check which warning flags are enabled when generating the diagnostic, which is against the declarative nature of the diagnostic framework. This patch allows a warning diagnostic to have multiple warning flags, which makes setup more declarative. The WarningWithFlag pattern synonym is added for backwards compatibility The 'msgEnvReason' field is added to MsgEnvelope to store the `ResolvedDiagnosticReason`, which accounts for the enabled flags, and then that is used for pretty printing the diagnostic. - - - - - ec01f0ec by Matthew Pickering at 2023-06-13T09:42:59-04:00 Add a test Way for running ghci with Core optimizations Tracking ticket: #23059 This runs compile_and_run tests with optimised code with bytecode interpreter Changed submodules: hpc, process Co-authored-by: Torsten Schmits <git at tryp.io> - - - - - c6741e72 by Rodrigo Mesquita at 2023-06-13T09:43:38-04:00 Configure -Qunused-arguments instead of hardcoding it When GHC invokes clang, it currently passes -Qunused-arguments to discard warnings resulting from GHC using multiple options that aren't used. In this commit, we configure -Qunused-arguments into the Cc options instead of checking if the compiler is clang at runtime and hardcoding the flag into GHC. This is part of the effort to centralise toolchain information in toolchain target files at configure time with the end goal of a runtime retargetable GHC. This also means we don't need to call getCompilerInfo ever, which improves performance considerably (see !10589). Metric Decrease: PmSeriesG T10421 T11303b T12150 T12227 T12234 T12425 T13035 T13253-spj T13386 T15703 T16875 T17836b T17977 T17977b T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T3064 T5030 T5321FD T5321Fun T5837 T6048 T9020 T9198 T9872d T9961 - - - - - 0128db87 by Victor Cacciari Miraldo at 2023-06-13T09:44:18-04:00 Improve docs for Data.Fixed; adds 'realToFrac' as an option for conversion between different precisions. - - - - - 95b69cfb by Ryan Scott at 2023-06-13T09:44:55-04:00 Add regression test for #23143 !10541, the fix for #23323, also fixes #23143. Let's add a regression test to ensure that it stays fixed. Fixes #23143. - - - - - ed2dbdca by Emily Martins at 2023-06-13T09:45:37-04:00 delete GHCi.UI.Tags module and remove remaining references Co-authored-by: Tilde Rose <t1lde at protonmail.com> - - - - - c90d96e4 by Victor Cacciari Miraldo at 2023-06-13T09:46:26-04:00 Add regression test for 17328 - - - - - de58080c by Victor Cacciari Miraldo at 2023-06-13T09:46:26-04:00 Skip checking whether constructors are in scope when deriving newtype instances. Fixes #17328 - - - - - 5e3c2b05 by Philip Hazelden at 2023-06-13T09:47:07-04:00 Don't suggest `DeriveAnyClass` when instance can't be derived. Fixes #19692. Prototypical cases: class C1 a where x1 :: a -> Int data G1 = G1 deriving C1 class C2 a where x2 :: a -> Int x2 _ = 0 data G2 = G2 deriving C2 Both of these used to give this suggestion, but for C1 the suggestion would have failed (generated code with undefined methods, which compiles but warns). Now C2 still gives the suggestion but C1 doesn't. - - - - - 80a0b099 by David Binder at 2023-06-13T09:47:49-04:00 Add testcase for error GHC-00711 to testsuite - - - - - e4b33a1d by Oleg Grenrus at 2023-06-14T07:01:21-04:00 Add -Wmissing-poly-kind-signatures Implements #22826 This is a restricted version of -Wmissing-kind-signatures shown only for polykinded types. - - - - - f8395b94 by doyougnu at 2023-06-14T07:02:01-04:00 ci: special case in req_host_target_ghc for JS - - - - - b852a5b6 by Gergő Érdi at 2023-06-14T07:02:42-04:00 When forcing a `ModIface`, force the `MINIMAL` pragmas in class definitions Fixes #23486 - - - - - c29b45ee by Krzysztof Gogolewski at 2023-06-14T07:03:19-04:00 Add a testcase for #20076 Remove 'recursive' in the error message, since the error can arise without recursion. - - - - - b80ef202 by Krzysztof Gogolewski at 2023-06-14T07:03:56-04:00 Use tcInferFRR to prevent bad generalisation Fixes #23176 - - - - - bd8ef37d by Matthew Pickering at 2023-06-14T07:04:31-04:00 ci: Add dependenices on necessary aarch64 jobs for head.hackage ci These need to be added since we started testing aarch64 on head.hackage CI. The jobs will sometimes fail because they will start before the relevant aarch64 job has finished. Fixes #23511 - - - - - a0c27cee by Vladislav Zavialov at 2023-06-14T07:05:08-04:00 Add standalone kind signatures for Code and TExp CodeQ and TExpQ already had standalone kind signatures even before this change: type TExpQ :: TYPE r -> Kind.Type type CodeQ :: TYPE r -> Kind.Type Now Code and TExp have signatures too: type TExp :: TYPE r -> Kind.Type type Code :: (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type This is a stylistic change. - - - - - e70c1245 by Tom Ellis at 2023-06-14T07:05:48-04:00 Warn that GHC.TypeLits.Internal should not be used - - - - - 100650e3 by Tom Ellis at 2023-06-14T07:05:48-04:00 Warn that GHC.TypeNats.Internal should not be used - - - - - 078250ef by Jacco Krijnen at 2023-06-14T17:17:53-04:00 Add more flags for dumping core passes (#23491) - - - - - 1b7604af by Jacco Krijnen at 2023-06-14T17:17:53-04:00 Add tests for dumping flags (#23491) - - - - - 42000000 by Sebastian Graf at 2023-06-14T17:18:29-04:00 Provide a demand signature for atomicModifyMutVar.# (#23047) Fixes #23047 - - - - - 8f27023b by Ben Gamari at 2023-06-15T03:10:24-04:00 compiler: Cross-reference Note [StgToJS design] In particular, the numeric representations are quite useful context in a few places. - - - - - a71b60e9 by Andrei Borzenkov at 2023-06-15T03:11:00-04:00 Implement the -Wimplicit-rhs-quantification warning (#23510) GHC Proposal #425 "Invisible binders in type declarations" forbids implicit quantification of type variables that occur free on the right-hand side of a type synonym but are not mentioned on the left-hand side. The users are expected to rewrite this using invisible binders: type T1 :: forall a . Maybe a type T1 = 'Nothing :: Maybe a -- old type T1 @a = 'Nothing :: Maybe a -- new Since the @k-binders are a new feature, we need to wait for three releases before we require the use of the new syntax. In the meantime, we ought to provide users with a new warning, -Wimplicit-rhs-quantification, that would detect when such implicit quantification takes place, and include it in -Wcompat. - - - - - 0078dd00 by Sven Tennie at 2023-06-15T03:11:36-04:00 Minor refactorings to mkSpillInstr and mkLoadInstr Better error messages. And, use the existing `off` constant to reduce duplication. - - - - - 1792b57a by doyougnu at 2023-06-15T03:12:17-04:00 JS: merge util modules Merge Core and StgUtil modules for StgToJS pass. Closes: #23473 - - - - - 469ff08b by Vladislav Zavialov at 2023-06-15T03:12:57-04:00 Check visibility of nested foralls in can_eq_nc (#18863) Prior to this change, `can_eq_nc` checked the visibility of the outermost layer of foralls: forall a. forall b. forall c. phi1 forall x. forall y. forall z. phi2 ^^ up to here Then it delegated the rest of the work to `can_eq_nc_forall`, which split off all foralls: forall a. forall b. forall c. phi1 forall x. forall y. forall z. phi2 ^^ up to here This meant that some visibility flags were completely ignored. We fix this oversight by moving the check to `can_eq_nc_forall`. - - - - - 59c9065b by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: use regular mask for blocking IO Blocking IO used uninterruptibleMask which should make any thread blocked on IO unreachable by async exceptions (such as those from timeout). This changes it to a regular mask. It's important to note that the nodejs runtime does not actually interrupt the blocking IO when the Haskell thread receives an async exception, and that file positions may be updated and buffers may be written after the Haskell thread has already resumed. Any file descriptor affected by an async exception interruption should therefore be used with caution. - - - - - 907c06c3 by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: nodejs: do not set 'readable' handler on stdin at startup The Haskell runtime used to install a 'readable' handler on stdin at startup in nodejs. This would cause the nodejs system to start buffering the stream, causing data loss if the stdin file descriptor is passed to another process. This change delays installation of the 'readable' handler until the first read of stdin by Haskell code. - - - - - a54b40a9 by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: reserve one more virtual (negative) file descriptor This is needed for upcoming support of the process package - - - - - 78cd1132 by Andrei Borzenkov at 2023-06-15T11:16:11+04:00 Report scoped kind variables at the type-checking phase (#16635) This patch modifies the renamer to respect ScopedTypeVariables in kind signatures. This means that kind variables bound by the outermost `forall` now scope over the type: type F = '[Right @a @() () :: forall a. Either a ()] -- ^^^^^^^^^^^^^^^ ^^^ -- in scope here bound here However, any use of such variables is a type error, because we don't have type-level lambdas to bind them in Core. This is described in the new Note [Type variable scoping errors during type check] in GHC.Tc.Types. - - - - - 4a41ba75 by Sylvain Henry at 2023-06-15T18:09:15-04:00 JS: testsuite: use correct ticket number Replace #22356 with #22349 for these tests because #22356 has been fixed but now these tests fail because of #22349. - - - - - 15f150c8 by Sylvain Henry at 2023-06-15T18:09:16-04:00 JS: testsuite: update ticket numbers - - - - - 08d8e9ef by Sylvain Henry at 2023-06-15T18:09:16-04:00 JS: more triage - - - - - e8752e12 by Krzysztof Gogolewski at 2023-06-15T18:09:52-04:00 Fix test T18522-deb-ppr Fixes #23509 - - - - - 62c56416 by Ben Price at 2023-06-16T05:52:39-04:00 Lint: more details on "Occurrence is GlobalId, but binding is LocalId" This is helpful when debugging a pass which accidentally shadowed a binder. - - - - - d4c10238 by Ryan Hendrickson at 2023-06-16T05:53:22-04:00 Clean a stray bit of text in user guide - - - - - 93647b5c by Vladislav Zavialov at 2023-06-16T05:54:02-04:00 testsuite: Add forall visibility test cases The added tests ensure that the type checker does not confuse visible and invisible foralls. VisFlag1: kind-checking type applications and inferred type variable instantiations VisFlag1_ql: kind-checking Quick Look instantiations VisFlag2: kind-checking type family instances VisFlag3: checking kind annotations on type parameters of associated type families VisFlag4: checking kind annotations on type parameters in type declarations with SAKS VisFlag5: checking the result kind annotation of data family instances - - - - - a5f0c00e by Sylvain Henry at 2023-06-16T12:25:40-04:00 JS: factorize SaneDouble into its own module Follow-up of b159e0e9 whose ticket is #22736 - - - - - 0baf9e7c by Krzysztof Gogolewski at 2023-06-16T12:26:17-04:00 Add tests for #21973 - - - - - 640ea90e by Diego Diverio at 2023-06-16T23:07:55-04:00 Update documentation for `<**>` - - - - - 2469a813 by Diego Diverio at 2023-06-16T23:07:55-04:00 Update text - - - - - 1f515bbb by Diego Diverio at 2023-06-16T23:07:55-04:00 Update examples - - - - - 7af99a0d by Diego Diverio at 2023-06-16T23:07:55-04:00 Update documentation to actually display code correctly - - - - - 800aad7e by Andrei Borzenkov at 2023-06-16T23:08:32-04:00 Type/data instances: require that variables on the RHS are mentioned on the LHS (#23512) GHC Proposal #425 "Invisible binders in type declarations" restricts the scope of type and data family instances as follows: In type family and data family instances, require that every variable mentioned on the RHS must also occur on the LHS. For example, here are three equivalent type instance definitions accepted before this patch: type family F1 a :: k type instance F1 Int = Any :: j -> j type family F2 a :: k type instance F2 @(j -> j) Int = Any :: j -> j type family F3 a :: k type instance forall j. F3 Int = Any :: j -> j - In F1, j is implicitly quantified and it occurs only on the RHS; - In F2, j is implicitly quantified and it occurs both on the LHS and the RHS; - In F3, j is explicitly quantified. Now F1 is rejected with an out-of-scope error, while F2 and F3 continue to be accepted. - - - - - 9132d529 by Sylvain Henry at 2023-06-18T02:50:34-04:00 JS: testsuite: use correct ticket numbers - - - - - c3a1274c by Sylvain Henry at 2023-06-18T02:50:34-04:00 JS: don't dump eventlog to stderr by default Fix T16707 Bump stm submodule - - - - - 89bb8ad8 by Ryan Hendrickson at 2023-06-18T02:51:14-04:00 Fix TH name lookup for symbolic tycons (#23525) - - - - - cb9e1ce4 by Finley McIlwaine at 2023-06-18T21:16:45-06:00 IPE data compression IPE data resulting from the `-finfo-table-map` flag may now be compressed by configuring the GHC build with the `--enable-ipe-data-compression` flag. This results in about a 20% reduction in the size of IPE-enabled build results. The compression library, zstd, may optionally be statically linked by configuring with the `--enabled-static-libzstd` flag (on non-darwin platforms) libzstd version 1.4.0 or greater is required. - - - - - 0cbc3ae0 by Gergő Érdi at 2023-06-19T09:11:38-04:00 Add `IfaceWarnings` to represent the `ModIface`-storable parts of a `Warnings GhcRn`. Fixes #23516 - - - - - 3e80c2b4 by Arnaud Spiwack at 2023-06-20T03:19:41-04:00 Avoid desugaring non-recursive lets into recursive lets This prepares for having linear let expressions in the frontend. When desugaring lets, SPECIALISE statements create more copies of a let binding. Because of the rewrite rules attached to the bindings, there are dependencies between the generated binds. Before this commit, we simply wrapped all these in a mutually recursive let block, and left it to the simplified to sort it out. With this commit: we are careful to generate the bindings in dependency order, so that we can wrap them in consecutive lets (if the source is non-recursive). - - - - - 9fad49e0 by Ben Gamari at 2023-06-20T03:20:19-04:00 rts: Do not call exit() from SIGINT handler Previously `shutdown_handler` would call `stg_exit` if the scheduler was Oalready found to be in `SCHED_INTERRUPTING` state (or higher). However, `stg_exit` is not signal-safe as it calls `exit` (which calls `atexit` handlers). The only safe thing to do in this situation is to call `_exit`, which terminates with minimal cleanup. Fixes #23417. - - - - - 7485f848 by Andrew Lelechenko at 2023-06-20T03:20:57-04:00 Bump Cabal submodule This requires changing the recomp007 test because now cabal passes `this-unit-id` to executable components, and that unit-id contains a hash which includes the ABI of the dependencies. Therefore changing the dependencies means that -this-unit-id changes and recompilation is triggered. The spririt of the test is to test GHC's recompilation logic assuming that `-this-unit-id` is constant, so we explicitly pass `-ipid` to `./configure` rather than letting `Cabal` work it out. - - - - - 1464a2a8 by mangoiv at 2023-06-20T03:21:34-04:00 [feat] add a hint to `HasField` error message - add a hint that indicates that the record that the record dot is used on might just be missing a field - as the intention of the programmer is not entirely clear, it is only shown if the type is known - This addresses in part issue #22382 - - - - - b65e78dd by Ben Gamari at 2023-06-20T16:56:43-04:00 rts/ipe: Fix unused lock warning - - - - - 6086effd by Ben Gamari at 2023-06-20T16:56:44-04:00 rts/ProfilerReportJson: Fix memory leak - - - - - 1e48c434 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Various warnings fixes - - - - - 471486b9 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix printf format mismatch - - - - - 80603fb3 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect #include <sys/poll.h> According to Alpine's warnings and poll(2), <poll.h> should be preferred. - - - - - ff18e6fd by Ben Gamari at 2023-06-20T16:56:44-04:00 nonmoving: Fix unused definition warrnings - - - - - 6e7fe8ee by Ben Gamari at 2023-06-20T16:56:44-04:00 Disable futimens on Darwin. See #22938 - - - - - b7706508 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect CPP guard - - - - - 94f00e9b by Ben Gamari at 2023-06-20T16:56:44-04:00 hadrian: Ensure that -Werror is passed when compiling the RTS. Previously the `+werror` transformer would only pass `-Werror` to GHC, which does not ensure that the same is passed to the C compiler when building the RTS. Arguably this is itself a bug but for now we will just work around this by passing `-optc-Werror` to GHC. I tried to enable `-Werror` in all C compilations but the boot libraries are something of a portability nightmare. - - - - - 5fb54bf8 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Disable `#pragma GCC`s on clang compilers Otherwise the build fails due to warnings. See #23530. - - - - - cf87f380 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix capitalization of prototype - - - - - 17f250d7 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect format specifier - - - - - 0ff1c501 by Josh Meredith at 2023-06-20T16:57:20-04:00 JS: remove js_broken(22576) in favour of the pre-existing wordsize(32) condition (#22576) - - - - - 3d1d42b7 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Memory usage fixes for Haddock - Do not include `mi_globals` in the `NoBackend` backend. It was only included for Haddock, but Haddock does not actually need it. This causes a 200MB reduction in max residency when generating haddocks on the Agda codebase (roughly 1GB to 800MB). - Make haddock_{parser,renamer}_perf tests more accurate by forcing docs to be written to interface files using `-fwrite-interface` Bumps haddock submodule. Metric Decrease: haddock.base - - - - - 8185b1c2 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Fix associated data family doc structure items Associated data families were being given their own export DocStructureItems, which resulted in them being documented separately from their classes in haddocks. This commit fixes it. - - - - - 4d356ea3 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: implement TH support - Add ghc-interp.js bootstrap script for the JS interpreter - Interactively link and execute iserv code from the ghci package - Incrementally load and run JS code for splices into the running iserv Co-authored-by: Luite Stegeman <stegeman at gmail.com> - - - - - 3249cf12 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Don't use getKey - - - - - f84ff161 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Stg: return imported FVs This is used to determine what to link when using the interpreter. For now it's only used by the JS interpreter but it could easily be used by the native interpreter too (instead of extracting names from compiled BCOs). - - - - - fab2ad23 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Fix some recompilation avoidance tests - - - - - a897dc13 by Sylvain Henry at 2023-06-21T12:04:59-04:00 TH_import_loop is now broken as expected - - - - - dbb4ad51 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: always recompile when TH is enabled (cf #23013) - - - - - 711b1d24 by Bartłomiej Cieślar at 2023-06-21T12:59:27-04:00 Add support for deprecating exported items (proposal #134) This is an implementation of the deprecated exports proposal #134. The proposal introduces an ability to introduce warnings to exports. This allows for deprecating a name only when it is exported from a specific module, rather than always depreacting its usage. In this example: module A ({-# DEPRECATED "do not use" #-} x) where x = undefined --- module B where import A(x) `x` will emit a warning when it is explicitly imported. Like the declaration warnings, export warnings are first accumulated within the `Warnings` struct, then passed into the ModIface, from which they are then looked up and warned about in the importing module in the `lookup_ie` helpers of the `filterImports` function (for the explicitly imported names) and in the `addUsedGRE(s)` functions where they warn about regular usages of the imported name. In terms of the AST information, the custom warning is stored in the extension field of the variants of the `IE` type (see Trees that Grow for more information). The commit includes a bump to the haddock submodule added in MR #28 Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - c1865854 by Ben Gamari at 2023-06-21T12:59:30-04:00 configure: Bump version to 9.8 Bumps Haddock submodule - - - - - 4e1de71c by Ben Gamari at 2023-06-21T21:07:48-04:00 configure: Bump version to 9.9 Bumps haddock submodule. - - - - - 5b6612bc by Ben Gamari at 2023-06-23T03:56:49-04:00 rts: Work around missing prototypes errors Darwin's toolchain inexpliciably claims that `write_barrier` and friends have declarations without prototypes, despite the fact that (a) they are definitions, and (b) the prototypes appear only a few lines above. Work around this by making the definitions proper prototypes. - - - - - 43b66a13 by Matthew Pickering at 2023-06-23T03:57:26-04:00 ghcup-metadata: Fix date modifier (M = minutes, m = month) Fixes #23552 - - - - - 564164ef by Luite Stegeman at 2023-06-24T10:27:29+09:00 Support large stack frames/offsets in GHCi bytecode interpreter Bytecode instructions like PUSH_L (push a local variable) contain an operand that refers to the stack slot. Before this patch, the operand type was SmallOp (Word16), limiting the maximum stack offset to 65535 words. This could cause compiler panics in some cases (See #22888). This patch changes the operand type for stack offsets from SmallOp to Op, removing the stack offset limit. Fixes #22888 - - - - - 8d6574bc by Sylvain Henry at 2023-06-26T13:15:06-04:00 JS: support levity-polymorphic datatypes (#22360,#22291) - thread knowledge about levity into PrimRep instead of panicking - JS: remove assumption that unlifted heap objects are rts objects (TVar#, etc.) Doing this also fixes #22291 (test added). There is a small performance hit (~1% more allocations). Metric Increase: T18698a T18698b - - - - - 5578bbad by Matthew Pickering at 2023-06-26T13:15:43-04:00 MR Review Template: Mention "Blocked on Review" label In order to improve our MR review processes we now have the label "Blocked on Review" which allows people to signal that a MR is waiting on a review to happen. See: https://mail.haskell.org/pipermail/ghc-devs/2023-June/021255.html - - - - - 4427e9cf by Matthew Pickering at 2023-06-26T13:15:43-04:00 Move MR template to Default.md This makes it more obvious what you have to modify to affect the default template rather than looking in the project settings. - - - - - 522bd584 by Arnaud Spiwack at 2023-06-26T13:16:33-04:00 Revert "Avoid desugaring non-recursive lets into recursive lets" This (temporary) reverts commit 3e80c2b40213bebe302b1bd239af48b33f1b30ef. Fixes #23550 - - - - - c59fbb0b by Torsten Schmits at 2023-06-26T19:34:20+02:00 Propagate breakpoint information when inlining across modules Tracking ticket: #23394 MR: !10448 * Add constructor `IfaceBreakpoint` to `IfaceTickish` * Store breakpoint data in interface files * Store `BreakArray` for the breakpoint's module, not the current module, in BCOs * Store module name in BCOs instead of `Unique`, since the `Unique` from an `Iface` doesn't match the modules in GHCi's state * Allocate module name in `ModBreaks`, like `BreakArray` * Lookup breakpoint by module name in GHCi * Skip creating breakpoint instructions when no `ModBreaks` are available, rather than injecting `ModBreaks` in the linker when breakpoints are enabled, and panicking when `ModBreaks` is missing - - - - - 6f904808 by Greg Steuck at 2023-06-27T16:53:07-04:00 Remove undefined FP_PROG_LD_BUILD_ID from configure.ac's - - - - - e89aa072 by Andrei Borzenkov at 2023-06-27T16:53:44-04:00 Remove arity inference in type declarations (#23514) Arity inference in type declarations was introduced as a workaround for the lack of @k-binders. They were added in 4aea0a72040, so I simplified all of this by simply removing arity inference altogether. This is part of GHC Proposal #425 "Invisible binders in type declarations". - - - - - 459dee1b by Torsten Schmits at 2023-06-27T16:54:20-04:00 Relax defaulting of RuntimeRep/Levity when printing Fixes #16468 MR: !10702 Only default RuntimeRep to LiftedRep when variables are bound by the toplevel forall - - - - - 151f8f18 by Torsten Schmits at 2023-06-27T16:54:57-04:00 Remove duplicate link label in linear types docs - - - - - ecdc4353 by Rodrigo Mesquita at 2023-06-28T12:24:57-04:00 Stop configuring unused Ld command in `settings` GHC has no direct dependence on the linker. Rather, we depend upon the C compiler for linking and an object-merging program (which is typically `ld`) for production of GHCi objects and merging of C stubs into final object files. Despite this, for historical reasons we still recorded information about the linker into `settings`. Remove these entries from `settings`, `hadrian/cfg/system.config`, as well as the `configure` logic responsible for this information. Closes #23566. - - - - - bf9ec3e4 by Bryan Richter at 2023-06-28T12:25:33-04:00 Remove extraneous debug output - - - - - 7eb68dd6 by Bryan Richter at 2023-06-28T12:25:33-04:00 Work with unset vars in -e mode - - - - - 49c27936 by Bryan Richter at 2023-06-28T12:25:33-04:00 Pass positional arguments in their positions By quoting $cmd, the default "bash -i" is a single argument to run, and no file named "bash -i" actually exists to be run. - - - - - 887dc4fc by Bryan Richter at 2023-06-28T12:25:33-04:00 Handle unset value in -e context - - - - - 5ffc7d7b by Rodrigo Mesquita at 2023-06-28T21:07:36-04:00 Configure CPP into settings There is a distinction to be made between the Haskell Preprocessor and the C preprocessor. The former is used to preprocess Haskell files, while the latter is used in C preprocessing such as Cmm files. In practice, they are both the same program (usually the C compiler) but invoked with different flags. Previously we would, at configure time, configure the haskell preprocessor and save the configuration in the settings file, but, instead of doing the same for CPP, we had hardcoded in GHC that the CPP program was either `cc -E` or `cpp`. This commit fixes that asymmetry by also configuring CPP at configure time, and tries to make more explicit the difference between HsCpp and Cpp (see Note [Preprocessing invocations]). Note that we don't use the standard CPP and CPPFLAGS to configure Cpp, but instead use the non-standard --with-cpp and --with-cpp-flags. The reason is that autoconf sets CPP to "$CC -E", whereas we expect the CPP command to be configured as a standalone executable rather than a command. These are symmetrical with --with-hs-cpp and --with-hs-cpp-flags. Cleanup: Hadrian no longer needs to pass the CPP configuration for CPP to be C99 compatible through -optP, since we now configure that into settings. Closes #23422 - - - - - 5efa9ca5 by Ben Gamari at 2023-06-28T21:08:13-04:00 hadrian: Always canonicalize topDirectory Hadrian's `topDirectory` is intended to provide an absolute path to the root of the GHC tree. However, if the tree is reached via a symlink this One question here is whether the `canonicalizePath` call is expensive enough to warrant caching. In a quick microbenchmark I observed that `canonicalizePath "."` takes around 10us per call; this seems sufficiently low not to worry. Alternatively, another approach here would have been to rather move the canonicalization into `m4/fp_find_root.m4`. This would have avoided repeated canonicalization but sadly path canonicalization is a hard problem in POSIX shell. Addresses #22451. - - - - - b3e1436f by aadaa_fgtaa at 2023-06-28T21:08:53-04:00 Optimise ELF linker (#23464) - cache last elements of `relTable`, `relaTable` and `symbolTables` in `ocInit_ELF` - cache shndx table in ObjectCode - run `checkProddableBlock` only with debug rts - - - - - 30525b00 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Introduce MO_{ACQUIRE,RELEASE}_FENCE - - - - - b787e259 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Drop MO_WriteBarrier rts: Drop write_barrier - - - - - 7550b4a5 by Ben Gamari at 2023-06-28T21:09:30-04:00 rts: Drop load_store_barrier() This is no longer used. - - - - - d5f2875e by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop last instances of prim_{write,read}_barrier - - - - - 965ac2ba by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Eliminate remaining uses of load_load_barrier - - - - - 0fc5cb97 by Sven Tennie at 2023-06-28T21:09:31-04:00 compiler: Drop MO_ReadBarrier - - - - - 7a7d326c by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop load_load_barrier This is no longer used. - - - - - 9f63da66 by Sven Tennie at 2023-06-28T21:09:31-04:00 Delete write_barrier function - - - - - bb0ed354 by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Make collectFreshWeakPtrs definition a prototype x86-64/Darwin's toolchain inexplicably warns that collectFreshWeakPtrs needs to be a prototype. - - - - - ef81a1eb by Sven Tennie at 2023-06-28T21:10:08-04:00 Fix number of free double regs D1..D4 are defined for aarch64 and thus not free. - - - - - c335fb7c by Ryan Scott at 2023-06-28T21:10:44-04:00 Fix typechecking of promoted empty lists The `'[]` case in `tc_infer_hs_type` is smart enough to handle arity-0 uses of `'[]` (see the newly added `T23543` test case for an example), but the `'[]` case in `tc_hs_type` was not. We fix this by changing the `tc_hs_type` case to invoke `tc_infer_hs_type`, as prescribed in `Note [Future-proofing the type checker]`. There are some benign changes to test cases' expected output due to the new code path using `forall a. [a]` as the kind of `'[]` rather than `[k]`. Fixes #23543. - - - - - fcf310e7 by Rodrigo Mesquita at 2023-06-28T21:11:21-04:00 Configure MergeObjs supports response files rather than Ld The previous configuration script to test whether Ld supported response files was * Incorrect (see #23542) * Used, in practice, to check if the *merge objects tool* supported response files. This commit modifies the macro to run the merge objects tool (rather than Ld), using a response file, and checking the result with $NM Fixes #23542 - - - - - 78b2f3cc by Sylvain Henry at 2023-06-28T21:12:02-04:00 JS: fix JS stack printing (#23565) - - - - - 9f01d14b by Matthew Pickering at 2023-06-29T04:13:41-04:00 Add -fpolymorphic-specialisation flag (off by default at all optimisation levels) Polymorphic specialisation has led to a number of hard to diagnose incorrect runtime result bugs (see #23469, #23109, #21229, #23445) so this commit introduces a flag `-fpolymorhphic-specialisation` which allows users to turn on this experimental optimisation if they are willing to buy into things going very wrong. Ticket #23469 - - - - - b1e611d5 by Ben Gamari at 2023-06-29T04:14:17-04:00 Rip out runtime linker/compiler checks We used to choose flags to pass to the toolchain at runtime based on the platform running GHC, and in this commit we drop all of those runtime linker checks Ultimately, this represents a change in policy: We no longer adapt at runtime to the toolchain being used, but rather make final decisions about the toolchain used at /configure time/ (we have deleted Note [Run-time linker info] altogether!). This works towards the goal of having all toolchain configuration logic living in the same place, which facilities the work towards a runtime-retargetable GHC (see #19877). As of this commit, the runtime linker/compiler logic was moved to autoconf, but soon it, and the rest of the existing toolchain configuration logic, will live in the standalone ghc-toolchain program (see !9263) In particular, what used to be done at runtime is now as follows: * The flags -Wl,--no-as-needed for needed shared libs are configured into settings * The flag -fstack-check is configured into settings * The check for broken tables-next-to-code was outdated * We use the configured c compiler by default as the assembler program * We drop `asmOpts` because we already configure -Qunused-arguments flag into settings (see !10589) Fixes #23562 Co-author: Rodrigo Mesquita (@alt-romes) - - - - - 8b35e8ca by Ben Gamari at 2023-06-29T18:46:12-04:00 Define FFI_GO_CLOSURES The libffi shipped with Apple's XCode toolchain does not contain a definition of the FFI_GO_CLOSURES macro, despite containing references to said macro. Work around this by defining the macro, following the model of a similar workaround in OpenJDK [1]. [1] https://github.com/openjdk/jdk17u-dev/pull/741/files - - - - - d7ef1704 by Ben Gamari at 2023-06-29T18:46:12-04:00 base: Fix incorrect CPP guard This was guarded on `darwin_HOST_OS` instead of `defined(darwin_HOST_OS)`. - - - - - 7c7d1f66 by Ben Gamari at 2023-06-29T18:46:48-04:00 rts/Trace: Ensure that debugTrace arguments are used As debugTrace is a macro we must take care to ensure that the fact is clear to the compiler lest we see warnings. - - - - - cb92051e by Ben Gamari at 2023-06-29T18:46:48-04:00 rts: Various warnings fixes - - - - - dec81dd1 by Ben Gamari at 2023-06-29T18:46:48-04:00 hadrian: Ignore warnings in unix and semaphore-compat - - - - - d7f6448a by Matthew Pickering at 2023-06-30T12:38:43-04:00 hadrian: Fix dependencies of docs:* rule For the docs:* rule we need to actually build the package rather than just the haddocks for the dependent packages. Therefore we depend on the .conf files of the packages we are trying to build documentation for as well as the .haddock files. Fixes #23472 - - - - - cec90389 by sheaf at 2023-06-30T12:39:27-04:00 Add tests for #22106 Fixes #22106 - - - - - 083794b1 by Torsten Schmits at 2023-07-03T03:27:27-04:00 Add -fbreak-points to control breakpoint insertion Rather than statically enabling breakpoints only for the interpreter, this adds a new flag. Tracking ticket: #23057 MR: !10466 - - - - - fd8c5769 by Ben Gamari at 2023-07-03T03:28:04-04:00 rts: Ensure that pinned allocations respect block size Previously, it was possible for pinned, aligned allocation requests to allocate beyond the end of the pinned accumulator block. Specifically, we failed to account for the padding needed to achieve the requested alignment in the "large object" check. With large alignment requests, this can result in the allocator using the capability's pinned object accumulator block to service a request which is larger than `PINNED_EMPTY_SIZE`. To fix this we reorganize `allocatePinned` to consistently account for the alignment padding in all large object checks. This is a bit subtle as we must handle the case of a small allocation request filling the accumulator block, as well as large requests. Fixes #23400. - - - - - 98185d52 by Ben Gamari at 2023-07-03T03:28:05-04:00 testsuite: Add test for #23400 - - - - - 4aac0540 by Ben Gamari at 2023-07-03T03:28:42-04:00 ghc-heap: Support for BLOCKING_QUEUE closures - - - - - 03f941f4 by Ben Bellick at 2023-07-03T03:29:29-04:00 Add some structured diagnostics in Tc/Validity.hs This addresses the work of ticket #20118 Created the following constructors for TcRnMessage - TcRnInaccessibleCoAxBranch - TcRnPatersonCondFailure - - - - - 6074cc3c by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Add failing test case for #23492 - - - - - 356a2692 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Use generated src span for catch-all case of record selector functions This fixes #23492. The problem was that we used the real source span of the field declaration for the generated catch-all case in the selector function, in particular in the generated call to `recSelError`, which meant it was included in the HIE output. Using `generatedSrcSpan` instead means that it is not included. - - - - - 3efe7f39 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Introduce genLHsApp and genLHsLit helpers in GHC.Rename.Utils - - - - - dd782343 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Construct catch-all default case using helpers GHC.Rename.Utils concrete helpers instead of wrapGenSpan + HS AST constructors - - - - - 0e09c38e by Ryan Hendrickson at 2023-07-03T03:30:56-04:00 Add regression test for #23549 - - - - - 32741743 by Alexis King at 2023-07-03T03:31:36-04:00 perf tests: Increase default stack size for MultiLayerModules An unhelpfully small stack size appears to have been the real culprit behind the metric fluctuations in #19293. Debugging metric decreases triggered by !10729 helped to finally identify the problem. Metric Decrease: MultiLayerModules MultiLayerModulesTH_Make T13701 T14697 - - - - - 82ac6bf1 by Bryan Richter at 2023-07-03T03:32:15-04:00 Add missing void prototypes to rts functions See #23561. - - - - - 6078b429 by Ben Gamari at 2023-07-03T03:32:51-04:00 gitlab-ci: Refactor compilation of gen_ci Flakify and document it, making it far less sensitive to the build environment. - - - - - aa2db0ae by Ben Gamari at 2023-07-03T03:33:29-04:00 testsuite: Update documentation - - - - - 924a2362 by Gregory Gerasev at 2023-07-03T03:34:10-04:00 Better error for data deriving of type synonym/family. Closes #23522 - - - - - 4457da2a by Dave Barton at 2023-07-03T03:34:51-04:00 Fix some broken links and typos - - - - - de5830d0 by Ben Gamari at 2023-07-04T22:03:59-04:00 configure: Rip out Solaris dyld check Solaris 11 was released over a decade ago and, moreover, I doubt we have any Solaris users - - - - - 59c5fe1d by doyougnu at 2023-07-04T22:04:56-04:00 CI: add JS release and debug builds, regen CI jobs - - - - - 679bbc97 by Vladislav Zavialov at 2023-07-04T22:05:32-04:00 testsuite: Do not require CUSKs Numerous tests make use of CUSKs (complete user-supplied kinds), a legacy feature scheduled for deprecation. In order to proceed with the said deprecation, the tests have been updated to use SAKS instead (standalone kind signatures). This also allows us to remove the Haskell2010 language pragmas that were added in 115cd3c85a8 to work around the lack of CUSKs in GHC2021. - - - - - 945d3599 by Ben Gamari at 2023-07-04T22:06:08-04:00 gitlab: Drop backport-for-8.8 MR template Its usefulness has long passed. - - - - - 66c721d3 by Alan Zimmerman at 2023-07-04T22:06:44-04:00 EPA: Simplify GHC/Parser.y comb2 Use the HasLoc instance from Ast.hs to allow comb2 to work with anything with a SrcSpan This gets rid of the custom comb2A, comb2Al, comb2N functions, and removes various reLoc calls. - - - - - 2be99b7e by Matthew Pickering at 2023-07-04T22:07:21-04:00 Fix deprecation warning when deprecated identifier is from another module A stray 'Just' was being printed in the deprecation message. Fixes #23573 - - - - - 46c9bcd6 by Ben Gamari at 2023-07-04T22:07:58-04:00 rts: Don't rely on initializers for sigaction_t As noted in #23577, CentOS's ancient toolchain throws spurious missing-field-initializer warnings. - - - - - ec55035f by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Don't treat -Winline warnings as fatal Such warnings are highly dependent upon the toolchain, platform, and build configuration. It's simply too fragile to rely on these. - - - - - 3a09b789 by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Only pass -Wno-nonportable-include-path on Darwin This flag, which was introduced due to #17798, is only understood by Clang and consequently throws warnings on platforms using gcc. Sadly, there is no good way to treat such warnings as non-fatal with `-Werror` so for now we simply make this flag specific to platforms known to use Clang and case-insensitive filesystems (Darwin and Windows). See #23577. - - - - - 4af7eac2 by Mario Blažević at 2023-07-04T22:08:38-04:00 Fixed ticket #23571, TH.Ppr.pprLit hanging on large numeric literals - - - - - 2304c697 by Ben Gamari at 2023-07-04T22:09:15-04:00 compiler: Make OccSet opaque - - - - - cf735db8 by Andrei Borzenkov at 2023-07-04T22:09:51-04:00 Add Note about why we need forall in Code to be on the right - - - - - fb140f82 by Hécate Moonlight at 2023-07-04T22:10:34-04:00 Relax the constraint about the foreign function's calling convention of FinalizerPtr to capi as well as ccall. - - - - - 9ce44336 by meooow25 at 2023-07-05T11:42:37-04:00 Improve the situation with the stimes cycle Currently the Semigroup stimes cycle is resolved in GHC.Base by importing stimes implementations from a hs-boot file. Resolve the cycle using hs-boot files for required classes (Num, Integral) instead. Now stimes can be defined directly in GHC.Base, making inlining and specialization possible. This leads to some new boot files for `GHC.Num` and `GHC.Real`, the methods for those are only used to implement `stimes` so it doesn't appear that these boot files will introduce any new performance traps. Metric Decrease: T13386 T8095 Metric Increase: T13253 T13386 T18698a T18698b T19695 T8095 - - - - - 9edcb1fb by Jaro Reinders at 2023-07-05T11:43:24-04:00 Refactor Unique to be represented by Word64 In #22010 we established that Int was not always sufficient to store all the uniques we generate during compilation on 32-bit platforms. This commit addresses that problem by using Word64 instead of Int for uniques. The core of the change is in GHC.Core.Types.Unique and GHC.Core.Types.Unique.Supply. However, the representation of uniques is used in many other places, so those needed changes too. Additionally, the RTS has been extended with an atomic_inc64 operation. One major change from this commit is the introduction of the Word64Set and Word64Map data types. These are adapted versions of IntSet and IntMap from the containers package. These are planned to be upstreamed in the future. As a natural consequence of these changes, the compiler will be a bit slower and take more space on 32-bit platforms. Our CI tests indicate around a 5% residency increase. Metric Increase: CoOpt_Read CoOpt_Singletons LargeRecord ManyAlternatives ManyConstructors MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot RecordUpdPerf T10421 T10547 T12150 T12227 T12234 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T13386 T13719 T14683 T14697 T14766 T15164 T15703 T16577 T16875 T17516 T18140 T18223 T18282 T18304 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T3294 T4801 T5030 T5321FD T5321Fun T5631 T5642 T5837 T6048 T783 T8095 T9020 T9198 T9233 T9630 T9675 T9872a T9872b T9872b_defer T9872c T9872d T9961 TcPlugin_RewritePerf UniqLoop WWRec hard_hole_fits - - - - - 6b9db7d4 by Brandon Chinn at 2023-07-05T11:44:03-04:00 Fix docs for __GLASGOW_HASKELL_FULL_VERSION__ macro - - - - - 40f4ef7c by Torsten Schmits at 2023-07-05T18:06:19-04:00 Substitute free variables captured by breakpoints in SpecConstr Fixes #23267 - - - - - 2b55cb5f by sheaf at 2023-07-05T18:07:07-04:00 Reinstate untouchable variable error messages This extra bit of information was accidentally being discarded after a refactoring of the way we reported problems when unifying a type variable with another type. This patch rectifies that. - - - - - 53ed21c5 by Rodrigo Mesquita at 2023-07-05T18:07:47-04:00 configure: Drop Clang command from settings Due to 01542cb7227614a93508b97ecad5b16dddeb6486 we no longer use the `runClang` function, and no longer need to configure into settings the Clang command. We used to determine options at runtime to pass clang when it was used as an assembler, but now that we configure at configure time we no longer need to. - - - - - 6fdcf969 by Torsten Schmits at 2023-07-06T12:12:09-04:00 Filter out nontrivial substituted expressions in substTickish Fixes #23272 - - - - - 41968fd6 by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: testsuite: use req_c predicate instead of js_broken - - - - - 74a4dd2e by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: implement some file primitives (lstat,rmdir) (#22374) - Implement lstat and rmdir. - Implement base_c_s_is* functions (testing a file type) - Enable passing tests - - - - - 7e759914 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: cleanup utils (#23314) - Removed unused code - Don't export unused functions - Move toTypeList to Closure module - - - - - f617655c by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: rename VarType/Vt into JSRep - - - - - 19216ca5 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: remove custom PrimRep conversion (#23314) We use the usual conversion to PrimRep and then we convert these PrimReps to JSReps. - - - - - d3de8668 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: don't use isRuntimeRepKindedTy in JS FFI - - - - - 8d1b75cb by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Also updates ghcup-nightlies-0.0.7.yaml file Fixes #23600 - - - - - e524fa7f by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Use dynamically linked alpine bindists In theory these will work much better on alpine to allow people to build statically linked applications there. We don't need to distribute a statically linked application ourselves in order to allow that. Fixes #23602 - - - - - b9e7beb9 by Ben Gamari at 2023-07-07T11:32:22-04:00 Drop circle-ci-job.sh - - - - - 9955eead by Ben Gamari at 2023-07-07T11:32:22-04:00 testsuite: Allow preservation of unexpected output Here we introduce a new flag to the testsuite driver, --unexpected-output-dir=<dir>, which allows the user to ask the driver to preserve unexpected output from tests. The intent is for this to be used in CI to allow users to more easily fix unexpected platform-dependent output. - - - - - 48f80968 by Ben Gamari at 2023-07-07T11:32:22-04:00 gitlab-ci: Preserve unexpected output Here we enable use of the testsuite driver's `--unexpected-output-dir` flag by CI, preserving the result as an artifact for use by users. - - - - - 76983a0d by Matthew Pickering at 2023-07-07T11:32:58-04:00 driver: Fix -S with .cmm files There was an oversight in the driver which assumed that you would always produce a `.o` file when compiling a .cmm file. Fixes #23610 - - - - - 6df15e93 by Mike Pilgrem at 2023-07-07T11:33:40-04:00 Update Hadrian's stack.yaml - - - - - 1dff43cf by Ben Gamari at 2023-07-08T05:05:37-04:00 compiler: Rework ShowSome Previously the field used to filter the sub-declarations to show was rather ad-hoc and was only able to show at most one sub-declaration. - - - - - 8165404b by Ben Gamari at 2023-07-08T05:05:37-04:00 testsuite: Add test to catch changes in core libraries This adds testing infrastructure to ensure that changes in core libraries (e.g. `base` and `ghc-prim`) are caught in CI. - - - - - ec1c32e2 by Melanie Phoenix at 2023-07-08T05:06:14-04:00 Deprecate Data.List.NonEmpty.unzip - - - - - 5d2442b8 by Ben Gamari at 2023-07-08T05:06:51-04:00 Drop latent mentions of -split-objs Closes #21134. - - - - - a9bc20cb by Oleg Grenrus at 2023-07-08T05:07:31-04:00 Add warn_and_run test kind This is a compile_and_run variant which also captures the GHC's stderr. The warn_and_run name is best I can come up with, as compile_and_run is taken. This is useful specifically for testing warnings. We want to test that when warning triggers, and it's not a false positive, i.e. that the runtime behaviour is indeed "incorrect". As an example a single test is altered to use warn_and_run - - - - - c7026962 by Ben Gamari at 2023-07-08T05:08:11-04:00 configure: Don't use ld.gold on i386 ld.gold appears to produce invalid static constructor tables on i386. While ideally we would add an autoconf check to check for this brokenness, sadly such a check isn't easy to compose. Instead to summarily reject such linkers on i386. Somewhat hackily closes #23579. - - - - - 054261dd by Andrew Lelechenko at 2023-07-08T19:32:47-04:00 Add since annotations for Data.Foldable1 - - - - - 550af505 by Sylvain Henry at 2023-07-08T19:33:28-04:00 JS: support -this-unit-id for programs in the linker (#23613) - - - - - d284470a by Andrew Lelechenko at 2023-07-08T19:34:08-04:00 Bump text submodule - - - - - 8e11630e by jade at 2023-07-10T16:58:40-04:00 Add a hint to enable ExplicitNamespaces for type operator imports (Fixes/Enhances #20007) As suggested in #20007 and implemented in !8895, trying to import type operators will suggest a fix to use the 'type' keyword, without considering whether ExplicitNamespaces is enabled. This patch will query whether ExplicitNamespaces is enabled and add a hint to suggest enabling ExplicitNamespaces if it isn't enabled, alongside the suggestion of adding the 'type' keyword. - - - - - 61b1932e by sheaf at 2023-07-10T16:59:26-04:00 tyThingLocalGREs: include all DataCons for RecFlds The GREInfo for a record field should include the collection of all the data constructors of the parent TyCon that have this record field. This information was being incorrectly computed in the tyThingLocalGREs function for a DataCon, as we were not taking into account other DataCons with the same parent TyCon. Fixes #23546 - - - - - e6627cbd by Alan Zimmerman at 2023-07-10T17:00:05-04:00 EPA: Simplify GHC/Parser.y comb3 A follow up to !10743 - - - - - ee20da34 by Andrew Lelechenko at 2023-07-10T17:01:01-04:00 Document that compareByteArrays# is available since ghc-prim-0.5.2.0 - - - - - 4926af7b by Matthew Pickering at 2023-07-10T17:01:38-04:00 Revert "Bump text submodule" This reverts commit d284470a77042e6bc17bdb0ab0d740011196958a. This commit requires that we bootstrap with ghc-9.4, which we do not require until #23195 has been completed. Subsequently this has broken nighty jobs such as the rocky8 job which in turn has broken nightly releases. - - - - - d1c92bf3 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Fingerprint more code generation flags Previously our recompilation check was quite inconsistent in its coverage of non-optimisation code generation flags. Specifically, we failed to account for most flags that would affect the behavior of generated code in ways that might affect the result of a program's execution (e.g. `-feager-blackholing`, `-fstrict-dicts`) Closes #23369. - - - - - eb623149 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Record original thunk info tables on stack Here we introduce a new code generation option, `-forig-thunk-info`, which ensures that an `stg_orig_thunk_info` frame is pushed before every update frame. This can be invaluable when debugging thunk cycles and similar. See Note [Original thunk info table frames] for details. Closes #23255. - - - - - 4731f44e by Jaro Reinders at 2023-07-11T08:07:40-04:00 Fix wrong MIN_VERSION_GLASGOW_HASKELL macros I forgot to change these after rebasing. - - - - - dd38aca9 by Andreas Schwab at 2023-07-11T13:55:56+00:00 Hadrian: enable GHCi support on riscv64 - - - - - 09a5c6cc by Josh Meredith at 2023-07-12T11:25:13-04:00 JavaScript: support unicode code points > 2^16 in toJSString using String.fromCodePoint (#23628) - - - - - 29fbbd4e by Matthew Pickering at 2023-07-12T11:25:49-04:00 Remove references to make build system in mk/build.mk Fixes #23636 - - - - - 630e3026 by sheaf at 2023-07-12T11:26:43-04:00 Valid hole fits: don't panic on a Given The function GHC.Tc.Errors.validHoleFits would end up panicking when encountering a Given constraint. To fix this, it suffices to filter out the Givens before continuing. Fixes #22684 - - - - - c39f279b by Matthew Pickering at 2023-07-12T23:18:38-04:00 Use deb10 for i386 bindists deb9 is now EOL so it's time to upgrade the i386 bindist to use deb10 Fixes #23585 - - - - - bf9b9de0 by Krzysztof Gogolewski at 2023-07-12T23:19:15-04:00 Fix #23567, a specializer bug Found by Simon in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507834 The testcase isn't ideal because it doesn't detect the bug in master, unless doNotUnbox is removed as in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507692. But I have confirmed that with that modification, it fails before and passes afterwards. - - - - - 84c1a4a2 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 Comments - - - - - b2846cb5 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 updates to comments - - - - - 2af23f0e by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 changes - - - - - 6143838a by sheaf at 2023-07-13T08:02:17-04:00 Fix deprecation of record fields Commit 3f374399 inadvertently broke the deprecation/warning mechanism for record fields due to its introduction of record field namespaces. This patch ensures that, when a top-level deprecation is applied to an identifier, it applies to all the record fields as well. This is achieved by refactoring GHC.Rename.Env.lookupLocalTcNames, and GHC.Rename.Env.lookupBindGroupOcc, to not look up a fixed number of NameSpaces but to look up all NameSpaces and filter out the irrelevant ones. - - - - - 6fd8f566 by sheaf at 2023-07-13T08:02:17-04:00 Introduce greInfo, greParent These are simple helper functions that wrap the internal field names gre_info, gre_par. - - - - - 7f0a86ed by sheaf at 2023-07-13T08:02:17-04:00 Refactor lookupGRE_... functions This commit consolidates all the logic for looking up something in the Global Reader Environment into the single function lookupGRE. This allows us to declaratively specify all the different modes of looking up in the GlobalRdrEnv, and avoids manually passing around filtering functions as was the case in e.g. the function GHC.Rename.Env.lookupSubBndrOcc_helper. ------------------------- Metric Decrease: T8095 ------------------------- ------------------------- Metric Increase: T8095 ------------------------- - - - - - 5e951395 by Rodrigo Mesquita at 2023-07-13T08:02:54-04:00 configure: Drop DllWrap command We used to configure into settings a DllWrap command for windows builds and distributions, however, we no longer do, and dllwrap is effectively unused. This simplification is motivated in part by the larger toolchain-selection project (#19877, !9263) - - - - - e10556b6 by Teo Camarasu at 2023-07-14T16:28:46-04:00 base: fix haddock syntax in GHC.Profiling - - - - - 0f3fda81 by Matthew Pickering at 2023-07-14T16:29:23-04:00 Revert "CI: add JS release and debug builds, regen CI jobs" This reverts commit 59c5fe1d4b624423b1c37891710f2757bb58d6af. This commit added two duplicate jobs on all validate pipelines, so we are reverting for now whilst we work out what the best way forward is. Ticket #23618 - - - - - 54bca324 by Alan Zimmerman at 2023-07-15T03:23:26-04:00 EPA: Simplify GHC/Parser.y sLL Follow up to !10743 - - - - - c8863828 by sheaf at 2023-07-15T03:24:06-04:00 Configure: canonicalise PythonCmd on Windows This change makes PythonCmd resolve to a canonical absolute path on Windows, which prevents HLS getting confused (now that we have a build-time dependency on python). fixes #23652 - - - - - ca1e636a by Rodrigo Mesquita at 2023-07-15T03:24:42-04:00 Improve Note [Binder-swap during float-out] - - - - - cf86f3ec by Matthew Craven at 2023-07-16T01:42:09+02:00 Equality of forall-types is visibility aware This patch finally (I hope) nails the question of whether (forall a. ty) and (forall a -> ty) are `eqType`: they aren't! There is a long discussion in #22762, plus useful Notes: * Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare * Note [Comparing visiblities] in GHC.Core.TyCo.Compare * Note [ForAllCo] in GHC.Core.TyCo.Rep It also establishes a helpful new invariant for ForAllCo, and ForAllTy, when the bound variable is a CoVar:in that case the visibility must be coreTyLamForAllTyFlag. All this is well documented in revised Notes. - - - - - 7f13acbf by Vladislav Zavialov at 2023-07-16T01:56:27-04:00 List and Tuple<n>: update documentation Add the missing changelog.md entries and @since-annotations. - - - - - 2afbddb0 by Andrei Borzenkov at 2023-07-16T10:21:24+04:00 Type patterns (#22478, #18986) Improved name resolution and type checking of type patterns in constructors: 1. HsTyPat: a new dedicated data type that represents type patterns in HsConPatDetails instead of reusing HsPatSigType 2. rnHsTyPat: a new function that renames a type pattern and collects its binders into three groups: - explicitly bound type variables, excluding locally bound variables - implicitly bound type variables from kind signatures (only if ScopedTypeVariables are enabled) - named wildcards (only from kind signatures) 2a. rnHsPatSigTypeBindingVars: removed in favour of rnHsTyPat 2b. rnImplcitTvBndrs: removed because no longer needed 3. collect_pat: updated to collect type variable binders from type patterns (this means that types and terms use the same infrastructure to detect conflicting bindings, unused variables and name shadowing) 3a. CollVarTyVarBinders: a new CollectFlag constructor that enables collection of type variables 4. tcHsTyPat: a new function that typechecks type patterns, capable of handling polymorphic kinds. See Note [Type patterns: binders and unifiers] Examples of code that is now accepted: f = \(P @a) -> \(P @a) -> ... -- triggers -Wname-shadowing g :: forall a. Proxy a -> ... g (P @a) = ... -- also triggers -Wname-shadowing h (P @($(TH.varT (TH.mkName "t")))) = ... -- t is bound at splice time j (P @(a :: (x,x))) = ... -- (x,x) is no longer rejected data T where MkT :: forall (f :: forall k. k -> Type). f Int -> f Maybe -> T k :: T -> () k (MkT @f (x :: f Int) (y :: f Maybe)) = () -- f :: forall k. k -> Type Examples of code that is rejected with better error messages: f (Left @a @a _) = ... -- new message: -- • Conflicting definitions for ‘a’ -- Bound at: Test.hs:1:11 -- Test.hs:1:14 Examples of code that is now rejected: {-# OPTIONS_GHC -Werror=unused-matches #-} f (P @a) = () -- Defined but not used: type variable ‘a’ - - - - - eb1a6ab1 by sheaf at 2023-07-16T09:20:45-04:00 Don't use substTyUnchecked in newMetaTyVar There were some comments that explained that we needed to use an unchecked substitution function because of issue #12931, but that has since been fixed, so we should be able to use substTy instead now. - - - - - c7bbad9a by sheaf at 2023-07-17T02:48:19-04:00 rnImports: var shouldn't import NoFldSelectors In an import declaration such as import M ( var ) the import of the variable "var" should **not** bring into scope record fields named "var" which are defined with NoFieldSelectors. Doing so can cause spurious "unused import" warnings, as reported in ticket #23557. Fixes #23557 - - - - - 1af2e773 by sheaf at 2023-07-17T02:48:19-04:00 Suggest similar names in imports This commit adds similar name suggestions when importing. For example module A where { spelling = 'o' } module B where { import B ( speling ) } will give rise to the error message: Module ‘A’ does not export ‘speling’. Suggested fix: Perhaps use ‘spelling’ This also provides hints when users try to import record fields defined with NoFieldSelectors. - - - - - 654fdb98 by Alan Zimmerman at 2023-07-17T02:48:55-04:00 EPA: Store leading AnnSemi for decllist in al_rest This simplifies the markAnnListA implementation in ExactPrint - - - - - 22565506 by sheaf at 2023-07-17T21:12:59-04:00 base: add COMPLETE pragma to BufferCodec PatSyn This implements CLC proposal #178, rectifying an oversight in the implementation of CLC proposal #134 which could lead to spurious pattern match warnings. https://github.com/haskell/core-libraries-committee/issues/178 https://github.com/haskell/core-libraries-committee/issues/134 - - - - - 860f6269 by sheaf at 2023-07-17T21:13:00-04:00 exactprint: silence incomplete record update warnings - - - - - df706de3 by sheaf at 2023-07-17T21:13:00-04:00 Re-instate -Wincomplete-record-updates Commit e74fc066 refactored the handling of record updates to use the HsExpanded mechanism. This meant that the pattern matching inherent to a record update was considered to be "generated code", and thus we stopped emitting "incomplete record update" warnings entirely. This commit changes the "data Origin = Source | Generated" datatype, adding a field to the Generated constructor to indicate whether we still want to perform pattern-match checking. We also have to do a bit of plumbing with HsCase, to record that the HsCase arose from an HsExpansion of a RecUpd, so that the error message continues to mention record updates as opposed to a generic "incomplete pattern matches in case" error. Finally, this patch also changes the way we handle inaccessible code warnings. Commit e74fc066 was also a regression in this regard, as we were emitting "inaccessible code" warnings for case statements spuriously generated when desugaring a record update (remember: the desugaring mechanism happens before typechecking; it thus can't take into account e.g. GADT information in order to decide which constructors to include in the RHS of the desugaring of the record update). We fix this by changing the mechanism through which we disable inaccessible code warnings: we now check whether we are in generated code in GHC.Tc.Utils.TcMType.newImplication in order to determine whether to emit inaccessible code warnings. Fixes #23520 Updates haddock submodule, to avoid incomplete record update warnings - - - - - 1d05971e by sheaf at 2023-07-17T21:13:00-04:00 Propagate long-distance information in do-notation The preceding commit re-enabled pattern-match checking inside record updates. This revealed that #21360 was in fact NOT fixed by e74fc066. This commit makes sure we correctly propagate long-distance information in do blocks, e.g. in ```haskell data T = A { fld :: Int } | B f :: T -> Maybe T f r = do a at A{} <- Just r Just $ case a of { A _ -> A 9 } ``` we need to propagate the fact that "a" is headed by the constructor "A" to see that the case expression "case a of { A _ -> A 9 }" cannot fail. Fixes #21360 - - - - - bea0e323 by sheaf at 2023-07-17T21:13:00-04:00 Skip PMC for boring patterns Some patterns introduce no new information to the pattern-match checker (such as plain variable or wildcard patterns). We can thus skip doing any pattern-match checking on them when the sole purpose for doing so was introducing new long-distance information. See Note [Boring patterns] in GHC.Hs.Pat. Doing this avoids regressing in performance now that we do additional pattern-match checking inside do notation. - - - - - ddcdd88c by Rodrigo Mesquita at 2023-07-17T21:13:36-04:00 Split GHC.Platform.ArchOS from ghc-boot into ghc-platform Split off the `GHC.Platform.ArchOS` module from the `ghc-boot` package into this reinstallable standalone package which abides by the PVP, in part motivated by the ongoing work on `ghc-toolchain` towards runtime retargetability. - - - - - b55a8ea7 by Sylvain Henry at 2023-07-17T21:14:27-04:00 JS: better implementation for plusWord64 (#23597) - - - - - 889c2bbb by sheaf at 2023-07-18T06:37:32-04:00 Do primop rep-poly checks when instantiating This patch changes how we perform representation-polymorphism checking for primops (and other wired-in Ids such as coerce). When instantiating the primop, we check whether each type variable is required to instantiated to a concrete type, and if so we create a new concrete metavariable (a ConcreteTv) instead of a simple MetaTv. (A little subtlety is the need to apply the substitution obtained from instantiating to the ConcreteTvOrigins, see Note [substConcreteTvOrigin] in GHC.Tc.Utils.TcMType.) This allows us to prevent representation-polymorphism in non-argument position, as that is required for some of these primops. We can also remove the logic in tcRemainingValArgs, except for the part concerning representation-polymorphic unlifted newtypes. The function has been renamed rejectRepPolyNewtypes; all it does now is reject unsaturated occurrences of representation-polymorphic newtype constructors when the representation of its argument isn't a concrete RuntimeRep (i.e. still a PHASE 1 FixedRuntimeRep check). The Note [Eta-expanding rep-poly unlifted newtypes] in GHC.Tc.Gen.Head gives more explanation about a possible path to PHASE 2, which would be in line with the treatment for primops taken in this patch. We also update the Core Lint check to handle this new framework. This means Core Lint now checks representation-polymorphism in continuation position like needed for catch#. Fixes #21906 ------------------------- Metric Increase: LargeRecord ------------------------- - - - - - 00648e5d by Krzysztof Gogolewski at 2023-07-18T06:38:10-04:00 Core Lint: distinguish let and letrec in locations Lint messages were saying "in the body of letrec" even for non-recursive let. I've also renamed BodyOfLetRec to BodyOfLet in stg, since there's no separate letrec. - - - - - 787bae96 by Krzysztof Gogolewski at 2023-07-18T06:38:50-04:00 Use extended literals when deriving Show This implements GHC proposal https://github.com/ghc-proposals/ghc-proposals/pull/596 Also add support for Int64# and Word64#; see testcase ShowPrim. - - - - - 257f1567 by Jaro Reinders at 2023-07-18T06:39:29-04:00 Add StgFromCore and StgCodeGen linting - - - - - 34d08a20 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Strictness - - - - - c5deaa27 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Don't repeatedly construct UniqSets - - - - - b947250b by Ben Gamari at 2023-07-19T03:33:22-04:00 compiler/Types: Ensure that fromList-type operations can fuse In #20740 I noticed that mkUniqSet does not fuse. In practice, allowing it to do so makes a considerable difference in allocations due to the backend. Metric Decrease: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 6c88c2ba by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 Codegen: Implement MO_S_MulMayOflo for W16 - - - - - 5f1154e0 by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: MO_S_MulMayOflo better error message for rep > W64 It's useful to see which value made the pattern match fail. (If it ever occurs.) - - - - - e8c9a95f by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: Implement MO_S_MulMayOflo for W8 This case wasn't handled before. But, the test-primops test suite showed that it actually might appear. - - - - - a36f9dc9 by Sven Tennie at 2023-07-19T03:33:59-04:00 Add test for %mulmayoflo primop The test expects a perfect implementation with no false positives. - - - - - 38a36248 by Matthew Pickering at 2023-07-19T03:34:36-04:00 lint-ci-config: Generate jobs-metadata.json We also now save the jobs-metadata.json and jobs.yaml file as artifacts as: * It might be useful for someone who is modifying CI to copy jobs.yaml if they are having trouble regenerating locally. * jobs-metadata.json is very useful for downstream pipelines to work out the right job to download. Fixes #23654 - - - - - 1535a671 by Vladislav Zavialov at 2023-07-19T03:35:12-04:00 Initialize 9.10.1-notes.rst Create new release notes for the next GHC release (GHC 9.10) - - - - - 3bd4d5b5 by sheaf at 2023-07-19T03:35:53-04:00 Prioritise Parent when looking up class sub-binder When we look up children GlobalRdrElts of a given Parent, we sometimes would rather prioritise those GlobalRdrElts which have the right Parent, and sometimes prioritise those that have the right NameSpace: - in export lists, we should prioritise NameSpace - for class/instance binders, we should prioritise Parent See Note [childGREPriority] in GHC.Types.Name.Reader. fixes #23664 - - - - - 9c8fdda3 by Alan Zimmerman at 2023-07-19T03:36:29-04:00 EPA: Improve annotation management in getMonoBind Ensure the LHsDecl for a FunBind has the correct leading comments and trailing annotations. See the added note for details. - - - - - ff884b77 by Matthew Pickering at 2023-07-19T11:42:02+01:00 Remove unused files in .gitlab These were left over after 6078b429 - - - - - 29ef590c by Matthew Pickering at 2023-07-19T11:42:52+01:00 gen_ci: Add hie.yaml file This allows you to load `gen_ci.hs` into HLS, and now it is a huge module, that is quite useful. - - - - - 808b55cf by Matthew Pickering at 2023-07-19T12:24:41+01:00 ci: Make "fast-ci" the default validate configuration We are trying out a lighter weight validation pipeline where by default we just test on 5 platforms: * x86_64-deb10-slow-validate * windows * x86_64-fedora33-release * aarch64-darwin * aarch64-linux-deb10 In order to enable the "full" validation pipeline you can apply the `full-ci` label which will enable all the validation pipelines. All the validation jobs are still run on a marge batch. The goal is to reduce the overall CI capacity so that pipelines start faster for MRs and marge bot batches are faster. Fixes #23694 - - - - - 0b23db03 by Alan Zimmerman at 2023-07-20T05:28:47-04:00 EPA: Simplify GHC/Parser.y sL1 This is the next patch in a series simplifying location management in GHC/Parser.y This one simplifies sL1, to use the HasLoc instances introduced in !10743 (closed) - - - - - 3ece9856 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Explicitly set flags of text sections on Windows The binutils documentation (for COFF) claims, > If no flags are specified, the default flags depend upon the section > name. If the section name is not recognized, the default will be for the > section to be loaded and writable. We previously assumed that this would do the right thing for split sections (e.g. a section named `.text$foo` would be correctly inferred to be a text section). However, we have observed that this is not the case (at least under the clang toolchain used on Windows): when split-sections is enabled, text sections are treated by the assembler as data (matching the "default" behavior specified by the documentation). Avoid this by setting section flags explicitly. This should fix split sections on Windows. Fixes #22834. - - - - - db7f7240 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Set explicit section types on all platforms - - - - - b444c16f by Finley McIlwaine at 2023-07-21T07:31:28-04:00 Insert documentation into parsed signature modules Causes haddock comments in signature modules to be properly inserted into the AST (just as they are for regular modules) if the `-haddock` flag is given. Also adds a test that compares `-ddump-parsed-ast` output for a signature module to prevent further regressions. Fixes #23315 - - - - - c30cea53 by Ben Gamari at 2023-07-21T23:23:49-04:00 primops: Introduce unsafeThawByteArray# This addresses an odd asymmetry in the ByteArray# primops, which previously provided unsafeFreezeByteArray# but no corresponding thaw operation. Closes #22710 - - - - - 87f9bd47 by Ben Gamari at 2023-07-21T23:23:49-04:00 testsuite: Elaborate in interface stability README This discussion didn't make it into the original MR. - - - - - e4350b41 by Matthew Pickering at 2023-07-21T23:24:25-04:00 Allow users to override non-essential haddock options in a Flavour We now supply the non-essential options to haddock using the `extraArgs` field, which can be specified in a Flavour so that if an advanced user wants to change how documentation is generated then they can use something other than the `defaultHaddockExtraArgs`. This does have the potential to regress some packaging if a user has overridden `extraArgs` themselves, because now they also need to add the haddock options to extraArgs. This can easily be done by appending `defaultHaddockExtraArgs` to their extraArgs invocation but someone might not notice this behaviour has changed. In any case, I think passing the non-essential options in this manner is the right thing to do and matches what we do for the "ghc" builder, which by default doesn't pass any optmisation levels, and would likewise be very bad if someone didn't pass suitable `-O` levels for builds. Fixes #23625 - - - - - fc186b0c by Ilias Tsitsimpis at 2023-07-21T23:25:03-04:00 ghc-prim: Link against libatomic Commit b4d39adbb58 made 'hs_cmpxchg64()' available to all architectures. Unfortunately this made GHC to fail to build on armel, since armel needs libatomic to support atomic operations on 64-bit word sizes. Configure libraries/ghc-prim/ghc-prim.cabal to link against libatomic, the same way as we do in rts/rts.cabal. - - - - - 4f5538a8 by Matthew Pickering at 2023-07-21T23:25:39-04:00 simplifier: Correct InScopeSet in rule matching The in-scope set passedto the `exprIsLambda_maybe` call lacked all the in-scope binders. @simonpj suggests this fix where we augment the in-scope set with the free variables of expression which fixes this failure mode in quite a direct way. Fixes #23630 - - - - - 5ad8d597 by Krzysztof Gogolewski at 2023-07-21T23:26:17-04:00 Add a test for #23413 It was fixed by commit e1590ddc661d6: Add the SolverStage monad. - - - - - 7e05f6df by sheaf at 2023-07-21T23:26:56-04:00 Finish migration of diagnostics in GHC.Tc.Validity This patch finishes migrating the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It also refactors the error message datatypes for class and family instances, to common them up under a single datatype as much as possible. - - - - - 4876fddc by Matthew Pickering at 2023-07-21T23:27:33-04:00 ci: Enable some more jobs to run in a marge batch In !10907 I made the majority of jobs not run on a validate pipeline but then forgot to renable a select few jobs on the marge batch MR. - - - - - 026991d7 by Jens Petersen at 2023-07-21T23:28:13-04:00 user_guide/flags.py: python-3.12 no longer includes distutils packaging.version seems able to handle this fine - - - - - b91bbc2b by Matthew Pickering at 2023-07-21T23:28:50-04:00 ci: Mention ~full-ci label in MR template We mention that if you need a full validation pipeline then you can apply the ~full-ci label to your MR in order to test against the full validation pipeline (like we do for marge). - - - - - 42b05e9b by sheaf at 2023-07-22T12:36:00-04:00 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 - - - - - a72015d6 by sheaf at 2023-07-22T12:36:01-04:00 Mark plugins-external as broken on Windows This test is broken on Windows, so we explicitly mark it as such now that we stop skipping plugin tests on Windows. - - - - - cb9c93d7 by sheaf at 2023-07-22T12:36:01-04:00 Stop marking plugin tests as fragile on Windows Now that b2bb3e62 has landed we are in a better situation with regards to plugins on Windows, allowing us to unmark many plugin tests as fragile. Fixes #16405 - - - - - a7349217 by Krzysztof Gogolewski at 2023-07-22T12:36:37-04:00 Misc cleanup - Remove unused RDR names - Fix typos in comments - Deriving: simplify boxConTbl and remove unused litConTbl - chmod -x GHC/Exts.hs, this seems accidental - - - - - 33b6850a by Vladislav Zavialov at 2023-07-23T10:27:37-04:00 Visible forall in types of terms: Part 1 (#22326) This patch implements part 1 of GHC Proposal #281, introducing explicit `type` patterns and `type` arguments. Summary of the changes: 1. New extension flag: RequiredTypeArguments 2. New user-facing syntax: `type p` patterns (represented by EmbTyPat) `type e` expressions (represented by HsEmbTy) 3. Functions with required type arguments (visible forall) can now be defined and applied: idv :: forall a -> a -> a -- signature (relevant change: checkVdqOK in GHC/Tc/Validity.hs) idv (type a) (x :: a) = x -- definition (relevant change: tcPats in GHC/Tc/Gen/Pat.hs) x = idv (type Int) 42 -- usage (relevant change: tcInstFun in GHC/Tc/Gen/App.hs) 4. template-haskell support: TH.TypeE corresponds to HsEmbTy TH.TypeP corresponds to EmbTyPat 5. Test cases and a new User's Guide section Changes *not* included here are the t2t (term-to-type) transformation and term variable capture; those belong to part 2. - - - - - 73b5c7ce by sheaf at 2023-07-23T10:28:18-04:00 Add test for #22424 This is a simple Template Haskell test in which we refer to record selectors by their exact Names, in two different ways. Fixes #22424 - - - - - 83cbc672 by Ben Gamari at 2023-07-24T07:40:49+00:00 ghc-toolchain: Initial commit - - - - - 31dcd26c by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 ghc-toolchain: Toolchain Selection This commit integrates ghc-toolchain, the brand new way of configuring toolchains for GHC, with the Hadrian build system, with configure, and extends and improves the first iteration of ghc-toolchain. The general overview is * We introduce a program invoked `ghc-toolchain --triple=...` which, when run, produces a file with a `Target`. A `GHC.Toolchain.Target.Target` describes the properties of a target and the toolchain (executables and configured flags) to produce code for that target * Hadrian was modified to read Target files, and will both * Invoke the toolchain configured in the Target file as needed * Produce a `settings` file for GHC based on the Target file for that stage * `./configure` will invoke ghc-toolchain to generate target files, but it will also generate target files based on the flags configure itself configured (through `.in` files that are substituted) * By default, the Targets generated by configure are still (for now) the ones used by Hadrian * But we additionally validate the Target files generated by ghc-toolchain against the ones generated by configure, to get a head start on catching configuration bugs before we transition completely. * When we make that transition, we will want to drop a lot of the toolchain configuration logic from configure, but keep it otherwise. * For each compiler stage we should have 1 target file (up to a stage compiler we can't run in our machine) * We just have a HOST target file, which we use as the target for stage0 * And a TARGET target file, which we use for stage1 (and later stages, if not cross compiling) * Note there is no BUILD target file, because we only support cross compilation where BUILD=HOST * (for more details on cross-compilation see discussion on !9263) See also * Note [How we configure the bundled windows toolchain] * Note [ghc-toolchain consistency checking] * Note [ghc-toolchain overview] Ticket: #19877 MR: !9263 - - - - - a732b6d3 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Add flag to enable/disable ghc-toolchain based configurations This flag is disabled by default, and we'll use the configure-generated-toolchains by default until we remove the toolchain configuration logic from configure. - - - - - 61eea240 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Split ghc-toolchain executable to new packge In light of #23690, we split the ghc-toolchain executable out of the library package to be able to ship it in the bindist using Hadrian. Ideally, we eventually revert this commit. - - - - - 38e795ff by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Ship ghc-toolchain in the bindist Add the ghc-toolchain binary to the binary distribution we ship to users, and teach the bindist configure to use the existing ghc-toolchain. - - - - - 32cae784 by Matthew Craven at 2023-07-24T16:48:24-04:00 Kill off gen_bytearray_addr_access_ops.py The relevant primop descriptions are now generated directly by genprimopcode. This makes progress toward fixing #23490, but it is not a complete fix since there is more than one way in which cabal-reinstall (hadrian/build build-cabal) is broken. - - - - - 02e6a6ce by Matthew Pickering at 2023-07-24T16:49:00-04:00 compiler: Remove unused `containers.h` include Fixes #23712 - - - - - 822ef66b by Matthew Pickering at 2023-07-25T08:44:50-04:00 Fix pretty printing of WARNING pragmas There is still something quite unsavoury going on with WARNING pragma printing because the printing relies on the fact that for decl deprecations the SourceText of WarningTxt is empty. However, I let that lion sleep and just fixed things directly. Fixes #23465 - - - - - e7b38ede by Matthew Pickering at 2023-07-25T08:45:28-04:00 ci-images: Bump to commit which has 9.6 image The test-bootstrap job has been failing for 9.6 because we accidentally used a non-master commit. - - - - - bb408936 by Matthew Pickering at 2023-07-25T08:45:28-04:00 Update bootstrap plans for 9.6.2 and 9.4.5 - - - - - 355e1792 by Alan Zimmerman at 2023-07-26T10:17:32-04:00 EPA: Simplify GHC/Parser.y comb4/comb5 Use the HasLoc instance from Ast.hs to allow comb4/comb5 to work with anything with a SrcSpan Also get rid of some more now unnecessary reLoc calls. - - - - - 9393df83 by Gavin Zhao at 2023-07-26T10:18:16-04:00 compiler: make -ddump-asm work with wasm backend NCG Fixes #23503. Now the `-ddump-asm` flag is respected in the wasm backend NCG, so developers can directly view the generated ASM instead of needing to pass `-S` or `-keep-tmp-files` and manually find & open the assembly file. Ideally, we should be able to output the assembly files in smaller chunks like in other NCG backends. This would also make dumping assembly stats easier. However, this would require a large refactoring, so for short-term debugging purposes I think the current approach works fine. Signed-off-by: Gavin Zhao <git at gzgz.dev> - - - - - 79463036 by Krzysztof Gogolewski at 2023-07-26T10:18:54-04:00 llvm: Restore accidentally deleted code in 0fc5cb97 Fixes #23711 - - - - - 20db7e26 by Rodrigo Mesquita at 2023-07-26T10:19:33-04:00 configure: Default missing options to False when preparing ghc-toolchain Targets This commit fixes building ghc with 9.2 as the boostrap compiler. The ghc-toolchain patch assumed all _STAGE0 options were available, and forgot to account for this missing information in 9.2. Ghc 9.2 does not have in settings whether ar supports -l, hence can't report it with --info (unliked 9.4 upwards). The fix is to default the missing information (we default "ar supports -l" and other missing options to False) - - - - - fac9e84e by Naïm Favier at 2023-07-26T10:20:16-04:00 docs: Fix typo - - - - - 503fd647 by Bartłomiej Cieślar at 2023-07-26T17:23:10-04:00 This MR is an implementation of the proposal #516. It adds a warning -Wincomplete-record-selectors for usages of a record field access function (either a record selector or getField @"rec"), while trying to silence the warning whenever it can be sure that a constructor without the record field would not be invoked (which would otherwise cause the program to fail). For example: data T = T1 | T2 {x :: Bool} f a = x a -- this would throw an error g T1 = True g a = x a -- this would not throw an error h :: HasField "x" r Bool => r -> Bool h = getField @"x" j :: T -> Bool j = h -- this would throw an error because of the `HasField` -- constraint being solved See the tests DsIncompleteRecSel* and TcIncompleteRecSel for more examples of the warning. See Note [Detecting incomplete record selectors] in GHC.HsToCore.Expr for implementation details - - - - - af6fdf42 by Arnaud Spiwack at 2023-07-26T17:23:52-04:00 Fix user-facing label in MR template - - - - - 5d45b92a by Matthew Pickering at 2023-07-27T05:46:46-04:00 ci: Test bootstrapping configurations with full-ci and on marge batches There have been two incidents recently where bootstrapping has been broken by removing support for building with 9.2.*. The process for bumping the minimum required version starts with bumping the configure version and then other CI jobs such as the bootstrap jobs have to be updated. We must not silently bump the minimum required version. Now we are running a slimmed down validate pipeline it seems worthwile to test these bootstrap configurations in the full-ci pipeline. - - - - - 25d4fee7 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Remove ghc-9_2_* plans We are anticipating shortly making it necessary to use ghc-9.4 to boot the compiler. - - - - - 2f66da16 by Matthew Pickering at 2023-07-27T05:46:46-04:00 Update bootstrap plans for ghc-platform and ghc-toolchain dependencies Fixes #23735 - - - - - c8c6eab1 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Disable -selftest flag from bootstrap plans This saves on building one dependency (QuickCheck) which is unecessary for bootstrapping. - - - - - a80ca086 by Andrew Lelechenko at 2023-07-27T05:47:26-04:00 Link reference paper and package from System.Mem.{StableName,Weak} - - - - - a5319358 by David Knothe at 2023-07-28T13:13:10-04:00 Update Match Datatype EquationInfo currently contains a list of the equation's patterns together with a CoreExpr that is to be evaluated after a successful match on this equation. All the match-functions only operate on the first pattern of an equation - after successfully matching it, match is called recursively on the tail of the pattern list. We can express this more clearly and make the code a little more elegant by updating the datatype of EquationInfo as follows: data EquationInfo = EqnMatch { eqn_pat = Pat GhcTc, eqn_rest = EquationInfo } | EqnDone { eqn_rhs = MatchResult CoreExpr } An EquationInfo now explicitly exposes its first pattern which most functions operate on, and exposes the equation that remains after processing the first pattern. An EqnDone signifies an empty equation where the CoreExpr can now be evaluated. - - - - - 86ad1af9 by David Binder at 2023-07-28T13:13:53-04:00 Improve documentation for Data.Fixed - - - - - f8fa1d08 by Ben Gamari at 2023-07-28T13:14:31-04:00 ghc-prim: Use C11 atomics Previously `ghc-prim`'s atomic wrappers used the legacy `__sync_*` family of C builtins. Here we refactor these to rather use the appropriate C11 atomic equivalents, allowing us to be more explicit about the expected ordering semantics. - - - - - 0bfc8908 by Finley McIlwaine at 2023-07-28T18:46:26-04:00 Include -haddock in DynFlags fingerprint The -haddock flag determines whether or not the resulting .hi files contain haddock documentation strings. If the existing .hi files do not contain haddock documentation strings and the user requests them, we should recompile. - - - - - 40425c50 by Andreas Klebinger at 2023-07-28T18:47:02-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - e9a0fa3f by Andrew Lelechenko at 2023-07-28T18:47:42-04:00 Bump filepath submodule to 1.4.100.4 Resolves #23741 Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T12234 T12425 T13035 T13701 T13719 T16875 T18304 T18698a T18698b T21839c T9198 TcPlugin_RewritePerf hard_hole_fits Metric decrease on Windows can be probably attributed to https://github.com/haskell/filepath/pull/183 - - - - - ee93edfd by Andrew Lelechenko at 2023-07-28T18:48:21-04:00 Add since pragmas to GHC.IO.Handle.FD - - - - - d0369802 by Simon Peyton Jones at 2023-07-30T09:24:48+01:00 Make the occurrence analyser smarter about join points This MR addresses #22404. There is a big Note Note [Occurrence analysis for join points] that explains it all. Significant changes * New field occ_join_points in OccEnv * The NonRec case of occAnalBind splits into two cases: one for existing join points (which does the special magic for Note [Occurrence analysis for join points], and one for other bindings. * mkOneOcc adds in info from occ_join_points. * All "bring into scope" activity is centralised in the new function `addInScope`. * I made a local data type LocalOcc for use inside the occurrence analyser It is like OccInfo, but lacks IAmDead and IAmALoopBreaker, which in turn makes computationns over it simpler and more efficient. * I found quite a bit of allocation in GHC.Core.Rules.getRules so I optimised it a bit. More minor changes * I found I was using (Maybe Arity) a lot, so I defined a new data type JoinPointHood and used it everwhere. This touches a lot of non-occ-anal files, but it makes everything more perspicuous. * Renamed data constructor WithUsageDetails to WUD, and WithTailUsageDetails to WTUD This also fixes #21128, on the way. --------- Compiler perf ----------- I spent quite a time on performance tuning, so even though it does more than before, the occurrence analyser runs slightly faster on average. Here are the compile-time allocation changes over 0.5% CoOpt_Read(normal) ghc/alloc 766,025,520 754,561,992 -1.5% CoOpt_Singletons(normal) ghc/alloc 759,436,840 762,925,512 +0.5% LargeRecord(normal) ghc/alloc 1,814,482,440 1,799,530,456 -0.8% PmSeriesT(normal) ghc/alloc 68,159,272 67,519,720 -0.9% T10858(normal) ghc/alloc 120,805,224 118,746,968 -1.7% T11374(normal) ghc/alloc 164,901,104 164,070,624 -0.5% T11545(normal) ghc/alloc 79,851,808 78,964,704 -1.1% T12150(optasm) ghc/alloc 73,903,664 71,237,544 -3.6% GOOD T12227(normal) ghc/alloc 333,663,200 331,625,864 -0.6% T12234(optasm) ghc/alloc 52,583,224 52,340,344 -0.5% T12425(optasm) ghc/alloc 81,943,216 81,566,720 -0.5% T13056(optasm) ghc/alloc 294,517,928 289,642,512 -1.7% T13253-spj(normal) ghc/alloc 118,271,264 59,859,040 -49.4% GOOD T15164(normal) ghc/alloc 1,102,630,352 1,091,841,296 -1.0% T15304(normal) ghc/alloc 1,196,084,000 1,166,733,000 -2.5% T15630(normal) ghc/alloc 148,729,632 147,261,064 -1.0% T15703(normal) ghc/alloc 379,366,664 377,600,008 -0.5% T16875(normal) ghc/alloc 32,907,120 32,670,976 -0.7% T17516(normal) ghc/alloc 1,658,001,888 1,627,863,848 -1.8% T17836(normal) ghc/alloc 395,329,400 393,080,248 -0.6% T18140(normal) ghc/alloc 71,968,824 73,243,040 +1.8% T18223(normal) ghc/alloc 456,852,568 453,059,088 -0.8% T18282(normal) ghc/alloc 129,105,576 131,397,064 +1.8% T18304(normal) ghc/alloc 71,311,712 70,722,720 -0.8% T18698a(normal) ghc/alloc 208,795,112 210,102,904 +0.6% T18698b(normal) ghc/alloc 230,320,736 232,697,976 +1.0% BAD T19695(normal) ghc/alloc 1,483,648,128 1,504,702,976 +1.4% T20049(normal) ghc/alloc 85,612,024 85,114,376 -0.6% T21839c(normal) ghc/alloc 415,080,992 410,906,216 -1.0% GOOD T4801(normal) ghc/alloc 247,590,920 250,726,272 +1.3% T6048(optasm) ghc/alloc 95,699,416 95,080,680 -0.6% T783(normal) ghc/alloc 335,323,384 332,988,120 -0.7% T9233(normal) ghc/alloc 709,641,224 685,947,008 -3.3% GOOD T9630(normal) ghc/alloc 965,635,712 948,356,120 -1.8% T9675(optasm) ghc/alloc 444,604,152 428,987,216 -3.5% GOOD T9961(normal) ghc/alloc 303,064,592 308,798,800 +1.9% BAD WWRec(normal) ghc/alloc 503,728,832 498,102,272 -1.1% geo. mean -1.0% minimum -49.4% maximum +1.9% In fact these figures seem to vary between platforms; generally worse on i386 for some reason. The Windows numbers vary by 1% espec in benchmarks where the total allocation is low. But the geom mean stays solidly negative, which is good. The "increase/decrease" list below covers all platforms. The big win on T13253-spj comes because it has a big nest of join points, each occurring twice in the next one. The new occ-anal takes only one iteration of the simplifier to do the inlining; the old one took four. Moreover, we get much smaller code with the new one: New: Result size of Tidy Core = {terms: 429, types: 84, coercions: 0, joins: 14/14} Old: Result size of Tidy Core = {terms: 2,437, types: 304, coercions: 0, joins: 10/10} --------- Runtime perf ----------- No significant changes in nofib results, except a 1% reduction in compiler allocation. Metric Decrease: CoOpt_Read T13253-spj T9233 T9630 T9675 T12150 T21839c LargeRecord MultiComponentModulesRecomp T10421 T13701 T10421 T13701 T12425 Metric Increase: T18140 T9961 T18282 T18698a T18698b T19695 - - - - - 42aa7fbd by Julian Ospald at 2023-07-30T17:22:01-04:00 Improve documentation around IOException and ioe_filename See: * https://github.com/haskell/core-libraries-committee/issues/189 * https://github.com/haskell/unix/pull/279 * https://github.com/haskell/unix/pull/289 - - - - - 33598ecb by Sylvain Henry at 2023-08-01T14:45:54-04:00 JS: implement getMonotonicTime (fix #23687) - - - - - d2bedffd by Bartłomiej Cieślar at 2023-08-01T14:46:40-04:00 Implementation of the Deprecated Instances proposal #575 This commit implements the ability to deprecate certain instances, which causes the compiler to emit the desired deprecation message whenever they are instantiated. For example: module A where class C t where instance {-# DEPRECATED "dont use" #-} C Int where module B where import A f :: C t => t f = undefined g :: Int g = f -- "dont use" emitted here The implementation is as follows: - In the parser, we parse deprecations/warnings attached to instances: instance {-# DEPRECATED "msg" #-} Show X deriving instance {-# WARNING "msg2" #-} Eq Y (Note that non-standalone deriving instance declarations do not support this mechanism.) - We store the resulting warning message in `ClsInstDecl` (respectively, `DerivDecl`). In `GHC.Tc.TyCl.Instance.tcClsInstDecl` (respectively, `GHC.Tc.Deriv.Utils.newDerivClsInst`), we pass on that information to `ClsInst` (and eventually store it in `IfaceClsInst` too). - Finally, when we solve a constraint using such an instance, in `GHC.Tc.Instance.Class.matchInstEnv`, we emit the appropriate warning that was stored in `ClsInst`. Note that we only emit a warning when the instance is used in a different module than it is defined, which keeps the behaviour in line with the deprecation of top-level identifiers. Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - d5a65af6 by Ben Gamari at 2023-08-01T14:47:18-04:00 compiler: Style fixes - - - - - 7218c80a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Fix implicit cast This ensures that Task.h can be built with a C++ compiler. - - - - - d6d5aafc by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Fix warning in hs_try_putmvar001 - - - - - d9eddf7a by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Add AtomicModifyIORef test - - - - - f9eea4ba by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce NO_WARN macro This allows fine-grained ignoring of warnings. - - - - - 497b24ec by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Simplify atomicModifyMutVar2# implementation Previously we would perform a redundant load in the non-threaded RTS in atomicModifyMutVar2# implementation for the benefit of the non-moving GC's write barrier. Eliminate this. - - - - - 52ee082b by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce more principled fence operations - - - - - cd3c0377 by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce SET_INFO_RELAXED - - - - - 6df2352a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Style fixes - - - - - 4ef6f319 by Ben Gamari at 2023-08-01T14:47:19-04:00 codeGen/tsan: Rework handling of spilling - - - - - f9ca7e27 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More debug information - - - - - df4153ac by Ben Gamari at 2023-08-01T14:47:19-04:00 Improve TSAN documentation - - - - - fecae988 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More selective TSAN instrumentation - - - - - 465a9a0b by Alan Zimmerman at 2023-08-01T14:47:56-04:00 EPA: Provide correct annotation span for ImportDecl Use the whole declaration, rather than just the span of the 'import' keyword. Metric Decrease: T9961 T5205 Metric Increase: T13035 - - - - - ae63d0fa by Bartłomiej Cieślar at 2023-08-01T14:48:40-04:00 Add cases to T23279: HasField for deprecated record fields This commit adds additional tests from ticket #23279 to ensure that we don't regress on reporting deprecated record fields in conjunction with HasField, either when using overloaded record dot syntax or directly through `getField`. Fixes #23279 - - - - - 00fb6e6b by Andreas Klebinger at 2023-08-01T14:49:17-04:00 AArch NCG: Pure refactor Combine some alternatives. Add some line breaks for overly long lines - - - - - 8f3b3b78 by Andreas Klebinger at 2023-08-01T14:49:54-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - 74a882dc by MorrowM at 2023-08-02T06:00:03-04:00 Add a RULE to make lookup fuse See https://github.com/haskell/core-libraries-committee/issues/175 Metric Increase: T18282 - - - - - cca74dab by Ben Gamari at 2023-08-02T06:00:39-04:00 hadrian: Ensure that way-flags are passed to CC Previously the way-specific compilation flags (e.g. `-DDEBUG`, `-DTHREADED_RTS`) would not be passed to the CC invocations. This meant that C dependency files would not correctly reflect dependencies predicated on the way, resulting in the rather painful #23554. Closes #23554. - - - - - 622b483c by Jaro Reinders at 2023-08-02T06:01:20-04:00 Native 32-bit Enum Int64/Word64 instances This commits adds more performant Enum Int64 and Enum Word64 instances for 32-bit platforms, replacing the Integer-based implementation. These instances are a copy of the Enum Int and Enum Word instances with minimal changes to manipulate Int64 and Word64 instead. On i386 this yields a 1.5x performance increase and for the JavaScript back end it even yields a 5.6x speedup. Metric Decrease: T18964 - - - - - c8bd7fa4 by Sylvain Henry at 2023-08-02T06:02:03-04:00 JS: fix typos in constants (#23650) - - - - - b9d5bfe9 by Josh Meredith at 2023-08-02T06:02:40-04:00 JavaScript: update MK_TUP macros to use current tuple constructors (#23659) - - - - - 28211215 by Matthew Pickering at 2023-08-02T06:03:19-04:00 ci: Pass -Werror when building hadrian in hadrian-ghc-in-ghci job Warnings when building Hadrian can end up cluttering the output of HLS, and we've had bug reports in the past about these warnings when building Hadrian. It would be nice to turn on -Werror on at least one build of Hadrian in CI to avoid a patch introducing warnings when building Hadrian. Fixes #23638 - - - - - aca20a5d by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers By using a proper release store instead of a fence. - - - - - 453c0531 by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that array reads have necessary barriers This was the cause of #23541. - - - - - 93a0d089 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Add test for #23550 - - - - - 6a2f4a20 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Desugar non-recursive lets to non-recursive lets (take 2) This reverts commit 522bd584f71ddeda21efdf0917606ce3d81ec6cc. And takes care of the case that I missed in my previous attempt. Namely the case of an AbsBinds with no type variables and no dictionary variable. Ironically, the comment explaining why non-recursive lets were desugared to recursive lets were pointing specifically at this case as the reason. I just failed to understand that it was until Simon PJ pointed it out to me. See #23550 for more discussion. - - - - - ff81d53f by jade at 2023-08-02T06:05:20-04:00 Expand documentation of List & Data.List This commit aims to improve the documentation and examples of symbols exported from Data.List - - - - - fa4e5913 by Jade at 2023-08-02T06:06:03-04:00 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid - - - - - e2c91bff by Gergő Érdi at 2023-08-03T02:55:46+01:00 Desugar bindings in the context of their evidence Closes #23172 - - - - - 481f4a46 by Gergő Érdi at 2023-08-03T07:48:43+01:00 Add flag to `-f{no-}specialise-incoherents` to enable/disable specialisation of incoherent instances Fixes #23287 - - - - - d751c583 by Profpatsch at 2023-08-04T12:24:26-04:00 base: Improve String & IsString documentation - - - - - 01db1117 by Ben Gamari at 2023-08-04T12:25:02-04:00 rts/win32: Ensure reliability of IO manager shutdown When the Win32 threaded IO manager shuts down, `ioManagerDie` sends an `IO_MANAGER_DIE` event to the IO manager thread using the `io_manager_event` event object. Finally, it will closes the event object, and invalidate `io_manager_event`. Previously, `readIOManagerEvent` would see that `io_manager_event` is invalid and return `0`, suggesting that everything is right with the world. This meant that if `ioManagerDie` invalidated the handle before the event manager was blocked on the event we would end up in a situation where the event manager would never realize it was asked to shut down. Fix this by ensuring that `readIOManagerEvent` instead returns `IO_MANAGER_DIE` when we detect that the event object has been invalidated by `ioManagerDie`. Fixes #23691. - - - - - fdef003a by Ryan Scott at 2023-08-04T12:25:39-04:00 Look through TH splices in splitHsApps This modifies `splitHsApps` (a key function used in typechecking function applications) to look through untyped TH splices and quasiquotes. Not doing so was the cause of #21077. This builds on !7821 by making `splitHsApps` match on `HsUntypedSpliceTop`, which contains the `ThModFinalizers` that must be run as part of invoking the TH splice. See the new `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Along the way, I needed to make the type of `splitHsApps.set` slightly more general to accommodate the fact that the location attached to a quasiquote is a `SrcAnn NoEpAnns` rather than a `SrcSpanAnnA`. Fixes #21077. - - - - - e77a0b41 by Ben Gamari at 2023-08-04T12:26:15-04:00 Bump deepseq submodule to 1.5. And bump bounds (cherry picked from commit 1228d3a4a08d30eaf0138a52d1be25b38339ef0b) - - - - - cebb5819 by Ben Gamari at 2023-08-04T12:26:15-04:00 configure: Bump minimal boot GHC version to 9.4 (cherry picked from commit d3ffdaf9137705894d15ccc3feff569d64163e8e) - - - - - 83766dbf by Ben Gamari at 2023-08-04T12:26:15-04:00 template-haskell: Bump version to 2.21.0.0 Bumps exceptions submodule. (cherry picked from commit bf57fc9aea1196f97f5adb72c8b56434ca4b87cb) - - - - - 1211112a by Ben Gamari at 2023-08-04T12:26:15-04:00 base: Bump version to 4.19 Updates all boot library submodules. (cherry picked from commit 433d99a3c24a55b14ec09099395e9b9641430143) - - - - - 3ab5efd9 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Normalise versions more aggressively In backpack hashes can contain `+` characters. (cherry picked from commit 024861af51aee807d800e01e122897166a65ea93) - - - - - d52be957 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Declare bkpcabal08 as fragile Due to spurious output changes described in #23648. (cherry picked from commit c046a2382420f2be2c4a657c56f8d95f914ea47b) - - - - - e75a58d1 by Ben Gamari at 2023-08-04T12:26:15-04:00 gitlab-ci: Only mark linker_unload_native as broken in static jobs This test passes on dynamically-linked Alpine. (cherry picked from commit f356a7e8ec8ec3d6b2b30fd175598b9b80065d87) - - - - - 8b176514 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Update base-exports - - - - - 4b647936 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite/interface-stability: normalise versions This eliminates spurious changes from version bumps. - - - - - 0eb54c05 by Ben Gamari at 2023-08-04T12:26:51-04:00 linker/PEi386: Don't sign-extend symbol section number Previously we incorrectly interpreted PE section numbers as signed values. However, this isn't the case; rather, it's an unsigned 16-bit number with a few special bit-patterns (0xffff and 0xfffe). This resulted in #22941 as the linker would conclude that the sections were invalid. Fixing this required quite a bit of refactoring. Closes #22941. - - - - - fd7ce39c by Ben Gamari at 2023-08-04T12:27:28-04:00 testsuite: Mark MulMayOflo_full as broken rather than skipping To ensure that we don't accidentally fix it. See #23742. - - - - - 824092f2 by Ben Gamari at 2023-08-04T12:27:28-04:00 nativeGen/AArch64: Fix sign extension in MulMayOflo Previously the 32-bit implementations of MulMayOflo would use the a non-sensical sign-extension mode. Rewrite these to reflect what gcc 11 produces. Also similarly rework the 16- and 8-bit cases. This now passes the MulMayOflo tests in ghc/test-primops> in all four widths, including the precision tests. Fixes #23721. - - - - - 1b15dbc4 by Jan Hrček at 2023-08-04T12:28:08-04:00 Fix haddock markup in code example for coerce - - - - - 46fd8ced by Vladislav Zavialov at 2023-08-04T12:28:44-04:00 Fix (~) and (@) infix operators in TH splices (#23748) 8168b42a "Whitespace-sensitive bang patterns" allows GHC to accept the following infix operators: a ~ b = () a @ b = () But not if TH is used to generate those declarations: $([d| a ~ b = () a @ b = () |]) -- Test.hs:5:2: error: [GHC-55017] -- Illegal variable name: ‘~’ -- When splicing a TH declaration: (~_0) a_1 b_2 = GHC.Tuple.Prim.() This is easily fixed by modifying `reservedOps` in GHC.Utils.Lexeme - - - - - a1899d8f by Aaron Allen at 2023-08-04T12:29:24-04:00 [#23663] Show Flag Suggestions in GHCi Makes suggestions when using `:set` in GHCi with a misspelled flag. This mirrors how invalid flags are handled when passed to GHC directly. Logic for producing flag suggestions was moved to GHC.Driver.Sesssion so it can be shared. resolves #23663 - - - - - 03f2debd by Rodrigo Mesquita at 2023-08-04T12:30:00-04:00 Improve ghc-toolchain validation configure warning Fixes the layout of the ghc-toolchain validation warning produced by configure. - - - - - de25487d by Alan Zimmerman at 2023-08-04T12:30:36-04:00 EPA make getLocA a synonym for getHasLoc This is basically a no-op change, but allows us to make future changes that can rely on the HasLoc instances And I presume this means we can use more precise functions based on class resolution, so the Windows CI build reports Metric Decrease: T12234 T13035 - - - - - 3ac423b9 by Ben Gamari at 2023-08-04T12:31:13-04:00 ghc-platform: Add upper bound on base Hackage upload requires this. - - - - - 8ba20b21 by Matthew Craven at 2023-08-04T17:22:59-04:00 Adjust and clarify handling of primop effects Fixes #17900; fixes #20195. The existing "can_fail" and "has_side_effects" primop attributes that previously governed this were used in inconsistent and confusingly-documented ways, especially with regard to raising exceptions. This patch replaces them with a single "effect" attribute, which has four possible values: NoEffect, CanFail, ThrowsException, and ReadWriteEffect. These are described in Note [Classifying primop effects]. A substantial amount of related documentation has been re-drafted for clarity and accuracy. In the process of making this attribute format change for literally every primop, several existing mis-classifications were detected and corrected. One of these mis-classifications was tagToEnum#, which is now considered CanFail; this particular fix is known to cause a regression in performance for derived Enum instances. (See #23782.) Fixing this is left as future work. New primop attributes "cheap" and "work_free" were also added, and used in the corresponding parts of GHC.Core.Utils. In view of their actual meaning and uses, `primOpOkForSideEffects` and `exprOkForSideEffects` have been renamed to `primOpOkToDiscard` and `exprOkToDiscard`, respectively. Metric Increase: T21839c - - - - - 41bf2c09 by sheaf at 2023-08-04T17:23:42-04:00 Update inert_solved_dicts for ImplicitParams When adding an implicit parameter dictionary to the inert set, we must make sure that it replaces any previous implicit parameter dictionaries that overlap, in order to get the appropriate shadowing behaviour, as in let ?x = 1 in let ?x = 2 in ?x We were already doing this for inert_cans, but we weren't doing the same thing for inert_solved_dicts, which lead to the bug reported in #23761. The fix is thus to make sure that, when handling an implicit parameter dictionary in updInertDicts, we update **both** inert_cans and inert_solved_dicts to ensure a new implicit parameter dictionary correctly shadows old ones. Fixes #23761 - - - - - 43578d60 by Matthew Craven at 2023-08-05T01:05:36-04:00 Bump bytestring submodule to 0.11.5.1 - - - - - 91353622 by Ben Gamari at 2023-08-05T01:06:13-04:00 Initial commit of Note [Thunks, blackholes, and indirections] This Note attempts to summarize the treatment of thunks, thunk update, and indirections. This fell out of work on #23185. - - - - - 8d686854 by sheaf at 2023-08-05T01:06:54-04:00 Remove zonk in tcVTA This removes the zonk in GHC.Tc.Gen.App.tc_inst_forall_arg and its accompanying Note [Visible type application zonk]. Indeed, this zonk is no longer necessary, as we no longer maintain the invariant that types are well-kinded without zonking; only that typeKind does not crash; see Note [The Purely Kinded Type Invariant (PKTI)]. This commit removes this zonking step (as well as a secondary zonk), and replaces the aforementioned Note with the explanatory Note [Type application substitution], which justifies why the substitution performed in tc_inst_forall_arg remains valid without this zonking step. Fixes #23661 - - - - - 19dea673 by Ben Gamari at 2023-08-05T01:07:30-04:00 Bump nofib submodule Ensuring that nofib can be build using the same range of bootstrap compilers as GHC itself. - - - - - aa07402e by Luite Stegeman at 2023-08-05T23:15:55+09:00 JS: Improve compatibility with recent emsdk The JavaScript code in libraries/base/jsbits/base.js had some hardcoded offsets for fields in structs, because we expected the layout of the data structures to remain unchanged. Emsdk 3.1.42 changed the layout of the stat struct, breaking this assumption, and causing code in .hsc files accessing the stat struct to fail. This patch improves compatibility with recent emsdk by removing the assumption that data layouts stay unchanged: 1. offsets of fields in structs used by JavaScript code are now computed by the configure script, so both the .js and .hsc files will automatically use the new layout if anything changes. 2. the distrib/configure script checks that the emsdk version on a user's system is the same version that a bindist was booted with, to avoid data layout inconsistencies See #23641 - - - - - b938950d by Luite Stegeman at 2023-08-07T06:27:51-04:00 JS: Fix missing local variable declarations This fixes some missing local variable declarations that were found by running the testsuite in strict mode. Fixes #23775 - - - - - 6c0e2247 by sheaf at 2023-08-07T13:31:21-04:00 Update Haddock submodule to fix #23368 This submodule update adds the following three commits: bbf1c8ae - Check for puns 0550694e - Remove fake exports for (~), List, and Tuple<n> 5877bceb - Fix pretty-printing of Solo and MkSolo These commits fix the issues with Haddock HTML rendering reported in ticket #23368. Fixes #23368 - - - - - 5b5be3ea by Matthew Pickering at 2023-08-07T13:32:00-04:00 Revert "Bump bytestring submodule to 0.11.5.1" This reverts commit 43578d60bfc478e7277dcd892463cec305400025. Fixes #23789 - - - - - 01961be3 by Ben Gamari at 2023-08-08T02:47:14-04:00 configure: Derive library version from ghc-prim.cabal.in Since ghc-prim.cabal is now generated by Hadrian, we cannot depend upon it. Closes #23726. - - - - - 3b373838 by Ryan Scott at 2023-08-08T02:47:49-04:00 tcExpr: Push expected types for untyped TH splices inwards In !10911, I deleted a `tcExpr` case for `HsUntypedSplice` in favor of a much simpler case that simply delegates to `tcApp`. Although this passed the test suite at the time, this was actually an error, as the previous `tcExpr` case was critically pushing the expected type inwards. This actually matters for programs like the one in #23796, which GHC would not accept with type inference alone—we need full-blown type _checking_ to accept these. I have added back the previous `tcExpr` case for `HsUntypedSplice` and now explain why we have two different `HsUntypedSplice` cases (one in `tcExpr` and another in `splitHsApps`) in `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Fixes #23796. - - - - - 0ef1d8ae by sheaf at 2023-08-08T21:26:51-04:00 Compute all emitted diagnostic codes This commit introduces in GHC.Types.Error.Codes the function constructorCodes :: forall diag. (...) => Map DiagnosticCode String which computes a collection of all the diagnostic codes that correspond to a particular type. In particular, we can compute the collection of all diagnostic codes emitted by GHC using the invocation constructorCodes @GhcMessage We then make use of this functionality in the new "codes" test which checks consistency and coverage of GHC diagnostic codes. It performs three checks: - check 1: all non-outdated GhcDiagnosticCode equations are statically used. - check 2: all outdated GhcDiagnosticCode equations are statically unused. - check 3: all statically used diagnostic codes are covered by the testsuite (modulo accepted exceptions). - - - - - 4bc7b1e5 by Fraser Tweedale at 2023-08-08T21:27:32-04:00 numberToRangedRational: fix edge cases for exp ≈ (maxBound :: Int) Currently a negative exponent less than `minBound :: Int` results in Infinity, which is very surprising and obviously wrong. ``` λ> read "1e-9223372036854775808" :: Double 0.0 λ> read "1e-9223372036854775809" :: Double Infinity ``` There is a further edge case where the exponent can overflow when increased by the number of tens places in the integer part, or underflow when decreased by the number of leading zeros in the fractional part if the integer part is zero: ``` λ> read "10e9223372036854775807" :: Double 0.0 λ> read "0.01e-9223372036854775808" :: Double Infinity ``` To resolve both of these issues, perform all arithmetic and comparisons involving the exponent in type `Integer`. This approach also eliminates the need to explicitly check the exponent against `maxBound :: Int` and `minBound :: Int`, because the allowed range of the exponent (i.e. the result of `floatRange` for the target floating point type) is certainly within those bounds. This change implements CLC proposal 192: https://github.com/haskell/core-libraries-committee/issues/192 - - - - - 6eab07b2 by Alan Zimmerman at 2023-08-08T21:28:10-04:00 EPA: Remove Location from WarningTxt source This is not needed. - - - - - 1a98d673 by Sebastian Graf at 2023-08-09T16:24:29-04:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 2274abc8 by Sebastian Graf at 2023-08-09T16:24:29-04:00 More explicit strictness in GHC.Real - - - - - ce8aa54c by Sebastian Graf at 2023-08-09T16:24:30-04:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - d004a36d by Sebastian Graf at 2023-08-09T16:24:30-04:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 8c73505e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - d8d993f1 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Disable tests RepPolyWrappedVar2 and RepPolyUnsafeCoerce1 in JS backend ... because those coerce between incompatible/unknown PrimReps. - - - - - f06e87e4 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Inlining literals into boring contexts is OK - - - - - 4a6b7c87 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Clarify floating of unsafeEqualityProofs (#23754) - - - - - b0f4752e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 7e0c8b3b by Sebastian Graf at 2023-08-09T16:24:30-04:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Annoyingly, in -O0 we sometimes generate ``` foo = case "blah"# of sat { __DEFAULT -> unpackCString# sat } ``` which makes it a bit harder to spot that we can emit a standard `stg_unpack_cstring` thunk. Fixes #23270. - - - - - 357f2738 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Deactivate -fcatch-nonexhaustive-cases in ghc-bignum (#23345) - - - - - 59202c80 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. In the ghc/alloc perf test `LargeRecord`, we introduce an additional Simplifier iteration due to #17910. E.g., FloatOut produces a binding ``` lvl_s6uK [Occ=Once1] :: GHC.Types.Int [LclId] lvl_s6uK = GHC.Types.I# 2# lvl_s6uL [Occ=Once1] :: GHC.Types.Any [LclId] lvl_s6uL = case Unsafe.Coerce.unsafeEqualityProof ... of { Unsafe.Coerce.UnsafeRefl v2_i6tr -> lvl_s6uK `cast` (... v2_i6tr ...) } ``` That occurs once and hence is pre-inlined unconditionally in the next Simplifier pass. It's non-trivial to find a way around that, but not really harmful otherwise. Hence we accept a 1.2% increase on some architectures. Metric Increase: LargeRecord - - - - - 00d31188 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - bf885d7a by Matthew Craven at 2023-08-09T16:25:07-04:00 Bump bytestring submodule to 0.11.5, again Fixes #23789. The bytestring commit used here is unreleased; a release can be made when necessary. - - - - - 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - 1d03238b by Ben Gamari at 2024-04-05T17:21:42-04:00 Bump terminfo submodule to current `master` This folds in @Jade's bash-ism removal in `configure`. - - - - - 13 changed files: - − .appveyor.sh - .editorconfig - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - − .gitlab/circle-ci-job.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - + .gitlab/generate-ci/LICENSE - + .gitlab/generate-ci/README.mkd - + .gitlab/generate-ci/flake.lock - + .gitlab/generate-ci/flake.nix The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c4249e53734d507003d8f6a8436cec6e7d8576f...1d03238b36efaead6ebc4a8be462debcf49da365 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c4249e53734d507003d8f6a8436cec6e7d8576f...1d03238b36efaead6ebc4a8be462debcf49da365 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 21:38:05 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 05 Apr 2024 17:38:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24634 Message-ID: <66106f3da9f7d_a58d3ba1918118976@gitlab.mail> Ben Gamari pushed new branch wip/T24634 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24634 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 21:39:01 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 05 Apr 2024 17:39:01 -0400 Subject: [Git][ghc/ghc][wip/T24634] testsuite: Add broken test for CApiFFI with -fprefer-bytecode Message-ID: <66106f75de578_a58d3c164ac120742@gitlab.mail> Ben Gamari pushed to branch wip/T24634 at Glasgow Haskell Compiler / GHC Commits: 6f7bdec2 by Ben Gamari at 2024-04-05T17:38:52-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - 6 changed files: - + testsuite/tests/bytecode/T24634/Hello.hs - + testsuite/tests/bytecode/T24634/Main.hs - + testsuite/tests/bytecode/T24634/Makefile - + testsuite/tests/bytecode/T24634/all.T - + testsuite/tests/bytecode/T24634/hello.c - + testsuite/tests/bytecode/T24634/hello.h Changes: ===================================== testsuite/tests/bytecode/T24634/Hello.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE CApiFFI #-} +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE TemplateHaskell #-} + +module Hello where + +import Language.Haskell.TH +import Language.Haskell.TH.Syntax + +foreign import capi "hello.h say_hello" say_hello :: IO Int + +mkHello :: DecsQ +mkHello = do + n <- runIO say_hello + [d| hello :: IO Int + hello = return $(lift n) |] ===================================== testsuite/tests/bytecode/T24634/Main.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Hello + +$(mkHello) + +main :: IO () +main = hello >>= print ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +bytecode-capi: + $(TEST_HC) -c hello.c + $(TEST_HC) -c -fbyte-code-and-object-code Hello.hs + $(TEST_HC) -fprefer-byte-code hello.o Main.hs + ./Main ===================================== testsuite/tests/bytecode/T24634/all.T ===================================== @@ -0,0 +1,7 @@ +test('T24634', + [extra_files(['hello.h', 'hello.c', 'Hello.hs', 'Main.hs']), + req_interp, + expect_broken(24634), + ], + makefile_test, + ['']) ===================================== testsuite/tests/bytecode/T24634/hello.c ===================================== @@ -0,0 +1,5 @@ +#include "hello.h" + +int say_hello() { + return 42; +} ===================================== testsuite/tests/bytecode/T24634/hello.h ===================================== @@ -0,0 +1 @@ +int say_hello(void); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f7bdec20ccba366bc5e677ce16406f3311fd038 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f7bdec20ccba366bc5e677ce16406f3311fd038 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 5 23:19:29 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Fri, 05 Apr 2024 19:19:29 -0400 Subject: [Git][ghc/ghc][wip/T24477] WIP Message-ID: <661087012f928_a58d316414901301b4@gitlab.mail> Jade pushed to branch wip/T24477 at Glasgow Haskell Compiler / GHC Commits: 25c852b9 by Jade at 2024-04-06T01:24:05+02:00 WIP - - - - - 4 changed files: - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Types/Hint/Ppr.hs - testsuite/tests/ghci/should_run/T10857a.stdout Changes: ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -42,6 +42,8 @@ module GHC.Driver.Flags , Deprecation(..) , extensionDeprecation , deprecation + , extensionNames + , extensionName ) where @@ -93,22 +95,36 @@ deprecation :: ExtensionDeprecation -> Deprecation deprecation ExtensionNotDeprecated = NotDeprecated deprecation _ = Deprecated -extensionDeprecation :: String -> ExtensionDeprecation +extensionDeprecation :: LangExt.Extension -> ExtensionDeprecation extensionDeprecation = \case - "TypeInType" -> ExtensionDeprecatedFor [LangExt.DataKinds, LangExt.PolyKinds] - "RecordPuns" -> ExtensionDeprecatedFor [LangExt.NamedFieldPuns] - "PatternSignatures" -> ExtensionDeprecatedFor [LangExt.ScopedTypeVariables] - "NullaryTypeClasses" -> ExtensionDeprecatedFor [LangExt.MultiParamTypeClasses] - "DoRec" -> ExtensionDeprecatedFor [LangExt.RecursiveDo] - "RelaxedPolyRec" -> ExtensionFlagDeprecatedCond turnOff + LangExt.TypeInType -> ExtensionDeprecatedFor [LangExt.DataKinds, LangExt.PolyKinds] + LangExt.NullaryTypeClasses -> ExtensionDeprecatedFor [LangExt.MultiParamTypeClasses] + LangExt.RelaxedPolyRec -> ExtensionFlagDeprecatedCond turnOff "You can't turn off RelaxedPolyRec any more" - "DatatypeContexts" -> ExtensionFlagDeprecatedCond turnOn + LangExt.DatatypeContexts -> ExtensionFlagDeprecatedCond turnOn "It was widely considered a misfeature, and has been removed from the Haskell language." - "AutoDeriveTypeable" -> ExtensionFlagDeprecatedCond turnOn + LangExt.AutoDeriveTypeable -> ExtensionFlagDeprecatedCond turnOn "Typeable instances are created automatically for all types since GHC 8.2." - "OverlappingInstances" -> ExtensionFlagDeprecated + LangExt.OverlappingInstances -> ExtensionFlagDeprecated "instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS" - _ -> ExtensionNotDeprecated + _ -> ExtensionNotDeprecated + + +extensionName :: LangExt.Extension -> String +extensionName LangExt.Cpp = "CPP" +extensionName ext = show ext + +-- | Is this extension known by any other names? For example +-- -XGeneralizedNewtypeDeriving is accepted +extensionAlternateNames :: LangExt.Extension -> [String] +extensionAlternateNames = \case + LangExt.GeneralizedNewtypeDeriving -> ["GeneralisedNewtypeDeriving"] + LangExt.RankNTypes -> ["Rank2Types", "PolymorphicComponents"] + _ -> [] + +-- | All the names by which an extension is known. +extensionNames :: LangExt.Extension -> [String] +extensionNames ext = extensionName ext : extensionAlternateNames ext impliedXFlags :: [(LangExt.Extension, TurnOnFlag, LangExt.Extension)] ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2608,15 +2608,33 @@ safeHaskellFlagsDeps = [mkF Sf_Unsafe, mkF Sf_Trustworthy, mkF Sf_Safe] xFlags :: [FlagSpec LangExt.Extension] xFlags = map snd xFlagsDeps -makeExtensionFlag :: (String, LangExt.Extension) -> (Deprecation, FlagSpec LangExt.Extension) -makeExtensionFlag (name, ext) = (deprecation depr, spec) - where depr = extensionDeprecation name +makeExtensionFlags :: LangExt.Extension -> [(Deprecation, FlagSpec LangExt.Extension)] +makeExtensionFlags ext = [ makeExtensionFlag name ext | name <- extensionNames ext ] + +-- We save lots of lines here by getting rid of all the boilerplate (String, Extension) pairs! Almost all flags are uniform so we can just treat the special cases specially. +xFlagsDeps :: [(Deprecation, FlagSpec LangExt.Extension)] +xFlagsDeps = concatMap makeExtensionFlags [minBound .. maxBound] ++ xFlagsDepsSpecialCases + +-- | These are deprecated extension flags that do not correspond to a proper Extension. +xFlagsDepsSpecialCases :: [(Deprecation, FlagSpec LangExt.Extension)] +xFlagsDepsSpecialCases = + [ depXFlagSpec "DoRec" LangExt.RecursiveDo + , depXFlagSpec "RecordPuns" LangExt.NamedFieldPuns + , depXFlagSpec "PatternSignatures" LangExt.ScopedTypeVariables + ] + +depXFlagSpec :: String -> LangExt.Extension -> (Deprecation, FlagSpec LangExt.Extension) +depXFlagSpec s ext = depFlagSpec' s ext (deprecatedForExtension $ extensionName ext) + +makeExtensionFlag :: String -> LangExt.Extension -> (Deprecation, FlagSpec LangExt.Extension) +makeExtensionFlag name ext = (deprecation depr, spec) + where depr = extensionDeprecation ext effect = extensionEffect ext spec = FlagSpec name ext (\f -> effect f >> act f) AllModes act = case depr of ExtensionNotDeprecated -> nop ExtensionDeprecatedFor xs - -> deprecate . deprecatedForExtensions (map show xs) -- JADE_TODO + -> deprecate . deprecatedForExtensions (map extensionName xs) ExtensionFlagDeprecatedCond cond str -> \f -> when (f == cond) (deprecate str) ExtensionFlagDeprecated str @@ -2636,148 +2654,6 @@ extensionEffect = \case -> setDeriveVia _ -> nop -xFlagsDeps :: [(Deprecation, FlagSpec LangExt.Extension)] -xFlagsDeps = map makeExtensionFlag - [ ("AllowAmbiguousTypes", LangExt.AllowAmbiguousTypes) - , ("AlternativeLayoutRule", LangExt.AlternativeLayoutRule) - , ("AlternativeLayoutRuleTransitional", LangExt.AlternativeLayoutRuleTransitional) - , ("Arrows", LangExt.Arrows) - , ("AutoDeriveTypeable", LangExt.AutoDeriveTypeable) - , ("BangPatterns", LangExt.BangPatterns) - , ("BinaryLiterals", LangExt.BinaryLiterals) - , ("CApiFFI", LangExt.CApiFFI) - , ("CPP", LangExt.Cpp) - , ("CUSKs", LangExt.CUSKs) - , ("ConstrainedClassMethods", LangExt.ConstrainedClassMethods) - , ("ConstraintKinds", LangExt.ConstraintKinds) - , ("DataKinds", LangExt.DataKinds) - , ("DatatypeContexts", LangExt.DatatypeContexts) - , ("DefaultSignatures", LangExt.DefaultSignatures) - , ("DeriveAnyClass", LangExt.DeriveAnyClass) - , ("DeriveDataTypeable", LangExt.DeriveDataTypeable) - , ("DeriveFoldable", LangExt.DeriveFoldable) - , ("DeriveFunctor", LangExt.DeriveFunctor) - , ("DeriveGeneric", LangExt.DeriveGeneric) - , ("DeriveLift", LangExt.DeriveLift) - , ("DeriveTraversable", LangExt.DeriveTraversable) - , ("DerivingStrategies", LangExt.DerivingStrategies) - , ("DerivingVia", LangExt.DerivingVia) - , ("DisambiguateRecordFields", LangExt.DisambiguateRecordFields) - , ("DoAndIfThenElse", LangExt.DoAndIfThenElse) - , ("BlockArguments", LangExt.BlockArguments) - , ("DoRec", LangExt.RecursiveDo) - , ("DuplicateRecordFields", LangExt.DuplicateRecordFields) - , ("FieldSelectors", LangExt.FieldSelectors) - , ("EmptyCase", LangExt.EmptyCase) - , ("EmptyDataDecls", LangExt.EmptyDataDecls) - , ("EmptyDataDeriving", LangExt.EmptyDataDeriving) - , ("ExistentialQuantification", LangExt.ExistentialQuantification) - , ("ExplicitForAll", LangExt.ExplicitForAll) - , ("ExplicitNamespaces", LangExt.ExplicitNamespaces) - , ("ExtendedDefaultRules", LangExt.ExtendedDefaultRules) - , ("ExtendedLiterals", LangExt.ExtendedLiterals) - , ("FlexibleContexts", LangExt.FlexibleContexts) - , ("FlexibleInstances", LangExt.FlexibleInstances) - , ("ForeignFunctionInterface", LangExt.ForeignFunctionInterface) - , ("FunctionalDependencies", LangExt.FunctionalDependencies) - , ("GADTSyntax", LangExt.GADTSyntax) - , ("GADTs", LangExt.GADTs) - , ("GHCForeignImportPrim", LangExt.GHCForeignImportPrim) - , ("GeneralizedNewtypeDeriving", LangExt.GeneralizedNewtypeDeriving) - , ("GeneralisedNewtypeDeriving", LangExt.GeneralizedNewtypeDeriving) - , ("ImplicitParams", LangExt.ImplicitParams) - , ("ImplicitPrelude", LangExt.ImplicitPrelude) - , ("ImportQualifiedPost", LangExt.ImportQualifiedPost) - , ("ImpredicativeTypes", LangExt.ImpredicativeTypes) - , ("IncoherentInstances", LangExt.IncoherentInstances) - , ("TypeFamilyDependencies", LangExt.TypeFamilyDependencies) - , ("InstanceSigs", LangExt.InstanceSigs) - , ("ApplicativeDo", LangExt.ApplicativeDo) - , ("InterruptibleFFI", LangExt.InterruptibleFFI) - , ("JavaScriptFFI", LangExt.JavaScriptFFI) - , ("KindSignatures", LangExt.KindSignatures) - , ("LambdaCase", LangExt.LambdaCase) - , ("LexicalNegation", LangExt.LexicalNegation) - , ("LiberalTypeSynonyms", LangExt.LiberalTypeSynonyms) - , ("LinearTypes", LangExt.LinearTypes) - , ("ListTuplePuns", LangExt.ListTuplePuns) - , ("MagicHash", LangExt.MagicHash) - , ("MonadComprehensions", LangExt.MonadComprehensions) - , ("MonoLocalBinds", LangExt.MonoLocalBinds) - , ("DeepSubsumption", LangExt.DeepSubsumption) - , ("MonomorphismRestriction", LangExt.MonomorphismRestriction) - , ("MultiParamTypeClasses", LangExt.MultiParamTypeClasses) - , ("MultiWayIf", LangExt.MultiWayIf) - , ("NumericUnderscores", LangExt.NumericUnderscores) - , ("NPlusKPatterns", LangExt.NPlusKPatterns) - , ("NamedFieldPuns", LangExt.NamedFieldPuns) - , ("NamedWildCards", LangExt.NamedWildCards) - , ("NegativeLiterals", LangExt.NegativeLiterals) - , ("HexFloatLiterals", LangExt.HexFloatLiterals) - , ("NondecreasingIndentation", LangExt.NondecreasingIndentation) - , ("NullaryTypeClasses", LangExt.NullaryTypeClasses) - , ("NumDecimals", LangExt.NumDecimals) - , ("OverlappingInstances", LangExt.OverlappingInstances) - , ("OverloadedLabels", LangExt.OverloadedLabels) - , ("OverloadedLists", LangExt.OverloadedLists) - , ("OverloadedStrings", LangExt.OverloadedStrings) - , ("PackageImports", LangExt.PackageImports) - , ("ParallelArrays", LangExt.ParallelArrays) - , ("ParallelListComp", LangExt.ParallelListComp) - , ("PartialTypeSignatures", LangExt.PartialTypeSignatures) - , ("PatternGuards", LangExt.PatternGuards) - , ("PatternSignatures", LangExt.ScopedTypeVariables) - , ("PatternSynonyms", LangExt.PatternSynonyms) - , ("PolyKinds", LangExt.PolyKinds) - , ("PolymorphicComponents", LangExt.RankNTypes) - , ("QuantifiedConstraints", LangExt.QuantifiedConstraints) - , ("PostfixOperators", LangExt.PostfixOperators) - , ("QuasiQuotes", LangExt.QuasiQuotes) - , ("QualifiedDo", LangExt.QualifiedDo) - , ("Rank2Types", LangExt.RankNTypes) - , ("RankNTypes", LangExt.RankNTypes) - , ("RebindableSyntax", LangExt.RebindableSyntax) - , ("OverloadedRecordDot", LangExt.OverloadedRecordDot) - , ("OverloadedRecordUpdate", LangExt.OverloadedRecordUpdate) - , ("RecordPuns", LangExt.NamedFieldPuns) - , ("RecordWildCards", LangExt.RecordWildCards) - , ("RecursiveDo", LangExt.RecursiveDo) - , ("RelaxedLayout", LangExt.RelaxedLayout) - , ("RelaxedPolyRec", LangExt.RelaxedPolyRec) - , ("RequiredTypeArguments", LangExt.RequiredTypeArguments) - , ("RoleAnnotations", LangExt.RoleAnnotations) - , ("ScopedTypeVariables", LangExt.ScopedTypeVariables) - , ("StandaloneDeriving", LangExt.StandaloneDeriving) - , ("StarIsType", LangExt.StarIsType) - , ("StaticPointers", LangExt.StaticPointers) - , ("Strict", LangExt.Strict) - , ("StrictData", LangExt.StrictData) - , ("TemplateHaskell", LangExt.TemplateHaskell) - , ("TemplateHaskellQuotes", LangExt.TemplateHaskellQuotes) - , ("StandaloneKindSignatures", LangExt.StandaloneKindSignatures) - , ("TraditionalRecordSyntax", LangExt.TraditionalRecordSyntax) - , ("TransformListComp", LangExt.TransformListComp) - , ("TupleSections", LangExt.TupleSections) - , ("TypeAbstractions", LangExt.TypeAbstractions) - , ("TypeApplications", LangExt.TypeApplications) - , ("TypeData", LangExt.TypeData) - , ("TypeInType", LangExt.TypeInType) - , ("TypeFamilies", LangExt.TypeFamilies) - , ("TypeOperators", LangExt.TypeOperators) - , ("TypeSynonymInstances", LangExt.TypeSynonymInstances) - , ("UnboxedTuples", LangExt.UnboxedTuples) - , ("UnboxedSums", LangExt.UnboxedSums) - , ("UndecidableInstances", LangExt.UndecidableInstances) - , ("UndecidableSuperClasses", LangExt.UndecidableSuperClasses) - , ("UnicodeSyntax", LangExt.UnicodeSyntax) - , ("UnliftedDatatypes", LangExt.UnliftedDatatypes) - , ("UnliftedFFITypes", LangExt.UnliftedFFITypes) - , ("UnliftedNewtypes", LangExt.UnliftedNewtypes) - , ("ViewPatterns", LangExt.ViewPatterns) - ] - - - -- | Things you get with `-dlint`. enableDLint :: DynP () enableDLint = do ===================================== compiler/GHC/Types/Hint/Ppr.hs ===================================== @@ -383,7 +383,7 @@ pprImpliedExtensions extension = case implied of [] -> empty xs -> parens $ "implied by" <+> unquotedListWith "and" xs where implied = map ppr - . filter (\ext -> extensionDeprecation (show ext) == ExtensionNotDeprecated) + . filter (\ext -> extensionDeprecation ext == ExtensionNotDeprecated) . map (\(impl, _, _) -> impl) . filter (\(_, t, orig) -> orig == extension && t == turnOn) $ impliedXFlags ===================================== testsuite/tests/ghci/should_run/T10857a.stdout ===================================== @@ -1,4 +1,4 @@ base language is: GHC2021 with the following modifiers: - -XExtendedDefaultRules -XNoMonomorphismRestriction + -XExtendedDefaultRules View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/25c852b96be168ee6cc68b20e7ea81504cec2f34 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/25c852b96be168ee6cc68b20e7ea81504cec2f34 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 15:46:36 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 06 Apr 2024 11:46:36 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] 7 commits: Cleanup Message-ID: <66116e5c17cdf_3559ef2f7184821389@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 707f61fb by Sven Tennie at 2024-04-06T10:37:45+02:00 Cleanup Delete dead code, useless/obsolete comments ... - - - - - 3f002026 by Sven Tennie at 2024-04-06T10:39:52+02:00 Remove unused constructors Aarch64 and RISCV64 are just too different... - - - - - 4e654b45 by Sven Tennie at 2024-04-06T10:45:20+02:00 Remove more dead code - - - - - 0eaa6163 by Sven Tennie at 2024-04-06T11:43:59+02:00 Replace duplicated source Note by reference - - - - - 41b2d605 by Sven Tennie at 2024-04-06T11:44:30+02:00 Delete commented out code - - - - - 0a5accfd by Sven Tennie at 2024-04-06T11:44:54+02:00 TLabel was unused / unsupported - - - - - 36471c3e by Sven Tennie at 2024-04-06T17:45:50+02:00 Cleanup immediate pretty printing - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Instr.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -10,18 +10,20 @@ module GHC.CmmToAsm.RV64.CodeGen ( where --- NCG stuff: -import GHC.Prelude hiding (EQ) - +import Control.Monad (mapAndUnzipM) +import Data.Maybe import Data.Word - -import GHC.Platform.Regs -import GHC.CmmToAsm.RV64.Instr -import GHC.CmmToAsm.RV64.Regs -import GHC.CmmToAsm.RV64.Cond - -import GHC.CmmToAsm.CPrim +import GHC.Cmm +import GHC.Cmm.BlockId +import GHC.Cmm.CLabel +import GHC.Cmm.Dataflow.Block +import GHC.Cmm.Dataflow.Graph import GHC.Cmm.DebugBlock +import GHC.Cmm.Switch +import GHC.Cmm.Utils +import GHC.CmmToAsm.CPrim +import GHC.CmmToAsm.Config +import GHC.CmmToAsm.Format import GHC.CmmToAsm.Monad ( NatM, getConfig, @@ -32,72 +34,28 @@ import GHC.CmmToAsm.Monad getPicBaseMaybeNat, getPlatform, ) - --- import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC -import GHC.CmmToAsm.Format -import GHC.CmmToAsm.Config +import GHC.CmmToAsm.RV64.Cond +import GHC.CmmToAsm.RV64.Instr +import GHC.CmmToAsm.RV64.Regs import GHC.CmmToAsm.Types -import GHC.Platform.Reg -import GHC.Platform - --- Our intermediate code: -import GHC.Cmm.BlockId -import GHC.Cmm -import GHC.Cmm.Utils -import GHC.Cmm.Switch -import GHC.Cmm.CLabel -import GHC.Cmm.Dataflow.Block -import GHC.Cmm.Dataflow.Graph -import GHC.Types.Tickish ( GenTickish(..) ) -import GHC.Types.SrcLoc ( srcSpanFile, srcSpanStartLine, srcSpanStartCol ) - --- The rest: +import GHC.Data.FastString import GHC.Data.OrdList -import GHC.Utils.Outputable - -import Control.Monad ( mapAndUnzipM, foldM ) -import Data.Maybe import GHC.Float - +import GHC.Platform +import GHC.Platform.Reg +import GHC.Platform.Regs +import GHC.Prelude hiding (EQ) import GHC.Types.Basic import GHC.Types.ForeignCall -import GHC.Data.FastString +import GHC.Types.SrcLoc (srcSpanFile, srcSpanStartCol, srcSpanStartLine) +import GHC.Types.Tickish (GenTickish (..)) +import GHC.Utils.Constants (debugIsOn) import GHC.Utils.Misc +import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Constants (debugIsOn) --- Note [General layout of an NCG] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- @cmmTopCodeGen@ will be our main entry point to code gen. Here we'll get --- @RawCmmDecl@; see GHC.Cmm --- --- RawCmmDecl = GenCmmDecl RawCmmStatics (LabelMap RawCmmStatics) CmmGraph --- --- GenCmmDecl d h g = CmmProc h CLabel [GlobalReg] g --- | CmmData Section d --- --- As a result we want to transform this to a list of @NatCmmDecl@, which is --- defined @GHC.CmmToAsm.Instr@ as --- --- type NatCmmDecl statics instr --- = GenCmmDecl statics (LabelMap RawCmmStatics) (ListGraph instr) --- --- Thus well' turn --- GenCmmDecl RawCmmStatics (LabelMap RawCmmStatics) CmmGraph --- into --- [GenCmmDecl RawCmmStatics (LabelMap RawCmmStatics) (ListGraph Instr)] --- --- where @CmmGraph@ is --- --- type CmmGraph = GenCmmGraph CmmNode --- data GenCmmGraph n = CmmGraph { g_entry :: BlockId, g_graph :: Graph n C C } --- type CmmBlock = Block CmmNode C C --- --- and @ListGraph Instr@ is --- --- newtype ListGraph i = ListGraph [GenBasicBlock i] --- data GenBasicBlock i = BasicBlock BlockId [i] +-- For an overview of an NCG's structure, see Note [General layout of an NCG] cmmTopCodeGen :: RawCmmDecl @@ -379,12 +337,6 @@ getRegisterReg platform (CmmGlobal mid) -- ones which map to a real machine register on this -- platform. Hence if it's not mapped to a registers something -- went wrong earlier in the pipeline. --- | Convert a BlockId to some CmmStatic data --- TODO: Add JumpTable Logic, see Ticket 19912 --- jumpTableEntry :: NCGConfig -> Maybe BlockId -> CmmStatic --- jumpTableEntry config Nothing = CmmStaticLit (CmmInt 0 (ncgWordWidth config)) --- jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel) --- where blockLabel = blockLbl blockid -- ----------------------------------------------------------------------------- -- General things for putting together code sequences @@ -861,6 +813,7 @@ getRegister' config plat expr = -- TODO: Handle sub-word case MO_Sub w -> intOp False w (\d x y -> unitOL $ annExpr expr (SUB d x y)) + -- TODO: Check if this comment is correct -- Note [CSET] -- ~~~~~~~~~~~ -- Setting conditional flags: the architecture internally knows the @@ -937,11 +890,6 @@ getRegister' config plat expr = MO_F_Eq w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y EQ)) MO_F_Ne w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y NE)) - -- careful with the floating point operations. - -- SLE is effectively LE or unordered (NaN) - -- SLT is the same. ULE, and ULT will not return true for NaN. - -- This is a bit counter-intuitive. Don't let yourself be fooled by - -- the S/U prefix for floats, it's only meaningful for integers. MO_F_Ge w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y FGE)) MO_F_Le w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y FLE)) -- x <= y <=> y > x MO_F_Gt w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y FGT)) @@ -1706,14 +1654,6 @@ genCCall target dest_regs arg_regs bid = do let cconv = ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn genCCall (ForeignTarget target cconv) dest_regs arg_regs bid - -- TODO: Optimize using paired stores and loads (STP, LDP). It is - -- automatically done by the allocator for us. However it's not optimal, - -- as we'd rather want to have control over - -- all spill/load registers, so we can optimize with instructions like - -- STP xA, xB, [sp, #-16]! - -- and - -- LDP xA, xB, sp, #16 - -- passArguments :: Bool -> [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock) passArguments _packStack _ _ [] stackSpace accumRegs accumCode = return (stackSpace, accumRegs, accumCode) -- passArguments _ _ [] accumCode stackSpace | isEven stackSpace = return $ SUM (OpReg W64 x31) (OpReg W64 x31) OpImm (ImmInt (-8 * stackSpace)) ===================================== compiler/GHC/CmmToAsm/RV64/Instr.hs ===================================== @@ -87,8 +87,6 @@ regUsageOfInstr platform instr = case instr of -- 1. Arithmetic Instructions ------------------------------------------------ ADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - -- CMN l r -> usage (regOp l ++ regOp r, []) - -- CMP l r -> usage (regOp l ++ regOp r, []) MUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) NEG dst src -> usage (regOp src, regOp dst) SMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -99,15 +97,10 @@ regUsageOfInstr platform instr = case instr of DIVU dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) -- 2. Bit Manipulation Instructions ------------------------------------------ - SBFM dst src _ _ -> usage (regOp src, regOp dst) - UBFM dst src _ _ -> usage (regOp src, regOp dst) - UBFX dst src _ _ -> usage (regOp src, regOp dst) -- 3. Logical and Move Instructions ------------------------------------------ AND dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) OR dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) ASR dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - BIC dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - BICS dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) XOR dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) LSL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) LSR dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -132,10 +125,6 @@ regUsageOfInstr platform instr = case instr of -- STLR _ src dst L -> usage (regOp src ++ regOp dst, []) LDR _ dst src -> usage (regOp src, regOp dst) LDRU _ dst src -> usage (regOp src, regOp dst) - -- LDAR _ dst src -> usage (regOp src, regOp dst) - -- TODO is this right? see STR, which I'm only partial about being right? - -- STP _ src1 src2 dst -> usage (regOp src1 ++ regOp src2 ++ regOp dst, []) - -- LDP _ dst1 dst2 src -> usage (regOp src, regOp dst1 ++ regOp dst2) -- 8. Synchronization Instructions ------------------------------------------- DMBSY _ _ -> usage ([], []) @@ -164,7 +153,6 @@ regUsageOfInstr platform instr = case instr of regOp (OpImm _) = [] regTarget :: Target -> [Reg] regTarget (TBlock _) = [] - regTarget (TLabel _) = [] regTarget (TReg r1) = [r1] -- Is this register interesting for the register allocator? @@ -216,8 +204,6 @@ patchRegsOfInstr instr env = case instr of DELTA{} -> instr -- 1. Arithmetic Instructions ---------------------------------------------- ADD o1 o2 o3 -> ADD (patchOp o1) (patchOp o2) (patchOp o3) - -- CMN o1 o2 -> CMN (patchOp o1) (patchOp o2) - -- CMP o1 o2 -> CMP (patchOp o1) (patchOp o2) MUL o1 o2 o3 -> MUL (patchOp o1) (patchOp o2) (patchOp o3) NEG o1 o2 -> NEG (patchOp o1) (patchOp o2) SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2) (patchOp o3) @@ -228,17 +214,11 @@ patchRegsOfInstr instr env = case instr of DIVU o1 o2 o3 -> DIVU (patchOp o1) (patchOp o2) (patchOp o3) -- 2. Bit Manipulation Instructions ---------------------------------------- - SBFM o1 o2 o3 o4 -> SBFM (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) - UBFM o1 o2 o3 o4 -> UBFM (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) - UBFX o1 o2 o3 o4 -> UBFX (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) -- 3. Logical and Move Instructions ---------------------------------------- AND o1 o2 o3 -> AND (patchOp o1) (patchOp o2) (patchOp o3) OR o1 o2 o3 -> OR (patchOp o1) (patchOp o2) (patchOp o3) - -- ANDS o1 o2 o3 -> ANDS (patchOp o1) (patchOp o2) (patchOp o3) ASR o1 o2 o3 -> ASR (patchOp o1) (patchOp o2) (patchOp o3) - BIC o1 o2 o3 -> BIC (patchOp o1) (patchOp o2) (patchOp o3) - BICS o1 o2 o3 -> BICS (patchOp o1) (patchOp o2) (patchOp o3) XOR o1 o2 o3 -> XOR (patchOp o1) (patchOp o2) (patchOp o3) LSL o1 o2 o3 -> LSL (patchOp o1) (patchOp o2) (patchOp o3) LSR o1 o2 o3 -> LSR (patchOp o1) (patchOp o2) (patchOp o3) @@ -264,9 +244,6 @@ patchRegsOfInstr instr env = case instr of -- STLR f o1 o2 -> STLR f (patchOp o1) (patchOp o2) LDR f o1 o2 -> LDR f (patchOp o1) (patchOp o2) LDRU f o1 o2 -> LDRU f (patchOp o1) (patchOp o2) - -- LDAR f o1 o2 -> LDAR f (patchOp o1) (patchOp o2) - -- STP f o1 o2 o3 -> STP f (patchOp o1) (patchOp o2) (patchOp o3) - -- LDP f o1 o2 o3 -> LDP f (patchOp o1) (patchOp o2) (patchOp o3) -- 8. Synchronization Instructions ----------------------------------------- DMBSY o1 o2 -> DMBSY o1 o2 @@ -310,7 +287,7 @@ isJumpishInstr instr = case instr of jumpDestsOfInstr :: Instr -> [BlockId] jumpDestsOfInstr (ANN _ i) = jumpDestsOfInstr i jumpDestsOfInstr (J t) = [id | TBlock id <- [t]] -jumpDestsOfInstr (J_TBL ids _mbLbl _r) = [id | Just id <- ids] +jumpDestsOfInstr (J_TBL ids _mbLbl _r) = catMaybes ids jumpDestsOfInstr (B t) = [id | TBlock id <- [t]] jumpDestsOfInstr (B_FAR t) = [t] jumpDestsOfInstr (BL t _ _) = [id | TBlock id <- [t]] @@ -532,9 +509,6 @@ allocMoreStack platform slots proc@(CmmProc info lbl live (ListGraph code)) = do -- We have a few common "instructions" (nearly all the pseudo-ops) but -- mostly all of 'Instr' is machine-specific. --- Some additional (potential future) instructions are commented out. They are --- not needed yet for the backend but could be used in the future. - -- RV64 reference card: https://cs61c.org/sp23/pdfs/resources/reference-card.pdf -- RV64 pseudo instructions: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#-a-listing-of-standard-risc-v-pseudoinstructions -- We will target: RV64G(C). That is G = I+A+F+S+D @@ -573,8 +547,6 @@ data Instr | DELTA Int -- 0. Pseudo Instructions -------------------------------------------------- - -- | SXTW Operand Operand - -- | SXTX Operand Operand | PUSH_STACK_FRAME | POP_STACK_FRAME @@ -590,10 +562,7 @@ data Instr -- | XOR Operand Operand Operand -- rd = rs1 ^ rs2 | LSL {- SLL -} Operand Operand Operand -- rd = rs1 << rs2 (zero ext) | LSR {- SRL -} Operand Operand Operand -- rd = rs1 >> rs2 (zero ext) - -- | ASL {- SLA -} Operand Operand Operand -- rd = rs1 << rs2 (sign ext) | ASR {- SRA -} Operand Operand Operand -- rd = rs1 >> rs2 (sign ext) - -- | SLT Operand Operand Operand -- rd = rs1 < rs2 ? 1 : 0 (signed) - -- | SLTU Operand Operand Operand -- rd = rs1 < rs2 ? 1 : 0 (unsigned) -- 2. Memory Load/Store Instructions --------------------------------------- -- Unlike arm, we don't have register shorthands for size. @@ -609,16 +578,10 @@ data Instr -- powerful. -- JAL / JARL are effectively the BL instruction from AArch64. - - -- | CMN Operand Operand -- rd + op2 - -- | CMP Operand Operand -- rd - op2 - | MUL Operand Operand Operand -- rd = rn × rm -- Pseudo/synthesized: - -- NEG = SUB x, 0, y - -- NOT = XOR -1, x | NEG Operand Operand -- rd = -op2 | DIV Operand Operand Operand -- rd = rn ÷ rm @@ -630,19 +593,11 @@ data Instr | DIVU Operand Operand Operand -- rd = rn ÷ rm -- 2. Bit Manipulation Instructions ---------------------------------------- - | SBFM Operand Operand Operand Operand -- rd = rn[i,j] - | UBFM Operand Operand Operand Operand -- rd = rn[i,j] - -- Signed/Unsigned bitfield extract - | UBFX Operand Operand Operand Operand -- rd = rn[i,j] -- 3. Logical and Move Instructions ---------------------------------------- -- | AND Operand Operand Operand -- rd = rn & op2 -- | ANDS Operand Operand Operand -- rd = rn & op2 -- | ASR Operand Operand Operand -- rd = rn ≫ rm or rd = rn ≫ #i, i is 6 bits - -- TODO: unused - | BIC Operand Operand Operand -- rd = rn & ~op2 - -- TODO: unused - | BICS Operand Operand Operand -- rd = rn & ~op2 | XOR Operand Operand Operand -- rd = rn ⊕ op2 -- | LSL Operand Operand Operand -- rd = rn ≪ rm or rd = rn ≪ #i, i is 6 bits -- | LSR Operand Operand Operand -- rd = rn ≫ rm or rd = rn ≫ #i, i is 6 bits @@ -650,13 +605,6 @@ data Instr | ORI Operand Operand Operand -- rd = rn | op2 | XORI Operand Operand Operand -- rd = rn `xor` imm -- Load and stores. - -- TODO STR/LDR might want to change to STP/LDP with XZR for the second register. - -- | STR Format Operand Operand -- str Xn, address-mode // Xn -> *addr - -- | STLR Format Operand Operand -- stlr Xn, address-mode // Xn -> *addr - -- | LDR Format Operand Operand -- ldr Xn, address-mode // Xn <- *addr - -- | LDAR Format Operand Operand -- ldar Xn, address-mode // Xn <- *addr - -- | STP Format Operand Operand Operand -- stp Xn, Xm, address-mode // Xn -> *addr, Xm -> *(addr + 8) - -- | LDP Format Operand Operand Operand -- stp Xn, Xm, address-mode // Xn <- *addr, Xm <- *(addr + 8) -- Conditional instructions -- This is a synthetic operation. @@ -711,13 +659,8 @@ instrCon i = SMULH{} -> "SMULH" SUB{} -> "SUB" DIVU{} -> "DIVU" - SBFM{} -> "SBFM" - UBFM{} -> "UBFM" - UBFX{} -> "UBFX" AND{} -> "AND" ASR{} -> "ASR" - BIC{} -> "BIC" - BICS{} -> "BICS" XOR{} -> "XOR" LSL{} -> "LSL" LSR{} -> "LSR" @@ -741,17 +684,18 @@ instrCon i = FCVTZS{} -> "FCVTZS" FABS{} -> "FABS" --- TODO: We don't need TLabel. data Target = TBlock BlockId - | TLabel CLabel | TReg Reg data Operand - = OpReg Width Reg -- register - | OpImm Imm -- immediate value - | OpAddr AddrMode -- memory reference - deriving (Eq, Show) + = -- | register + OpReg Width Reg + | -- | immediate value + OpImm Imm + | -- | memory reference + OpAddr AddrMode + deriving (Eq, Show) operandFromReg :: Reg -> Operand operandFromReg = OpReg W64 ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -231,10 +231,10 @@ pprDataItem config lit imm = litToImm lit - ppr_item II8 _ = [text "\t.byte\t" <> pprImm platform imm] - ppr_item II16 _ = [text "\t.short\t" <> pprImm platform imm] - ppr_item II32 _ = [text "\t.long\t" <> pprImm platform imm] - ppr_item II64 _ = [text "\t.quad\t" <> pprImm platform imm] + ppr_item II8 _ = [text "\t.byte\t" <> pprDataImm platform imm] + ppr_item II16 _ = [text "\t.short\t" <> pprDataImm platform imm] + ppr_item II32 _ = [text "\t.long\t" <> pprDataImm platform imm] + ppr_item II64 _ = [text "\t.quad\t" <> pprDataImm platform imm] ppr_item FF32 (CmmFloat r _) = let bs = floatToBytes (fromRational r) @@ -246,23 +246,23 @@ pprDataItem config lit ppr_item _ _ = pprPanic "pprDataItem:ppr_item" (text $ show lit) -pprImm :: IsLine doc => Platform -> Imm -> doc -pprImm _ (ImmInt i) = int i -pprImm _ (ImmInteger i) = integer i -pprImm p (ImmCLbl l) = pprAsmLabel p l -pprImm p (ImmIndex l i) = pprAsmLabel p l <> char '+' <> int i -pprImm _ (ImmLit s) = ftext s - --- TODO: See pprIm below for why this is a bad idea! -pprImm _ (ImmFloat f) = float (fromRational f) -pprImm _ (ImmDouble d) = double (fromRational d) - -pprImm p (ImmConstantSum a b) = pprImm p a <> char '+' <> pprImm p b -pprImm p (ImmConstantDiff a b) = pprImm p a <> char '-' - <> lparen <> pprImm p b <> rparen - +-- | Pretty print an immediate value in the @data@ section +-- +-- This does not include any checks. We rely on the Assembler to check for +-- errors. Use `pprOpImm` for immediates in instructions (operands.) +pprDataImm :: IsLine doc => Platform -> Imm -> doc +pprDataImm _ (ImmInt i) = int i +pprDataImm _ (ImmInteger i) = integer i +pprDataImm p (ImmCLbl l) = pprAsmLabel p l +pprDataImm p (ImmIndex l i) = pprAsmLabel p l <> char '+' <> int i +pprDataImm _ (ImmLit s) = ftext s +pprDataImm _ (ImmFloat f) = float (fromRational f) +pprDataImm _ (ImmDouble d) = double (fromRational d) + +pprDataImm p (ImmConstantSum a b) = pprDataImm p a <> char '+' <> pprDataImm p b +pprDataImm p (ImmConstantDiff a b) = pprDataImm p a <> char '-' + <> lparen <> pprDataImm p b <> rparen --- aarch64 GNU as uses // for comments. asmComment :: SDoc -> SDoc asmComment c = text "#" <+> c @@ -272,32 +272,18 @@ asmDoubleslashComment c = text "//" <+> c asmMultilineComment :: SDoc -> SDoc asmMultilineComment c = text "/*" $+$ c $+$ text "*/" -pprIm :: IsLine doc => Platform -> Imm -> doc -pprIm platform im = case im of - ImmInt i -> int i +-- | Pretty print an immediate operand of an instruction +-- +-- The kinds of immediates we can use here is pretty limited: RISCV doesn't +-- support index expressions (as e.g. Aarch64 does.) Floating points need to +-- fit in range. As we don't need them, forbit them to save us from future +-- troubles. +pprOpImm :: (IsLine doc) => Platform -> Imm -> doc +pprOpImm platform im = case im of + ImmInt i -> int i ImmInteger i -> integer i - - -- FIXME: This is AArch64 commentry, not necesarily correct for RISCV! - -- TODO: This will only work for - -- The floating point value must be expressible as ±n ÷ 16 × 2^r, - -- where n and r are integers such that 16 ≤ n ≤ 31 and -3 ≤ r ≤ 4. - -- and 0 needs to be encoded as wzr/xzr. - -- - -- Except for 0, we might want to either split it up into enough - -- ADD operations into an Integer register and then just bit copy it into - -- the double register? See the toBytes + fromRational above for data items. - -- This is something the x86 backend does. - -- - -- We could also just turn them into statics :-/ Which is what the - -- PowerPC backend does. - ImmFloat f | f == 0 -> text "zero" - ImmFloat f -> char '#' <> float (fromRational f) - ImmDouble d | d == 0 -> text "zero" - ImmDouble d -> char '#' <> double (fromRational d) - -- = pseudo instruction! - ImmCLbl l -> char '=' <> pprAsmLabel platform l - ImmIndex l o -> text "[=" <> pprAsmLabel platform l <> comma <+> char '#' <> int o <> char ']' - _ -> panic "AArch64.pprIm" + ImmCLbl l -> char '=' <> pprAsmLabel platform l + _ -> pprPanic "RV64.Ppr.pprOpImm" (text "Unsupported immediate for instruction operands" <> colon <+> (text . show) im) negOp :: Operand -> Operand negOp (OpImm (ImmInt i)) = OpImm (ImmInt (negate i)) @@ -307,8 +293,8 @@ negOp op = pprPanic "RV64.negOp" (text $ show op) pprOp :: IsLine doc => Platform -> Operand -> doc pprOp plat op = case op of OpReg w r -> pprReg w r - OpImm im -> pprIm plat im - OpAddr (AddrRegImm r1 im) -> pprImm plat im <> char '(' <> pprReg W64 r1 <> char ')' + OpImm im -> pprOpImm plat im + OpAddr (AddrRegImm r1 im) -> pprOpImm plat im <> char '(' <> pprReg W64 r1 <> char ')' OpAddr (AddrReg r1) -> text "0(" <+> pprReg W64 r1 <+> char ')' pprReg :: forall doc. IsLine doc => Width -> Reg -> doc @@ -416,12 +402,10 @@ isImmZero _ = False isLabel :: Target -> Bool isLabel (TBlock _) = True -isLabel (TLabel _) = True isLabel _ = False getLabel :: IsLine doc => Platform -> Target -> doc getLabel platform (TBlock bid) = pprBlockId platform bid -getLabel platform (TLabel lbl) = pprAsmLabel platform lbl getLabel _platform _other = panic "Cannot turn this into a label" pprBlockId :: IsLine doc => Platform -> BlockId -> doc @@ -459,11 +443,6 @@ pprInstr platform instr = case instr of -- This case is used for sign extension: SEXT.W op | OpReg W64 _ <- o1 , OpReg W32 _ <- o2, isImmOp o3 -> op3 (text "\taddiw") o1 o2 o3 | otherwise -> op3 (text "\tadd") o1 o2 o3 - -- TODO: Delete commented out code. - -- CMN o1 o2 -> op2 (text "\tcmn") o1 o2 - -- CMP o1 o2 - -- | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 - -- | otherwise -> op2 (text "\tcmp") o1 o2 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul." <> if isSingleOp o1 then text "s" else text "d") o1 o2 o3 | otherwise -> op3 (text "\tmul") o1 o2 o3 @@ -487,22 +466,12 @@ pprInstr platform instr = case instr of DIVU o1 o2 o3 -> op3 (text "\tdivu") o1 o2 o3 -- 2. Bit Manipulation Instructions ------------------------------------------ - -- TODO: Non-existant in RISCV - delete - SBFM o1 o2 o3 o4 -> op4 (text "\tsbfm") o1 o2 o3 o4 - -- TODO: Non-existant in RISCV - delete - UBFM o1 o2 o3 o4 -> op4 (text "\tubfm") o1 o2 o3 o4 - -- signed and unsigned bitfield extract - -- TODO: Non-existant in RISCV - delete - UBFX o1 o2 o3 o4 -> op4 (text "\tubfx") o1 o2 o3 o4 -- 3. Logical and Move Instructions ------------------------------------------ AND o1 o2 o3 -> op3 (text "\tand") o1 o2 o3 OR o1 o2 o3 -> op3 (text "\tor") o1 o2 o3 - -- ANDS o1 o2 o3 -> op3 (text "\tands") o1 o2 o3 ASR o1 o2 o3 | isImmOp o3 -> op3 (text "\tsrai") o1 o2 o3 ASR o1 o2 o3 -> op3 (text "\tsra") o1 o2 o3 - BIC o1 o2 o3 -> op3 (text "\tbic") o1 o2 o3 - BICS o1 o2 o3 -> op3 (text "\tbics") o1 o2 o3 XOR o1 o2 o3 -> op3 (text "\txor") o1 o2 o3 LSL o1 o2 o3 -> op3 (text "\tsll") o1 o2 o3 LSR o1 o2 o3 -> op3 (text "\tsrl") o1 o2 o3 @@ -652,10 +621,6 @@ pprInstr platform instr = case instr of LDRU FF64 o1 o2@(OpAddr (AddrReg _)) -> op2 (text "\tfld") o1 o2 LDRU FF64 o1 o2@(OpAddr (AddrRegImm _ _)) -> op2 (text "\tfld") o1 o2 LDRU f o1 o2 -> pprPanic "Unsupported unsigned load" ((text.show) f <+> pprOp platform o1 <+> pprOp platform o2) - -- LDAR _f o1 o2 -> op2 (text "\tldar") o1 o2 - - -- STP _f o1 o2 o3 -> op3 (text "\tstp") o1 o2 o3 - -- LDP _f o1 o2 o3 -> op3 (text "\tldp") o1 o2 o3 -- 8. Synchronization Instructions ------------------------------------------- DMBSY r w -> line $ text "\tfence" <+> pprDmbType r <> char ',' <+> pprDmbType w @@ -685,11 +650,6 @@ pprInstr platform instr = case instr of instr -> panic $ "RV64.pprInstr - Unknown instruction: " ++ instrCon instr where op2 op o1 o2 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 op3 op o1 o2 o3 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 - op4 op o1 o2 o3 o4 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 <> comma <+> pprOp platform o4 - -- TODO: Delete commented out code. - -- op_ldr o1 rest = line $ text "\tld" <+> pprOp platform o1 <> comma <+> rest <+> text "(" <> pprOp platform o1 <> text ")" - -- op_adrp o1 rest = line $ text "\tauipc" <+> pprOp platform o1 <> comma <+> rest - -- op_add o1 rest = line $ text "\taddi" <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> rest pprDmbType DmbRead = text "r" pprDmbType DmbWrite = text "w" pprDmbType DmbReadWrite = text "rw" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61f8c7e4a06349df7fe31863ac9791abee2741db...36471c3ebe3b8824dc31c33825a0f2eced92f63f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61f8c7e4a06349df7fe31863ac9791abee2741db...36471c3ebe3b8824dc31c33825a0f2eced92f63f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 15:47:15 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Sat, 06 Apr 2024 11:47:15 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Try out a variant of Simon's fix to the second perf problem Message-ID: <66116e83aa132_3559ef3038c68219f6@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 7e0adeab by Mikolaj Konarski at 2024-04-06T17:36:43+02:00 Try out a variant of Simon's fix to the second perf problem - - - - - 1 changed file: - compiler/GHC/Core/TyCo/FVs.hs Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -668,7 +668,8 @@ tyCoFVsOfCoVar v fv_cand in_scope acc tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc -tyCoFVsOfProv (PluginProv _ cvs) fv_cand in_scope acc = mkFVs (dVarSetElems cvs) fv_cand in_scope acc +tyCoFVsOfProv (PluginProv _ cvs) _ _ (have, haveSet) = + (dVarSetElems cvs ++ have, dVarSetToVarSet cvs `unionVarSet` haveSet) tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e0adeab973de7cafb24770875d59c7befa2582b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e0adeab973de7cafb24770875d59c7befa2582b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 15:51:57 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sat, 06 Apr 2024 11:51:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-warningtxt-epalocation Message-ID: <66116f9daebf3_3559ef31c72b422593@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-warningtxt-epalocation at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-warningtxt-epalocation You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 18:46:32 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Sat, 06 Apr 2024 14:46:32 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Ajust a single test in testsuite that uses PluginProv Message-ID: <66119888dd219_183ba52729c8757cd@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 318499d8 by Mikolaj Konarski at 2024-04-06T20:46:23+02:00 Ajust a single test in testsuite that uses PluginProv - - - - - 1 changed file: - testsuite/tests/pmcheck/should_compile/T11195.hs Changes: ===================================== testsuite/tests/pmcheck/should_compile/T11195.hs ===================================== @@ -84,7 +84,7 @@ opt_trans_rule is in_co1@(UnivCo p1 r1 tyl1 _tyr1) = Just $ PhantomProv $ opt_trans is kco1 kco2 opt_trans_prov (ProofIrrelProv kco1) (ProofIrrelProv kco2) = Just $ ProofIrrelProv $ opt_trans is kco1 kco2 - opt_trans_prov (PluginProv str1) (PluginProv str2) + opt_trans_prov (PluginProv str1 _) (PluginProv str2 _) | str1 == str2 = Just p1 opt_trans_prov _ _ = Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/318499d81e685fd6ad9bb39c80f5bc217276301e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/318499d81e685fd6ad9bb39c80f5bc217276301e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 18:53:58 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Sat, 06 Apr 2024 14:53:58 -0400 Subject: [Git][ghc/ghc][wip/T24477] Improve suggestions for language extensions Message-ID: <66119a46a3e9f_183ba53e8f3c76346@gitlab.mail> Jade pushed to branch wip/T24477 at Glasgow Haskell Compiler / GHC Commits: fb287149 by Jade at 2024-04-06T20:55:38+02:00 Improve suggestions for language extensions - When suggesting Language extensions, also suggest Extensions which imply them - Suggest ExplicitForAll and GADTSyntax instead of more specific extensions - Rephrase suggestion to include the term 'Extension' - Also moves some flag specific definitions out of Session.hs into Flags.hs (#24478) Fixes: #24477 Fixes: #24448 Fixes: #10893 - - - - - 30 changed files: - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Utils/Outputable.hs - testsuite/tests/dependent/should_fail/T15215.stderr - testsuite/tests/dependent/should_fail/T15859.stderr - testsuite/tests/dependent/should_fail/T16326_Fail1.stderr - testsuite/tests/dependent/should_fail/T16326_Fail10.stderr - testsuite/tests/dependent/should_fail/T16326_Fail11.stderr - testsuite/tests/dependent/should_fail/T16326_Fail2.stderr - testsuite/tests/dependent/should_fail/T16326_Fail3.stderr - testsuite/tests/dependent/should_fail/T16326_Fail4.stderr - testsuite/tests/dependent/should_fail/T16326_Fail5.stderr - testsuite/tests/dependent/should_fail/T16326_Fail7.stderr - testsuite/tests/dependent/should_fail/T16326_Fail9.stderr - testsuite/tests/dependent/should_fail/T17687.stderr - testsuite/tests/deriving/should_compile/T16179.stderr - testsuite/tests/deriving/should_fail/T10598_fail2.stderr - testsuite/tests/deriving/should_fail/T10598_fail4.stderr - testsuite/tests/deriving/should_fail/T10598_fail5.stderr - testsuite/tests/deriving/should_fail/T1133A.stderr - testsuite/tests/deriving/should_fail/T12512.stderr - testsuite/tests/deriving/should_fail/T19692.stderr - testsuite/tests/deriving/should_fail/T3833.stderr - testsuite/tests/deriving/should_fail/T3834.stderr - testsuite/tests/deriving/should_fail/T7401_fail.stderr - testsuite/tests/deriving/should_fail/T7959.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fb2871499f748bb24c54e6dc8b0ab729914bd726 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fb2871499f748bb24c54e6dc8b0ab729914bd726 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 6 22:29:55 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Sat, 06 Apr 2024 18:29:55 -0400 Subject: [Git][ghc/ghc][wip/T24477] Improve suggestions for language extensions Message-ID: <6611cce3f2bcd_2297eb346674206e5@gitlab.mail> Jade pushed to branch wip/T24477 at Glasgow Haskell Compiler / GHC Commits: cc3bec95 by Jade at 2024-04-07T00:34:35+02:00 Improve suggestions for language extensions - When suggesting Language extensions, also suggest Extensions which imply them - Suggest ExplicitForAll and GADTSyntax instead of more specific extensions - Rephrase suggestion to include the term 'Extension' - Also moves some flag specific definitions out of Session.hs into Flags.hs (#24478) Fixes: #24477 Fixes: #24448 Fixes: #10893 - - - - - 30 changed files: - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Utils/Outputable.hs - testsuite/tests/dependent/should_fail/T15215.stderr - testsuite/tests/dependent/should_fail/T15859.stderr - testsuite/tests/dependent/should_fail/T16326_Fail1.stderr - testsuite/tests/dependent/should_fail/T16326_Fail10.stderr - testsuite/tests/dependent/should_fail/T16326_Fail11.stderr - testsuite/tests/dependent/should_fail/T16326_Fail2.stderr - testsuite/tests/dependent/should_fail/T16326_Fail3.stderr - testsuite/tests/dependent/should_fail/T16326_Fail4.stderr - testsuite/tests/dependent/should_fail/T16326_Fail5.stderr - testsuite/tests/dependent/should_fail/T16326_Fail7.stderr - testsuite/tests/dependent/should_fail/T16326_Fail9.stderr - testsuite/tests/dependent/should_fail/T17687.stderr - testsuite/tests/deriving/should_compile/T16179.stderr - testsuite/tests/deriving/should_fail/T10598_fail2.stderr - testsuite/tests/deriving/should_fail/T10598_fail4.stderr - testsuite/tests/deriving/should_fail/T10598_fail5.stderr - testsuite/tests/deriving/should_fail/T1133A.stderr - testsuite/tests/deriving/should_fail/T12512.stderr - testsuite/tests/deriving/should_fail/T19692.stderr - testsuite/tests/deriving/should_fail/T3833.stderr - testsuite/tests/deriving/should_fail/T3834.stderr - testsuite/tests/deriving/should_fail/T7401_fail.stderr - testsuite/tests/deriving/should_fail/T7959.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc3bec95c3a433758ceb7dc3a8eba177d125f57b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc3bec95c3a433758ceb7dc3a8eba177d125f57b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 7 10:14:39 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 07 Apr 2024 06:14:39 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-T24533-3 Message-ID: <6612720f6a735_3046f92d495fc68af@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-T24533-3 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-T24533-3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 7 12:55:45 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 07 Apr 2024 08:55:45 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Cleanup C calling conv code Message-ID: <661297d1239c3_1965d986ace0653ed@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 5d05c008 by Sven Tennie at 2024-04-07T14:54:55+02:00 Cleanup C calling conv code - - - - - 1 changed file: - compiler/GHC/CmmToAsm/RV64/CodeGen.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -1410,10 +1410,7 @@ genCCall target dest_regs arg_regs bid = do let (_res_hints, arg_hints) = foreignTargetHints target arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints - platform <- getPlatform - let packStack = platformOS platform == OSDarwin - - (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL + (stackSpace', passRegs, passArgumentsCode) <- passArguments allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL -- if we pack the stack, we may need to adjust to multiple of 8byte. -- if we don't pack the stack, it will always be multiple of 8. @@ -1654,47 +1651,14 @@ genCCall target dest_regs arg_regs bid = do let cconv = ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn genCCall (ForeignTarget target cconv) dest_regs arg_regs bid - passArguments :: Bool -> [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock) - passArguments _packStack _ _ [] stackSpace accumRegs accumCode = return (stackSpace, accumRegs, accumCode) - -- passArguments _ _ [] accumCode stackSpace | isEven stackSpace = return $ SUM (OpReg W64 x31) (OpReg W64 x31) OpImm (ImmInt (-8 * stackSpace)) - -- passArguments _ _ [] accumCode stackSpace = return $ SUM (OpReg W64 x31) (OpReg W64 x31) OpImm (ImmInt (-8 * (stackSpace + 1))) - -- passArguments [] fpRegs (arg0:arg1:args) stack accumCode = do - -- -- allocate this on the stack - -- (r0, format0, code_r0) <- getSomeReg arg0 - -- (r1, format1, code_r1) <- getSomeReg arg1 - -- let w0 = formatToWidth format0 - -- w1 = formatToWidth format1 - -- stackCode = unitOL $ STP (OpReg w0 r0) (OpReg w1 R1), (OpAddr (AddrRegImm x31 (ImmInt (stackSpace * 8))) - -- passArguments gpRegs (fpReg:fpRegs) args (stackCode `appOL` accumCode) - - -- float promotion. - -- According to - -- ISO/IEC 9899:2018 - -- Information technology — Programming languages — C - -- - -- e.g. - -- http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf - -- http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf - -- - -- GHC would need to know the prototype. - -- - -- > If the expression that denotes the called function has a type that does not include a - -- > prototype, the integer promotions are performed on each argument, and arguments that - -- > have type float are promoted to double. - -- - -- As we have no way to get prototypes for C yet, we'll *not* promote this - -- which is in line with the x86_64 backend :( - -- - -- See the encode_values.cmm test. - -- - -- We would essentially need to insert an FCVT (OpReg W64 fpReg) (OpReg W32 fpReg) - -- if w == W32. But *only* if we don't have a prototype m( - -- - -- For AArch64 specificies see: https://developer.arm.com/docs/ihi0055/latest/procedure-call-standard-for-the-arm-64-bit-architecture - -- - -- Still have GP regs, and we want to pass an GP argument. + -- Implementiation of the RISCV ABI calling convention. + -- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/948463cd5dbebea7c1869e20146b17a2cc8fda2f/riscv-cc.adoc#integer-calling-convention + passArguments :: [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock) + -- Base case: no more arguments to pass (left) + passArguments _ _ [] stackSpace accumRegs accumCode = return (stackSpace, accumRegs, accumCode) - passArguments pack (gpReg:gpRegs) fpRegs ((r, format, hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do + -- Still have GP regs, and we want to pass an GP argument. + passArguments (gpReg:gpRegs) fpRegs ((r, format, hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do -- RISCV64 Integer Calling Convention: "When passed in registers or on the -- stack, integer scalars narrower than XLEN bits are widened according to -- the sign of their type up to 32 bits, then sign-extended to XLEN bits." @@ -1708,27 +1672,22 @@ genCCall target dest_regs arg_regs bid = do accumCode' = accumCode `appOL` code_r `appOL` assignArg - passArguments pack gpRegs fpRegs args stackSpace (gpReg:accumRegs) accumCode' + passArguments gpRegs fpRegs args stackSpace (gpReg:accumRegs) accumCode' -- Still have FP regs, and we want to pass an FP argument. - passArguments pack gpRegs (fpReg:fpRegs) ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isFloatFormat format = do + passArguments gpRegs (fpReg:fpRegs) ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isFloatFormat format = do let w = formatToWidth format mov = MOV (OpReg w fpReg) (OpReg w r) accumCode' = accumCode `appOL` code_r `snocOL` ann (text "Pass fp argument: " <> ppr r) mov - passArguments pack gpRegs fpRegs args stackSpace (fpReg:accumRegs) accumCode' + passArguments gpRegs fpRegs args stackSpace (fpReg:accumRegs) accumCode' -- No mor regs left to pass. Must pass on stack. - -- TODO: Pack can probably be deleted - passArguments pack [] [] ((r, format, hint, code_r) : args) stackSpace accumRegs accumCode = do + passArguments [] [] ((r, format, hint, code_r) : args) stackSpace accumRegs accumCode = do let w = formatToWidth format - bytes = widthInBits w `div` 8 - space = if pack then bytes else 8 - stackSpace' - | pack && stackSpace `mod` space /= 0 = stackSpace + space - (stackSpace `mod` space) - | otherwise = stackSpace - str = STR format (OpReg w r) (OpAddr (AddrRegImm (regSingle 2) (ImmInt stackSpace'))) + space = 8 + str = STR format (OpReg w r) (OpAddr (AddrRegImm (regSingle 2) (ImmInt stackSpace))) stackCode = if hint == SignedHint then @@ -1738,30 +1697,27 @@ genCCall target dest_regs arg_regs bid = do else code_r `snocOL` ann (text "Pass unsigned argument (size " <> ppr w <> text ") on the stack: " <> ppr r) str - passArguments pack [] [] args (stackSpace' + space) accumRegs (stackCode `appOL` accumCode) + passArguments [] [] args (stackSpace + space) accumRegs (stackCode `appOL` accumCode) --- Still have fpRegs left, but want to pass a GP argument. Must be passed on the stack then. - passArguments pack [] fpRegs ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do + -- Still have fpRegs left, but want to pass a GP argument. Must be passed on the stack then. + passArguments [] fpRegs ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do let w = formatToWidth format - bytes = widthInBits w `div` 8 - space = if pack then bytes else 8 - stackSpace' | pack && stackSpace `mod` space /= 0 = stackSpace + space - (stackSpace `mod` space) - | otherwise = stackSpace - str = STR format (OpReg w r) (OpAddr (AddrRegImm (regSingle 2) (ImmInt stackSpace'))) + space = 8 + str = STR format (OpReg w r) (OpAddr (AddrRegImm (regSingle 2) (ImmInt stackSpace))) stackCode = code_r `snocOL` ann (text "Pass argument (size " <> ppr w <> text ") on the stack: " <> ppr r) str - passArguments pack [] fpRegs args (stackSpace'+space) accumRegs (stackCode `appOL` accumCode) + passArguments [] fpRegs args (stackSpace+space) accumRegs (stackCode `appOL` accumCode) -- Still have gpRegs left, but want to pass a FP argument. Must be passed in gpReg then. - passArguments pack (gpReg:gpRegs) [] ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isFloatFormat format = do + passArguments (gpReg:gpRegs) [] ((r, format, _hint, code_r):args) stackSpace accumRegs accumCode | isFloatFormat format = do let w = formatToWidth format mov = MOV (OpReg w gpReg) (OpReg w r) accumCode' = accumCode `appOL` code_r `snocOL` ann (text "Pass fp argument in gpReg: " <> ppr r) mov - passArguments pack gpRegs [] args stackSpace (gpReg:accumRegs) accumCode' + passArguments gpRegs [] args stackSpace (gpReg:accumRegs) accumCode' - passArguments _ _ _ _ _ _ _ = pprPanic "passArguments" (text "invalid state") + passArguments _ _ _ _ _ _ = pprPanic "passArguments" (text "invalid state") readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg]-> InstrBlock -> NatM ([Reg], InstrBlock) readResults _ _ [] accumRegs accumCode = return (accumRegs, accumCode) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d05c0085c3cf1c23c949b1046b0a1710e6fc20a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d05c0085c3cf1c23c949b1046b0a1710e6fc20a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 09:51:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 08 Apr 2024 05:51:30 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 2 commits: Add deduplication table for `IfaceType` Message-ID: <6613be22ba27d_1da3db44f13878828@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 543544d6 by Matthew Pickering at 2024-04-08T11:51:05+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 17010aed by Fendor at 2024-04-08T11:51:05+02:00 Add IfaceType deduplication table to .hie serialisation Refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 20 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - utils/haddock Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -952,13 +952,13 @@ data CoSel -- See Note [SelCo] | SelForAll -- Decomposes (forall a. co) - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) data FunSel -- See Note [SelCo] = SelMult -- Multiplicity | SelArg -- Argument of function | SelRes -- Result of function - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -121,7 +121,7 @@ toIfaceTvBndr :: TyVar -> IfaceTvBndr toIfaceTvBndr = toIfaceTvBndrX emptyVarSet toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr -toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar) +toIfaceTvBndrX fr tyvar = ( mkIfLclName (occNameFS (getOccName tyvar)) , toIfaceTypeX fr (tyVarKind tyvar) ) @@ -133,7 +133,7 @@ toIfaceIdBndr = toIfaceIdBndrX emptyVarSet toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr toIfaceIdBndrX fr covar = ( toIfaceType (idMult covar) - , occNameFS (getOccName covar) + , mkIfLclName (occNameFS (getOccName covar)) , toIfaceTypeX fr (varType covar) ) @@ -218,11 +218,11 @@ toIfaceTypeX fr (TyConApp tc tys) arity = tyConArity tc n_tys = length tys -toIfaceTyVar :: TyVar -> FastString -toIfaceTyVar = occNameFS . getOccName +toIfaceTyVar :: TyVar -> IfLclName +toIfaceTyVar = mkIfLclName . occNameFS . getOccName -toIfaceCoVar :: CoVar -> FastString -toIfaceCoVar = occNameFS . getOccName +toIfaceCoVar :: CoVar -> IfLclName +toIfaceCoVar = mkIfLclName . occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon @@ -264,7 +264,7 @@ toIfaceTyCon_name n = IfaceTyCon n info toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x -toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x +toIfaceTyLit (StrTyLit x) = IfaceStrTyLit (LexicalFastString x) toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x ---------------- @@ -296,7 +296,7 @@ toIfaceCoercionX fr co go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c) go (SubCo co) = IfaceSubCo (go co) - go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs) + go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (mkIfLclName (coaxrName co)) (map go cs) go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs) go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) @@ -433,7 +433,7 @@ toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang toIfaceLetBndr :: Id -> IfaceLetBndr -toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) +toIfaceLetBndr id = IfLetBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (idJoinPointHood id) @@ -444,7 +444,7 @@ toIfaceTopBndr :: Id -> IfaceTopBndrInfo toIfaceTopBndr id = if isExternalName name then IfGblTopBndr name - else IfLclTopBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) + else IfLclTopBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (toIfaceIdDetails (idDetails id)) where name = getName id @@ -555,7 +555,7 @@ toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfac toIfaceExpr (App f a) = toIfaceApp f [a] toIfaceExpr (Case s x ty as) | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty) - | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as) + | otherwise = IfaceCase (toIfaceExpr s) (mkIfLclName (getOccFS x)) (map toIfaceAlt as) toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e) toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co) toIfaceExpr (Tick t e) = IfaceTick (toIfaceTickish t) (toIfaceExpr e) @@ -610,7 +610,7 @@ toIfaceTopBind b = --------------------- toIfaceAlt :: CoreAlt -> IfaceAlt -toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map getOccFS bs) (toIfaceExpr r) +toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map (mkIfLclName . getOccFS) bs) (toIfaceExpr r) --------------------- toIfaceCon :: AltCon -> IfaceConAlt @@ -655,7 +655,7 @@ toIfaceVar v -- Foreign calls have special syntax | isExternalName name = IfaceExt name - | otherwise = IfaceLcl (occNameFS $ nameOccName name) + | otherwise = IfaceLcl (mkIfLclName (occNameFS $ nameOccName name)) where name = idName v ty = idType v ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -283,13 +283,16 @@ instance Ord NonDetFastString where -- `lexicalCompareFS` (i.e. which compares FastStrings on their String -- representation). Hence it is deterministic from one run to the other. newtype LexicalFastString - = LexicalFastString FastString + = LexicalFastString { getLexicalFastString :: FastString } deriving newtype (Eq, Show) deriving stock Data instance Ord LexicalFastString where compare (LexicalFastString fs1) (LexicalFastString fs2) = lexicalCompareFS fs1 fs2 +instance NFData LexicalFastString where + rnf (LexicalFastString f) = rnf f + -- ----------------------------------------------------------------------------- -- Construction ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -25,6 +25,8 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude @@ -54,6 +56,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -158,9 +163,13 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - fsReaderTable <- initFastStringReaderTable - nameReaderTable <- (initReadNameCachedBinary name_cache) + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameCachedBinary name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud -- The order of these deserialisation matters! -- @@ -168,14 +177,21 @@ getTables name_cache bh = do fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) let fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh + bhFs = addReaderToUserData fsReader bh + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) let nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs + bhName = addReaderToUserData nameReader bhFs - pure bhName + ifaceTypeTable <- Binary.forwardGet bh (getTable ifaceTypeReaderTable bhName) + let + ifaceTypeReader = mkReaderFromTable ifaceTypeReaderTable ifaceTypeTable + bhIfaceType = addReaderToUserData ifaceTypeReader bhName + + writeIORef bhRef (getReaderUserData bhIfaceType) + pure bhIfaceType -- | Write an interface file. -- @@ -238,11 +254,13 @@ putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter , mkSomeBinaryWriter @Name nameWriter , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -250,18 +268,24 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) - where - putAllTables _ [] act = do - a <- act - pure ([], a) - putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do - putAllTables bh xs act - pure (r : res, a) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -335,6 +359,24 @@ Here, a visualisation of the table structure we currently have: -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType = do + sym_tab <- initGenericSymbolTable + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ putGenericSymTab sym_tab + ) + initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) initReadNameCachedBinary cache = do ===================================== compiler/GHC/Iface/Decl.hs ===================================== @@ -45,7 +45,6 @@ import GHC.Types.SrcLoc import GHC.Utils.Panic.Plain import GHC.Utils.Misc -import GHC.Data.FastString import GHC.Data.Maybe import GHC.Data.BooleanFormula @@ -147,7 +146,7 @@ tyConToIfaceDecl env tycon | Just fam_flav <- famTyConFlav_maybe tycon = ( tc_env1 , IfaceFamily { ifName = getName tycon, - ifResVar = if_res_var, + ifResVar = mkIfLclName <$> if_res_var, ifFamFlav = to_if_fam_flav fam_flav, ifBinders = if_binders, ifResKind = if_res_kind, @@ -288,7 +287,7 @@ classToIfaceDecl env clas ifClassCtxt = tidyToIfaceContext env1 sc_theta, ifATs = map toIfaceAT clas_ats, ifSigs = map toIfaceClassOp op_stuff, - ifMinDef = toIfaceBooleanFormula $ fmap getOccFS (classMinimalDef clas) + ifMinDef = toIfaceBooleanFormula $ fmap (mkIfLclName . getOccFS) (classMinimalDef clas) } (env1, tc_binders) = tidyTyConBinders env (tyConBinders tycon) @@ -334,7 +333,7 @@ tidyTyConBinder env@(_, subst) tvb@(Bndr tv vis) tidyTyConBinders :: TidyEnv -> [TyConBinder] -> (TidyEnv, [TyConBinder]) tidyTyConBinders = mapAccumL tidyTyConBinder -tidyTyVar :: TidyEnv -> TyVar -> FastString +tidyTyVar :: TidyEnv -> TyVar -> IfLclName tidyTyVar (_, subst) tv = toIfaceTyVar (lookupVarEnv subst tv `orElse` tv) toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula ===================================== compiler/GHC/Iface/Env.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Runtime.Context import GHC.Unit.Module import GHC.Unit.Module.ModIface -import GHC.Data.FastString import GHC.Data.FastString.Env import GHC.Types.Var @@ -190,10 +189,10 @@ setNameModule (Just m) n = ************************************************************************ -} -tcIfaceLclId :: FastString -> IfL Id +tcIfaceLclId :: IfLclName -> IfL Id tcIfaceLclId occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_id_env lcl) occ of + ; case lookupFsEnv (if_id_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM $ vcat @@ -209,10 +208,10 @@ extendIfaceIdEnv ids in env { if_id_env = id_env' } -tcIfaceTyVar :: FastString -> IfL TyVar +tcIfaceTyVar :: IfLclName -> IfL TyVar tcIfaceTyVar occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_tv_env lcl) occ of + ; case lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ) } @@ -220,15 +219,15 @@ tcIfaceTyVar occ lookupIfaceTyVar :: IfaceTvBndr -> IfL (Maybe TyVar) lookupIfaceTyVar (occ, _) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar) lookupIfaceVar (IfaceIdBndr (_, occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_id_env lcl) occ) } + ; return (lookupFsEnv (if_id_env lcl) (ifLclNameFS occ)) } lookupIfaceVar (IfaceTvBndr (occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a extendIfaceTyVarEnv tyvars ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -84,58 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBinWriter bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType - -- remember where the symbol table pointer will go - symtab_p_p <- tellBinWriter bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBinWriter bh - putAt bh symtab_p_p symtab_p - seekBinWriter bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBinWriter bh - putAt bh dict_p_p dict_p - seekBinWriter bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Iface Binary Serialiser Order] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -216,50 +215,32 @@ readHieFileHeader file bh0 = do readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBinReader bin_handle - seekBinReader bin_handle dict_p - dict <- getDictionary bin_handle - seekBinReader bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBinReader bh1 - seekBinReader bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBinReader bh1 data_p' - return symtab - -putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -162,15 +162,15 @@ getEvidenceTree refmap var = go emptyNameSet var hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where - go (HTyVarTy n) = IfaceTyVar $ occNameFS $ getOccName n + go (HTyVarTy n) = IfaceTyVar $ (mkIfLclName (occNameFS $ getOccName n)) go (HAppTy a b) = IfaceAppTy a (hieToIfaceArgs b) go (HLitTy l) = IfaceLitTy l - go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k) + go (HForAllTy ((n,k),af) t) = let b = (mkIfLclName (occNameFS $ getOccName n), k) in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t go (HFunTy w a b) = IfaceFunTy visArgTypeLike w a b go (HQualTy pred b) = IfaceFunTy invisArgTypeLike many_ty pred b go (HCastTy a) = a - go HCoercionTy = IfaceTyVar "" + go HCoercionTy = IfaceTyVar (mkIfLclName "") go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs) -- This isn't fully faithful - we can't produce the 'Inferred' case ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1216,8 +1216,8 @@ addFingerprints hsc_env iface0 getOcc (IfLclTopBndr fs _ _ details) = case details of IfRecSelId { ifRecSelFirstCon = first_con } - -> mkRecFieldOccFS (getOccFS first_con) fs - _ -> mkVarOccFS fs + -> mkRecFieldOccFS (getOccFS first_con) (ifLclNameFS fs) + _ -> mkVarOccFS (ifLclNameFS fs) binding_key (IfaceNonRec b _) = IfaceNonRec (getOcc b) () binding_key (IfaceRec bs) = IfaceRec (map (\(b, _) -> (getOcc b, ())) bs) ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -632,6 +632,7 @@ data IfaceExpr | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E + data IfaceTickish = IfaceHpcTick Module Int -- from HpcTick x | IfaceSCC CostCentre Bool Bool -- from ProfNote @@ -1026,7 +1027,7 @@ pprIfaceDecl ss (IfaceClass { ifName = clas pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions text "{-# MINIMAL" <+> pprBooleanFormula - (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+> + (\_ def -> cparen (isLexSym def) (ppr def)) 0 (fmap ifLclNameFS minDef) <+> text "#-}" -- See Note [Suppressing binder signatures] in GHC.Iface.Type ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -10,7 +10,8 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} module GHC.Iface.Type ( - IfExtName, IfLclName, + IfExtName, + IfLclName(..), mkIfLclName, ifLclNameFS, IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), @@ -32,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, -- Equality testing isIfaceLiftedTypeKind, @@ -90,9 +93,11 @@ import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) import Control.DeepSeq +import Data.Proxy import Control.Monad ((<$!>)) +import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) +import Data.Maybe (isJust) {- ************************************************************************ @@ -102,7 +107,16 @@ import Data.Maybe( isJust ) ************************************************************************ -} -type IfLclName = FastString -- A local name in iface syntax +-- | A local name in iface syntax +newtype IfLclName = IfLclName + { getIfLclName :: LexicalFastString + } deriving (Eq, Ord, Show) + +ifLclNameFS :: IfLclName -> FastString +ifLclNameFS = getLexicalFastString . getIfLclName + +mkIfLclName :: FastString -> IfLclName +mkIfLclName = IfLclName . LexicalFastString type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax -- (However Internal or System Names never should) @@ -110,6 +124,8 @@ type IfExtName = Name -- An External or WiredIn Name can appear in Iface synta data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr + deriving (Eq, Ord) + type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) type IfaceTvBndr = (IfLclName, IfaceKind) @@ -178,6 +194,7 @@ data IfaceType -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression -- in interface file size (in GHC's boot libraries). -- See !3987. + deriving (Eq, Ord) type IfaceMult = IfaceType @@ -186,9 +203,9 @@ type IfaceContext = [IfacePredType] data IfaceTyLit = IfaceNumTyLit Integer - | IfaceStrTyLit FastString + | IfaceStrTyLit LexicalFastString | IfaceCharTyLit Char - deriving (Eq) + deriving (Eq, Ord) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag @@ -230,6 +247,7 @@ data IfaceAppArgs -- arguments in @{...}. IfaceAppArgs -- The rest of the arguments + deriving (Eq, Ord) instance Semi.Semigroup IfaceAppArgs where IA_Nil <> xs = xs @@ -256,7 +274,7 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName -- See Note [Sharing IfaceTyConInfo] for why -- sharing is so important for 'IfaceTyConInfo'. } - deriving (Eq) + deriving (Eq, Ord) -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -276,7 +294,7 @@ data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon -- that is actually being applied to two types -- of the same kind. This affects pretty-printing -- only: see Note [Equality predicates in IfaceType] - deriving (Eq) + deriving (Eq, Ord) instance Outputable IfaceTyConSort where ppr IfaceNormalTyCon = text "normal" @@ -370,7 +388,7 @@ data IfaceTyConInfo -- Used only to guide pretty-printing -- should be printed as 'D to distinguish it from -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } - deriving (Eq) + deriving (Eq, Ord) -- | This smart constructor allows sharing of the two most common -- cases. See Note [Sharing IfaceTyConInfo] @@ -420,7 +438,7 @@ This one change leads to an 15% reduction in residency for GHC when embedding data IfaceMCoercion = IfaceMRefl - | IfaceMCo IfaceCoercion + | IfaceMCo IfaceCoercion deriving (Eq, Ord) data IfaceCoercion = IfaceReflCo IfaceType @@ -445,11 +463,13 @@ data IfaceCoercion | IfaceSubCo IfaceCoercion | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] + deriving (Eq, Ord) data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String + deriving (Eq, Ord) {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -621,11 +641,11 @@ type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType] mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst -- See Note [Substitution on IfaceType] -mkIfaceTySubst eq_spec = mkFsEnv eq_spec +mkIfaceTySubst eq_spec = mkFsEnv (map (first ifLclNameFS) eq_spec) inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool -- See Note [Substitution on IfaceType] -inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs) +inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst (ifLclNameFS fs)) substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType -- See Note [Substitution on IfaceType] @@ -681,7 +701,7 @@ substIfaceAppArgs env args substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType substIfaceTyVar env tv - | Just ty <- lookupFsEnv env tv = ty + | Just ty <- lookupFsEnv env (ifLclNameFS tv) = ty | otherwise = IfaceTyVar tv @@ -1190,7 +1210,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind - = let subs' = extendFsEnv subs var substituted_ty + = let subs' = extendFsEnv subs (ifLclNameFS var) substituted_ty -- Record that we should replace it with LiftedRep/Lifted/Many, -- and recurse, discarding the forall in go subs' True ty @@ -1198,7 +1218,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty go subs rank1 (IfaceForAllTy bndr ty) = IfaceForAllTy (go_ifacebndr subs bndr) (go subs rank1 ty) - go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of + go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs (ifLclNameFS tv) of Just s -> s Nothing -> ty @@ -1626,7 +1646,7 @@ pprTyTcApp ctxt_prec tc tys = , IA_Arg (IfaceLitTy (IfaceStrTyLit n)) Required (IA_Arg ty Required IA_Nil) <- tys -> maybeParen ctxt_prec funPrec - $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty + $ char '?' <> ftext (getLexicalFastString n) <> text "::" <> ppr_ty topPrec ty | IfaceTupleTyCon arity sort <- ifaceTyConSort info , not debug @@ -2014,6 +2034,9 @@ pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) ------------------- +instance Outputable IfLclName where + ppr = ppr . ifLclNameFS + instance Outputable IfaceTyCon where ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc) @@ -2171,38 +2194,47 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) - - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } - - get bh = do + put_ bh tyCon = case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh tyCon + + get bh = case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2230,6 +2262,13 @@ instance Binary IfaceType where _ -> do n <- get bh return (IfaceLitTy n) +instance Binary IfLclName where + put_ bh = put_ bh . ifLclNameFS + + get bh = do + fs <- get bh + pure $ IfLclName $ LexicalFastString fs + instance Binary IfaceMCoercion where put_ bh IfaceMRefl = putByte bh 1 @@ -2475,6 +2514,9 @@ instance NFData IfaceTyConSort where IfaceSumTyCon arity -> rnf arity IfaceEqualityTyCon -> () +instance NFData IfLclName where + rnf (IfLclName lfs) = rnf lfs + instance NFData IfaceTyConInfo where rnf (IfaceTyConInfo f s) = f `seq` rnf s ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -733,7 +733,7 @@ tc_iface_decl parent _ (IfaceFamily {ifName = tc_name, { res_kind' <- tcIfaceType res_kind -- Note [Synonym kind loop] ; rhs <- forkM (mk_doc tc_name) $ tc_fam_flav tc_name fam_flav - ; res_name <- traverse (newIfaceName . mkTyVarOccFS) res + ; res_name <- traverse (newIfaceName . mkTyVarOccFS . ifLclNameFS) res ; let tycon = mkFamilyTyCon tc_name binders' res_kind' res_name rhs parent inj ; return (ATyCon tycon) } where @@ -782,7 +782,7 @@ tc_iface_decl _parent ignore_prags ; fds <- mapM tc_fd rdr_fds ; traceIf (text "tc-iface-class3" <+> ppr tc_name) ; let mindef_occ = fromIfaceBooleanFormula if_mindef - ; mindef <- traverse (lookupIfaceTop . mkVarOccFS) mindef_occ + ; mindef <- traverse (lookupIfaceTop . mkVarOccFS . ifLclNameFS) mindef_occ ; cls <- fixM $ \ cls -> do { ats <- mapM (tc_at cls) rdr_ats ; traceIf (text "tc-iface-class4" <+> ppr tc_name) @@ -936,8 +936,8 @@ mk_top_id (IfLclTopBndr raw_name iface_type info details) = do ; let occ = case details' of RecSelId { sel_tycon = parent } -> let con_fs = getOccFS $ recSelFirstConName parent - in mkRecFieldOccFS con_fs raw_name - _ -> mkVarOccFS raw_name + in mkRecFieldOccFS con_fs (ifLclNameFS raw_name) + _ -> mkVarOccFS (ifLclNameFS raw_name) ; name <- newIfaceName occ } info' <- tcIdInfo False TopLevel name ty info let new_id = mkGlobalId details' name ty info' @@ -1441,7 +1441,7 @@ tcIfaceCtxt sts = mapM tcIfaceType sts ----------------------------------------- tcIfaceTyLit :: IfaceTyLit -> IfL TyLit tcIfaceTyLit (IfaceNumTyLit n) = return (NumTyLit n) -tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) +tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit (getLexicalFastString n)) tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n) {- @@ -1485,7 +1485,7 @@ tcIfaceCo = go go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) - go_var :: FastString -> IfL CoVar + go_var :: IfLclName -> IfL CoVar go_var = tcIfaceLclId tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance @@ -1561,7 +1561,7 @@ tcIfaceExpr (IfaceECase scrut ty) tcIfaceExpr (IfaceCase scrut case_bndr alts) = do scrut' <- tcIfaceExpr scrut - case_bndr_name <- newIfaceName (mkVarOccFS case_bndr) + case_bndr_name <- newIfaceName (mkVarOccFS (ifLclNameFS case_bndr)) let scrut_ty = exprType scrut' case_mult = ManyTy @@ -1580,7 +1580,7 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do return (Case scrut' case_bndr' (coreAltsType alts') alts') tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} NotTopLevel name ty' info @@ -1598,7 +1598,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; return (Let (Rec pairs') body') } } where tc_rec_bndr (IfLetBndr fs ty _ ji) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; return (mkLocalId name ManyTy ty' `asJoinId_maybe` ji) } tc_pair (IfLetBndr _ _ info _, rhs) id @@ -1655,12 +1655,12 @@ tcIfaceAlt scrut mult (tycon, inst_tys) (IfaceAlt (IfaceDataAlt data_occ) arg_st (failIfM (ppr scrut $$ ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon))) ; tcIfaceDataAlt mult con inst_tys arg_strs rhs } -tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [FastString] -> IfaceExpr +tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [IfLclName] -> IfaceExpr -> IfL CoreAlt tcIfaceDataAlt mult con inst_tys arg_strs rhs = do { uniqs <- getUniquesM ; let (ex_tvs, arg_ids) - = dataConRepFSInstPat arg_strs uniqs mult con inst_tys + = dataConRepFSInstPat (map ifLclNameFS arg_strs) uniqs mult con inst_tys ; rhs' <- extendIfaceEnvs ex_tvs $ extendIfaceIdEnv arg_ids $ @@ -2031,7 +2031,7 @@ tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule -- - axioms for type-level literals (Nat and Symbol), -- enumerated in typeNatCoAxiomRules tcIfaceCoAxiomRule n - | Just ax <- lookupUFM typeNatCoAxiomRules n + | Just ax <- lookupUFM typeNatCoAxiomRules (ifLclNameFS n) = return ax | otherwise = pprPanic "tcIfaceCoAxiomRule" (ppr n) @@ -2075,7 +2075,7 @@ tcIfaceImplicit n = do bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a bindIfaceId (w, fs, ty) thing_inside - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; w' <- tcIfaceType w ; let id = mkLocalIdOrCoVar name w' ty' @@ -2118,7 +2118,7 @@ bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside - = do { name <- newIfaceName (mkTyVarOccFS occ) + = do { name <- newIfaceName (mkTyVarOccFS (ifLclNameFS occ)) ; tyvar <- mk_iface_tyvar name kind ; extendIfaceTyVarEnv [tyvar] (thing_inside tyvar) } ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -148,7 +148,7 @@ import qualified Data.Semigroup as Semi ********************************************************************* -} data LeftOrRight = CLeft | CRight - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) pickLR :: LeftOrRight -> (a,a) -> a pickLR CLeft (l,_) = l ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -720,7 +720,7 @@ Currently there are nine different uses of 'VarBndr': data VarBndr var argf = Bndr var argf -- See Note [The VarBndr type and its uses] - deriving( Data ) + deriving( Data, Eq, Ord) -- | Variable Binder -- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -127,7 +136,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (unfoldr) +import Data.List (sortOn, unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -230,22 +239,26 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a @@ -1102,24 +1115,35 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = inner_bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f p bh' seekBinReader bh p -- skip over the object for now return a @@ -1173,6 +1197,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) @@ -1313,6 +1343,80 @@ data WriterTable = WriterTable { putTable :: WriteBinHandle -> IO Int } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol + } + +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop bound = do + d <- readIORef symtab_map + table_count <- readFastMutInt symtab_next + let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + case vs of + [] -> return table_count + todo -> do + mapM_ (\n -> serialiser bh n) (map snd todo) + loop table_count + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop 0) + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -78,6 +78,7 @@ import Data.Eq import Data.Bool import Data.Char import Prelude (Integer, length) +import Data.Ord (Ord) {- ************************************************************************ @@ -91,7 +92,7 @@ import Prelude (Integer, length) data PromotionFlag = NotPromoted | IsPromoted - deriving ( Eq, Data ) + deriving ( Eq, Data, Ord ) isPromoted :: PromotionFlag -> Bool isPromoted IsPromoted = True ===================================== compiler/Language/Haskell/Syntax/Type.hs-boot ===================================== @@ -2,6 +2,7 @@ module Language.Haskell.Syntax.Type where import Data.Bool import Data.Eq +import Data.Ord {- ************************************************************************ @@ -17,5 +18,6 @@ data PromotionFlag | IsPromoted instance Eq PromotionFlag +instance Ord PromotionFlag isPromoted :: PromotionFlag -> Bool ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 +Subproject commit 223f7c8667db506dfbb209f9c996a946de8d4a51 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87897928c0e0e7f44ddfac6633ef1301a5d2778f...17010aed403c3388411e15efb585d81bb3c30e3c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87897928c0e0e7f44ddfac6633ef1301a5d2778f...17010aed403c3388411e15efb585d81bb3c30e3c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 10:14:10 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 08 Apr 2024 06:14:10 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 4 commits: linker: Avoid linear search when looking up Haskell symbols via dlsym Message-ID: <6613c3721fdbc_1da3db7527cc83240@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 732155fe by Alexis King at 2024-04-08T11:13:59+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 6aa5584b by Rodrigo Mesquita at 2024-04-08T11:13:59+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - a4b7320f by Rodrigo Mesquita at 2024-04-08T11:13:59+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - de52433e by Ben Gamari at 2024-04-08T11:13:59+01:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - testsuite/tests/rts/linker/T2615.hs - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/785937b46351fa021eac5b7bb683b2fa38739302...de52433e3d2259cf227252cd0ccedce0ad09ec98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/785937b46351fa021eac5b7bb683b2fa38739302...de52433e3d2259cf227252cd0ccedce0ad09ec98 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 10:18:37 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 08 Apr 2024 06:18:37 -0400 Subject: [Git][ghc/ghc][wip/fendor/fix-thunks-name-and-ui] 61 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <6613c47d44ca5_1da3db89164c89062@gitlab.mail> Matthew Pickering pushed to branch wip/fendor/fix-thunks-name-and-ui at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - dc0d8903 by Matthew Pickering at 2024-04-08T11:18:21+01:00 Force in_multi to avoid retaining entire hsc_env - - - - - 8bb2acf9 by Fendor at 2024-04-08T11:18:21+01:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 19 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2de39aa82420a30ff04814adb65d28ddb787455...8bb2acf92414a37b69467788539cceb4e5977328 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2de39aa82420a30ff04814adb65d28ddb787455...8bb2acf92414a37b69467788539cceb4e5977328 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 10:21:31 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 08 Apr 2024 06:21:31 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 2 commits: Add deduplication table for `IfaceType` Message-ID: <6613c52bbe6ac_1da3db9ce6b898414@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 8dada682 by Matthew Pickering at 2024-04-08T12:21:09+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - fba95eb0 by Fendor at 2024-04-08T12:21:09+02:00 Add IfaceType deduplication table to .hie serialisation Refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 20 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - utils/haddock Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -952,13 +952,13 @@ data CoSel -- See Note [SelCo] | SelForAll -- Decomposes (forall a. co) - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) data FunSel -- See Note [SelCo] = SelMult -- Multiplicity | SelArg -- Argument of function | SelRes -- Result of function - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -121,7 +121,7 @@ toIfaceTvBndr :: TyVar -> IfaceTvBndr toIfaceTvBndr = toIfaceTvBndrX emptyVarSet toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr -toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar) +toIfaceTvBndrX fr tyvar = ( mkIfLclName (occNameFS (getOccName tyvar)) , toIfaceTypeX fr (tyVarKind tyvar) ) @@ -133,7 +133,7 @@ toIfaceIdBndr = toIfaceIdBndrX emptyVarSet toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr toIfaceIdBndrX fr covar = ( toIfaceType (idMult covar) - , occNameFS (getOccName covar) + , mkIfLclName (occNameFS (getOccName covar)) , toIfaceTypeX fr (varType covar) ) @@ -218,11 +218,11 @@ toIfaceTypeX fr (TyConApp tc tys) arity = tyConArity tc n_tys = length tys -toIfaceTyVar :: TyVar -> FastString -toIfaceTyVar = occNameFS . getOccName +toIfaceTyVar :: TyVar -> IfLclName +toIfaceTyVar = mkIfLclName . occNameFS . getOccName -toIfaceCoVar :: CoVar -> FastString -toIfaceCoVar = occNameFS . getOccName +toIfaceCoVar :: CoVar -> IfLclName +toIfaceCoVar = mkIfLclName . occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon @@ -264,7 +264,7 @@ toIfaceTyCon_name n = IfaceTyCon n info toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x -toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x +toIfaceTyLit (StrTyLit x) = IfaceStrTyLit (LexicalFastString x) toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x ---------------- @@ -296,7 +296,7 @@ toIfaceCoercionX fr co go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c) go (SubCo co) = IfaceSubCo (go co) - go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs) + go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (mkIfLclName (coaxrName co)) (map go cs) go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs) go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) @@ -433,7 +433,7 @@ toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang toIfaceLetBndr :: Id -> IfaceLetBndr -toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) +toIfaceLetBndr id = IfLetBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (idJoinPointHood id) @@ -444,7 +444,7 @@ toIfaceTopBndr :: Id -> IfaceTopBndrInfo toIfaceTopBndr id = if isExternalName name then IfGblTopBndr name - else IfLclTopBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) + else IfLclTopBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (toIfaceIdDetails (idDetails id)) where name = getName id @@ -555,7 +555,7 @@ toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfac toIfaceExpr (App f a) = toIfaceApp f [a] toIfaceExpr (Case s x ty as) | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty) - | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as) + | otherwise = IfaceCase (toIfaceExpr s) (mkIfLclName (getOccFS x)) (map toIfaceAlt as) toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e) toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co) toIfaceExpr (Tick t e) = IfaceTick (toIfaceTickish t) (toIfaceExpr e) @@ -610,7 +610,7 @@ toIfaceTopBind b = --------------------- toIfaceAlt :: CoreAlt -> IfaceAlt -toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map getOccFS bs) (toIfaceExpr r) +toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map (mkIfLclName . getOccFS) bs) (toIfaceExpr r) --------------------- toIfaceCon :: AltCon -> IfaceConAlt @@ -655,7 +655,7 @@ toIfaceVar v -- Foreign calls have special syntax | isExternalName name = IfaceExt name - | otherwise = IfaceLcl (occNameFS $ nameOccName name) + | otherwise = IfaceLcl (mkIfLclName (occNameFS $ nameOccName name)) where name = idName v ty = idType v ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -283,13 +283,16 @@ instance Ord NonDetFastString where -- `lexicalCompareFS` (i.e. which compares FastStrings on their String -- representation). Hence it is deterministic from one run to the other. newtype LexicalFastString - = LexicalFastString FastString + = LexicalFastString { getLexicalFastString :: FastString } deriving newtype (Eq, Show) deriving stock Data instance Ord LexicalFastString where compare (LexicalFastString fs1) (LexicalFastString fs2) = lexicalCompareFS fs1 fs2 +instance NFData LexicalFastString where + rnf (LexicalFastString f) = rnf f + -- ----------------------------------------------------------------------------- -- Construction ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -25,6 +25,8 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude @@ -54,6 +56,9 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -158,9 +163,13 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - fsReaderTable <- initFastStringReaderTable - nameReaderTable <- (initReadNameCachedBinary name_cache) + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameCachedBinary name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud -- The order of these deserialisation matters! -- @@ -168,14 +177,21 @@ getTables name_cache bh = do fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) let fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh + bhFs = addReaderToUserData fsReader bh + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) let nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs + bhName = addReaderToUserData nameReader bhFs - pure bhName + ifaceTypeTable <- Binary.forwardGet bh (getTable ifaceTypeReaderTable bhName) + let + ifaceTypeReader = mkReaderFromTable ifaceTypeReaderTable ifaceTypeTable + bhIfaceType = addReaderToUserData ifaceTypeReader bhName + + writeIORef bhRef (getReaderUserData bhIfaceType) + pure bhIfaceType -- | Write an interface file. -- @@ -238,11 +254,13 @@ putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initWriteNameTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter , mkSomeBinaryWriter @Name nameWriter , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -250,18 +268,24 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Iface Binary Serialiser Order] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) - where - putAllTables _ [] act = do - a <- act - pure ([], a) - putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do - putAllTables bh xs act - pure (r : res, a) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -335,6 +359,24 @@ Here, a visualisation of the table structure we currently have: -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType = do + sym_tab <- initGenericSymbolTable + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ putGenericSymTab sym_tab + ) + initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) initReadNameCachedBinary cache = do ===================================== compiler/GHC/Iface/Decl.hs ===================================== @@ -45,7 +45,6 @@ import GHC.Types.SrcLoc import GHC.Utils.Panic.Plain import GHC.Utils.Misc -import GHC.Data.FastString import GHC.Data.Maybe import GHC.Data.BooleanFormula @@ -147,7 +146,7 @@ tyConToIfaceDecl env tycon | Just fam_flav <- famTyConFlav_maybe tycon = ( tc_env1 , IfaceFamily { ifName = getName tycon, - ifResVar = if_res_var, + ifResVar = mkIfLclName <$> if_res_var, ifFamFlav = to_if_fam_flav fam_flav, ifBinders = if_binders, ifResKind = if_res_kind, @@ -288,7 +287,7 @@ classToIfaceDecl env clas ifClassCtxt = tidyToIfaceContext env1 sc_theta, ifATs = map toIfaceAT clas_ats, ifSigs = map toIfaceClassOp op_stuff, - ifMinDef = toIfaceBooleanFormula $ fmap getOccFS (classMinimalDef clas) + ifMinDef = toIfaceBooleanFormula $ fmap (mkIfLclName . getOccFS) (classMinimalDef clas) } (env1, tc_binders) = tidyTyConBinders env (tyConBinders tycon) @@ -334,7 +333,7 @@ tidyTyConBinder env@(_, subst) tvb@(Bndr tv vis) tidyTyConBinders :: TidyEnv -> [TyConBinder] -> (TidyEnv, [TyConBinder]) tidyTyConBinders = mapAccumL tidyTyConBinder -tidyTyVar :: TidyEnv -> TyVar -> FastString +tidyTyVar :: TidyEnv -> TyVar -> IfLclName tidyTyVar (_, subst) tv = toIfaceTyVar (lookupVarEnv subst tv `orElse` tv) toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula ===================================== compiler/GHC/Iface/Env.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Runtime.Context import GHC.Unit.Module import GHC.Unit.Module.ModIface -import GHC.Data.FastString import GHC.Data.FastString.Env import GHC.Types.Var @@ -190,10 +189,10 @@ setNameModule (Just m) n = ************************************************************************ -} -tcIfaceLclId :: FastString -> IfL Id +tcIfaceLclId :: IfLclName -> IfL Id tcIfaceLclId occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_id_env lcl) occ of + ; case lookupFsEnv (if_id_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM $ vcat @@ -209,10 +208,10 @@ extendIfaceIdEnv ids in env { if_id_env = id_env' } -tcIfaceTyVar :: FastString -> IfL TyVar +tcIfaceTyVar :: IfLclName -> IfL TyVar tcIfaceTyVar occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_tv_env lcl) occ of + ; case lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ) } @@ -220,15 +219,15 @@ tcIfaceTyVar occ lookupIfaceTyVar :: IfaceTvBndr -> IfL (Maybe TyVar) lookupIfaceTyVar (occ, _) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar) lookupIfaceVar (IfaceIdBndr (_, occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_id_env lcl) occ) } + ; return (lookupFsEnv (if_id_env lcl) (ifLclNameFS occ)) } lookupIfaceVar (IfaceTvBndr (occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a extendIfaceTyVarEnv tyvars ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -84,58 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBinWriter bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType - -- remember where the symbol table pointer will go - symtab_p_p <- tellBinWriter bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBinWriter bh - putAt bh symtab_p_p symtab_p - seekBinWriter bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBinWriter bh - putAt bh dict_p_p dict_p - seekBinWriter bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Iface Binary Serialiser Order] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -216,50 +215,32 @@ readHieFileHeader file bh0 = do readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBinReader bin_handle - seekBinReader bin_handle dict_p - dict <- getDictionary bin_handle - seekBinReader bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBinReader bh1 - seekBinReader bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBinReader bh1 data_p' - return symtab - -putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -162,15 +162,15 @@ getEvidenceTree refmap var = go emptyNameSet var hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where - go (HTyVarTy n) = IfaceTyVar $ occNameFS $ getOccName n + go (HTyVarTy n) = IfaceTyVar $ (mkIfLclName (occNameFS $ getOccName n)) go (HAppTy a b) = IfaceAppTy a (hieToIfaceArgs b) go (HLitTy l) = IfaceLitTy l - go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k) + go (HForAllTy ((n,k),af) t) = let b = (mkIfLclName (occNameFS $ getOccName n), k) in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t go (HFunTy w a b) = IfaceFunTy visArgTypeLike w a b go (HQualTy pred b) = IfaceFunTy invisArgTypeLike many_ty pred b go (HCastTy a) = a - go HCoercionTy = IfaceTyVar "" + go HCoercionTy = IfaceTyVar (mkIfLclName "") go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs) -- This isn't fully faithful - we can't produce the 'Inferred' case ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1216,8 +1216,8 @@ addFingerprints hsc_env iface0 getOcc (IfLclTopBndr fs _ _ details) = case details of IfRecSelId { ifRecSelFirstCon = first_con } - -> mkRecFieldOccFS (getOccFS first_con) fs - _ -> mkVarOccFS fs + -> mkRecFieldOccFS (getOccFS first_con) (ifLclNameFS fs) + _ -> mkVarOccFS (ifLclNameFS fs) binding_key (IfaceNonRec b _) = IfaceNonRec (getOcc b) () binding_key (IfaceRec bs) = IfaceRec (map (\(b, _) -> (getOcc b, ())) bs) ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -632,6 +632,7 @@ data IfaceExpr | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E + data IfaceTickish = IfaceHpcTick Module Int -- from HpcTick x | IfaceSCC CostCentre Bool Bool -- from ProfNote @@ -1026,7 +1027,7 @@ pprIfaceDecl ss (IfaceClass { ifName = clas pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions text "{-# MINIMAL" <+> pprBooleanFormula - (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+> + (\_ def -> cparen (isLexSym def) (ppr def)) 0 (fmap ifLclNameFS minDef) <+> text "#-}" -- See Note [Suppressing binder signatures] in GHC.Iface.Type ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -10,7 +10,8 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} module GHC.Iface.Type ( - IfExtName, IfLclName, + IfExtName, + IfLclName(..), mkIfLclName, ifLclNameFS, IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), @@ -32,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, -- Equality testing isIfaceLiftedTypeKind, @@ -90,9 +93,11 @@ import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) import Control.DeepSeq +import Data.Proxy import Control.Monad ((<$!>)) +import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) +import Data.Maybe (isJust) {- ************************************************************************ @@ -102,7 +107,16 @@ import Data.Maybe( isJust ) ************************************************************************ -} -type IfLclName = FastString -- A local name in iface syntax +-- | A local name in iface syntax +newtype IfLclName = IfLclName + { getIfLclName :: LexicalFastString + } deriving (Eq, Ord, Show) + +ifLclNameFS :: IfLclName -> FastString +ifLclNameFS = getLexicalFastString . getIfLclName + +mkIfLclName :: FastString -> IfLclName +mkIfLclName = IfLclName . LexicalFastString type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax -- (However Internal or System Names never should) @@ -110,6 +124,8 @@ type IfExtName = Name -- An External or WiredIn Name can appear in Iface synta data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr + deriving (Eq, Ord) + type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) type IfaceTvBndr = (IfLclName, IfaceKind) @@ -178,6 +194,7 @@ data IfaceType -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression -- in interface file size (in GHC's boot libraries). -- See !3987. + deriving (Eq, Ord) type IfaceMult = IfaceType @@ -186,9 +203,9 @@ type IfaceContext = [IfacePredType] data IfaceTyLit = IfaceNumTyLit Integer - | IfaceStrTyLit FastString + | IfaceStrTyLit LexicalFastString | IfaceCharTyLit Char - deriving (Eq) + deriving (Eq, Ord) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag @@ -230,6 +247,7 @@ data IfaceAppArgs -- arguments in @{...}. IfaceAppArgs -- The rest of the arguments + deriving (Eq, Ord) instance Semi.Semigroup IfaceAppArgs where IA_Nil <> xs = xs @@ -256,7 +274,7 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName -- See Note [Sharing IfaceTyConInfo] for why -- sharing is so important for 'IfaceTyConInfo'. } - deriving (Eq) + deriving (Eq, Ord) -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -276,7 +294,7 @@ data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon -- that is actually being applied to two types -- of the same kind. This affects pretty-printing -- only: see Note [Equality predicates in IfaceType] - deriving (Eq) + deriving (Eq, Ord) instance Outputable IfaceTyConSort where ppr IfaceNormalTyCon = text "normal" @@ -370,7 +388,7 @@ data IfaceTyConInfo -- Used only to guide pretty-printing -- should be printed as 'D to distinguish it from -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } - deriving (Eq) + deriving (Eq, Ord) -- | This smart constructor allows sharing of the two most common -- cases. See Note [Sharing IfaceTyConInfo] @@ -420,7 +438,7 @@ This one change leads to an 15% reduction in residency for GHC when embedding data IfaceMCoercion = IfaceMRefl - | IfaceMCo IfaceCoercion + | IfaceMCo IfaceCoercion deriving (Eq, Ord) data IfaceCoercion = IfaceReflCo IfaceType @@ -445,11 +463,13 @@ data IfaceCoercion | IfaceSubCo IfaceCoercion | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] + deriving (Eq, Ord) data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String + deriving (Eq, Ord) {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -621,11 +641,11 @@ type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType] mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst -- See Note [Substitution on IfaceType] -mkIfaceTySubst eq_spec = mkFsEnv eq_spec +mkIfaceTySubst eq_spec = mkFsEnv (map (first ifLclNameFS) eq_spec) inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool -- See Note [Substitution on IfaceType] -inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs) +inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst (ifLclNameFS fs)) substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType -- See Note [Substitution on IfaceType] @@ -681,7 +701,7 @@ substIfaceAppArgs env args substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType substIfaceTyVar env tv - | Just ty <- lookupFsEnv env tv = ty + | Just ty <- lookupFsEnv env (ifLclNameFS tv) = ty | otherwise = IfaceTyVar tv @@ -1190,7 +1210,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind - = let subs' = extendFsEnv subs var substituted_ty + = let subs' = extendFsEnv subs (ifLclNameFS var) substituted_ty -- Record that we should replace it with LiftedRep/Lifted/Many, -- and recurse, discarding the forall in go subs' True ty @@ -1198,7 +1218,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty go subs rank1 (IfaceForAllTy bndr ty) = IfaceForAllTy (go_ifacebndr subs bndr) (go subs rank1 ty) - go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of + go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs (ifLclNameFS tv) of Just s -> s Nothing -> ty @@ -1626,7 +1646,7 @@ pprTyTcApp ctxt_prec tc tys = , IA_Arg (IfaceLitTy (IfaceStrTyLit n)) Required (IA_Arg ty Required IA_Nil) <- tys -> maybeParen ctxt_prec funPrec - $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty + $ char '?' <> ftext (getLexicalFastString n) <> text "::" <> ppr_ty topPrec ty | IfaceTupleTyCon arity sort <- ifaceTyConSort info , not debug @@ -2014,6 +2034,9 @@ pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) ------------------- +instance Outputable IfLclName where + ppr = ppr . ifLclNameFS + instance Outputable IfaceTyCon where ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc) @@ -2171,38 +2194,47 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) - - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } - - get bh = do + put_ bh tyCon = case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh tyCon + + get bh = case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2230,6 +2262,13 @@ instance Binary IfaceType where _ -> do n <- get bh return (IfaceLitTy n) +instance Binary IfLclName where + put_ bh = put_ bh . ifLclNameFS + + get bh = do + fs <- get bh + pure $ IfLclName $ LexicalFastString fs + instance Binary IfaceMCoercion where put_ bh IfaceMRefl = putByte bh 1 @@ -2475,6 +2514,9 @@ instance NFData IfaceTyConSort where IfaceSumTyCon arity -> rnf arity IfaceEqualityTyCon -> () +instance NFData IfLclName where + rnf (IfLclName lfs) = rnf lfs + instance NFData IfaceTyConInfo where rnf (IfaceTyConInfo f s) = f `seq` rnf s ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -733,7 +733,7 @@ tc_iface_decl parent _ (IfaceFamily {ifName = tc_name, { res_kind' <- tcIfaceType res_kind -- Note [Synonym kind loop] ; rhs <- forkM (mk_doc tc_name) $ tc_fam_flav tc_name fam_flav - ; res_name <- traverse (newIfaceName . mkTyVarOccFS) res + ; res_name <- traverse (newIfaceName . mkTyVarOccFS . ifLclNameFS) res ; let tycon = mkFamilyTyCon tc_name binders' res_kind' res_name rhs parent inj ; return (ATyCon tycon) } where @@ -782,7 +782,7 @@ tc_iface_decl _parent ignore_prags ; fds <- mapM tc_fd rdr_fds ; traceIf (text "tc-iface-class3" <+> ppr tc_name) ; let mindef_occ = fromIfaceBooleanFormula if_mindef - ; mindef <- traverse (lookupIfaceTop . mkVarOccFS) mindef_occ + ; mindef <- traverse (lookupIfaceTop . mkVarOccFS . ifLclNameFS) mindef_occ ; cls <- fixM $ \ cls -> do { ats <- mapM (tc_at cls) rdr_ats ; traceIf (text "tc-iface-class4" <+> ppr tc_name) @@ -936,8 +936,8 @@ mk_top_id (IfLclTopBndr raw_name iface_type info details) = do ; let occ = case details' of RecSelId { sel_tycon = parent } -> let con_fs = getOccFS $ recSelFirstConName parent - in mkRecFieldOccFS con_fs raw_name - _ -> mkVarOccFS raw_name + in mkRecFieldOccFS con_fs (ifLclNameFS raw_name) + _ -> mkVarOccFS (ifLclNameFS raw_name) ; name <- newIfaceName occ } info' <- tcIdInfo False TopLevel name ty info let new_id = mkGlobalId details' name ty info' @@ -1441,7 +1441,7 @@ tcIfaceCtxt sts = mapM tcIfaceType sts ----------------------------------------- tcIfaceTyLit :: IfaceTyLit -> IfL TyLit tcIfaceTyLit (IfaceNumTyLit n) = return (NumTyLit n) -tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) +tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit (getLexicalFastString n)) tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n) {- @@ -1485,7 +1485,7 @@ tcIfaceCo = go go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) - go_var :: FastString -> IfL CoVar + go_var :: IfLclName -> IfL CoVar go_var = tcIfaceLclId tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance @@ -1561,7 +1561,7 @@ tcIfaceExpr (IfaceECase scrut ty) tcIfaceExpr (IfaceCase scrut case_bndr alts) = do scrut' <- tcIfaceExpr scrut - case_bndr_name <- newIfaceName (mkVarOccFS case_bndr) + case_bndr_name <- newIfaceName (mkVarOccFS (ifLclNameFS case_bndr)) let scrut_ty = exprType scrut' case_mult = ManyTy @@ -1580,7 +1580,7 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do return (Case scrut' case_bndr' (coreAltsType alts') alts') tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} NotTopLevel name ty' info @@ -1598,7 +1598,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; return (Let (Rec pairs') body') } } where tc_rec_bndr (IfLetBndr fs ty _ ji) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; return (mkLocalId name ManyTy ty' `asJoinId_maybe` ji) } tc_pair (IfLetBndr _ _ info _, rhs) id @@ -1655,12 +1655,12 @@ tcIfaceAlt scrut mult (tycon, inst_tys) (IfaceAlt (IfaceDataAlt data_occ) arg_st (failIfM (ppr scrut $$ ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon))) ; tcIfaceDataAlt mult con inst_tys arg_strs rhs } -tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [FastString] -> IfaceExpr +tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [IfLclName] -> IfaceExpr -> IfL CoreAlt tcIfaceDataAlt mult con inst_tys arg_strs rhs = do { uniqs <- getUniquesM ; let (ex_tvs, arg_ids) - = dataConRepFSInstPat arg_strs uniqs mult con inst_tys + = dataConRepFSInstPat (map ifLclNameFS arg_strs) uniqs mult con inst_tys ; rhs' <- extendIfaceEnvs ex_tvs $ extendIfaceIdEnv arg_ids $ @@ -2031,7 +2031,7 @@ tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule -- - axioms for type-level literals (Nat and Symbol), -- enumerated in typeNatCoAxiomRules tcIfaceCoAxiomRule n - | Just ax <- lookupUFM typeNatCoAxiomRules n + | Just ax <- lookupUFM typeNatCoAxiomRules (ifLclNameFS n) = return ax | otherwise = pprPanic "tcIfaceCoAxiomRule" (ppr n) @@ -2075,7 +2075,7 @@ tcIfaceImplicit n = do bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a bindIfaceId (w, fs, ty) thing_inside - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; w' <- tcIfaceType w ; let id = mkLocalIdOrCoVar name w' ty' @@ -2118,7 +2118,7 @@ bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside - = do { name <- newIfaceName (mkTyVarOccFS occ) + = do { name <- newIfaceName (mkTyVarOccFS (ifLclNameFS occ)) ; tyvar <- mk_iface_tyvar name kind ; extendIfaceTyVarEnv [tyvar] (thing_inside tyvar) } ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -148,7 +148,7 @@ import qualified Data.Semigroup as Semi ********************************************************************* -} data LeftOrRight = CLeft | CRight - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) pickLR :: LeftOrRight -> (a,a) -> a pickLR CLeft (l,_) = l ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -720,7 +720,7 @@ Currently there are nine different uses of 'VarBndr': data VarBndr var argf = Bndr var argf -- See Note [The VarBndr type and its uses] - deriving( Data ) + deriving( Data, Eq, Ord) -- | Variable Binder -- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -127,7 +136,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (unfoldr) +import Data.List (sortOn, unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -230,22 +239,26 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a @@ -1102,24 +1115,35 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = inner_bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f p bh' seekBinReader bh p -- skip over the object for now return a @@ -1173,6 +1197,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) @@ -1313,6 +1343,80 @@ data WriterTable = WriterTable { putTable :: WriteBinHandle -> IO Int } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable a = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (Map.Map a Int)) + -- ^ Given a symbol, find the symbol + } + +initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef Map.empty + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + } + +putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_map = gen_symtab_map gen_sym_tab + symtab_next = gen_symtab_next gen_sym_tab + putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop bound = do + d <- readIORef symtab_map + table_count <- readFastMutInt symtab_next + let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + case vs of + [] -> return table_count + todo -> do + mapM_ (\n -> serialiser bh n) (map snd todo) + loop table_count + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop 0) + +getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next } + bh val = do + symtab_map <- readIORef symtab_map_ref + case Map.lookup val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! Map.insert val off symtab_map + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -78,6 +78,7 @@ import Data.Eq import Data.Bool import Data.Char import Prelude (Integer, length) +import Data.Ord (Ord) {- ************************************************************************ @@ -91,7 +92,7 @@ import Prelude (Integer, length) data PromotionFlag = NotPromoted | IsPromoted - deriving ( Eq, Data ) + deriving ( Eq, Data, Ord ) isPromoted :: PromotionFlag -> Bool isPromoted IsPromoted = True ===================================== compiler/Language/Haskell/Syntax/Type.hs-boot ===================================== @@ -2,6 +2,7 @@ module Language.Haskell.Syntax.Type where import Data.Bool import Data.Eq +import Data.Ord {- ************************************************************************ @@ -17,5 +18,6 @@ data PromotionFlag | IsPromoted instance Eq PromotionFlag +instance Ord PromotionFlag isPromoted :: PromotionFlag -> Bool ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 +Subproject commit e095ca841b89b5958376768d18ae156b7a413da0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17010aed403c3388411e15efb585d81bb3c30e3c...fba95eb0166ee5660fc92e603decf83ce381bf64 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17010aed403c3388411e15efb585d81bb3c30e3c...fba95eb0166ee5660fc92e603decf83ce381bf64 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 10:23:35 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 06:23:35 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <6613c5a796d2_1da3dbae1a8c987aa@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - f724da82 by Fendor at 2024-04-08T06:23:19-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - d42a8a04 by Fendor at 2024-04-08T06:23:20-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - 13 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Pat.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - − test.hs - testsuite/tests/ghci/should_run/BinaryArray.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive @@ -224,7 +224,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64 +mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) + let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + insns + bitmap + (mkBCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOByteArray(..), mkBCOByteArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -34,10 +37,10 @@ import GHCi.BreakArray import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq +import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray ) import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -153,8 +156,8 @@ data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !(BCOByteArray Word16), -- insns + unlinkedBCOBitmap :: !(BCOByteArray Word), -- bitmap unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -350,7 +350,7 @@ hsRecUpdFieldOcc = fmap unambiguousFieldOcc . hfbLHS instance Outputable (HsTyPat p) => Outputable (HsConPatTyArg p) where ppr (HsConPatTyArg _ ty) = char '@' <> ppr ty -instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ Located RecFieldsDotDot) +instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ LocatedE RecFieldsDotDot) => Outputable (HsRecFields p arg) where ppr (HsRecFields { rec_flds = flds, rec_dotdot = Nothing }) = braces (fsep (punctuate comma (map ppr flds))) @@ -976,4 +976,4 @@ type instance Anno (Pat (GhcPass p)) = SrcSpanAnnA type instance Anno (HsOverLit (GhcPass p)) = EpAnnCO type instance Anno ConLike = SrcSpanAnnN type instance Anno (HsFieldBind lhs rhs) = SrcSpanAnnA -type instance Anno RecFieldsDotDot = SrcSpan +type instance Anno RecFieldsDotDot = EpaLocation ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1830,7 +1830,7 @@ lPatImplicits = hs_lpat details (RecCon (HsRecFields { rec_dotdot = Nothing, rec_flds })) = hs_lpats $ map (hfbRHS . unLoc) rec_flds details (RecCon (HsRecFields { rec_dotdot = Just (L err_loc rec_dotdot), rec_flds })) - = [(err_loc, implicit_field_binders)] + = [(l2l err_loc, implicit_field_binders)] ++ hs_lpats explicit_pats where (explicit_pats, implicit_field_binders) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2679,7 +2679,7 @@ mkRdrRecordCon con flds anns mk_rec_fields :: [LocatedA (HsRecField (GhcPass p) arg)] -> Maybe SrcSpan -> HsRecFields (GhcPass p) arg mk_rec_fields fs Nothing = HsRecFields { rec_flds = fs, rec_dotdot = Nothing } mk_rec_fields fs (Just s) = HsRecFields { rec_flds = fs - , rec_dotdot = Just (L s (RecFieldsDotDot $ length fs)) } + , rec_dotdot = Just (L (l2l s) (RecFieldsDotDot $ length fs)) } mk_rec_upd_field :: HsRecField GhcPs (LHsExpr GhcPs) -> HsRecUpdField GhcPs GhcPs mk_rec_upd_field (HsFieldBind noAnn (L loc (FieldOcc _ rdr)) arg pun) ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -775,7 +775,7 @@ rnHsRecPatsAndThen mk (L _ con) do { arg' <- rnLPatAndThen (nested_mk dd mk (RecFieldsDotDot n')) (hfbRHS fld) ; return (L l (fld { hfbRHS = arg' })) } - loc = maybe noSrcSpan getLoc dd + loc = maybe noSrcSpan getLocA dd -- Don't warn for let P{..} = ... in ... check_unused_wildcard = case mk of @@ -873,12 +873,12 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) , hfbRHS = arg' , hfbPun = pun } } - rn_dotdot :: Maybe (Located RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat + rn_dotdot :: Maybe (LocatedE RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat -> Maybe Name -- The constructor (Nothing for an -- out of scope constructor) -> [LHsRecField GhcRn (LocatedA arg)] -- Explicit fields -> RnM ([LHsRecField GhcRn (LocatedA arg)]) -- Field Labels we need to fill in - rn_dotdot (Just (L loc (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match + rn_dotdot (Just (L loc_e (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match | not (isUnboundName con) -- This test is because if the constructor -- isn't in scope the constructor lookup will add -- an error but still return an unbound name. We @@ -910,6 +910,7 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) _other -> True ] ; addUsedGREs NoDeprecationWarnings dot_dot_gres + ; let loc = locA loc_e ; let locn = noAnnSrcSpan loc ; return [ L (noAnnSrcSpan loc) (HsFieldBind { hfbAnn = noAnn ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) + , mkBCOByteArray ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +14,19 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts +import Data.Array.Base (UArray(..)) + +import GHC.IO #include "MachDeps.h" @@ -32,19 +43,35 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word, -- bitmap + resolvedBCOLits :: BCOByteArray Word, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +mkBCOByteArray :: UArray Int a -> BCOByteArray a +mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word) where + showsPrec _ _ = showString "BCOByteArray Word" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +81,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +106,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== test.hs deleted ===================================== @@ -1,14 +0,0 @@ -import Data.Char -import Data.Foldable --- | Just like 'GHC.ResponseFile.escapeArg', but it is not exposed from base. -escapeArg :: String -> String -escapeArg = reverse . foldl' escape [] - -escape :: String -> Char -> String -escape cs c - | isSpace c - || '\\' == c - || '\'' == c - || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result - | otherwise = c:cs - ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -3328,12 +3328,13 @@ instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where setAnnotationAnchor a _ _ _ = a exact (HsRecFields fields mdot) = do fields' <- markAnnotated fields - case mdot of - Nothing -> return () - Just (L ss _) -> - printStringAtSs ss ".." >> return () + mdot' <- case mdot of + Nothing -> return Nothing + Just (L ss d) -> do + ss' <- printStringAtAA ss ".." + return $ Just (L ss' d) -- Note: mdot contains the SrcSpan where the ".." appears, if present - return (HsRecFields fields' mdot) + return (HsRecFields fields' mdot') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81bbfde980e4a60daafd22de09609e91c261ae4a...d42a8a04e8d73b75110ad376149ac071987481dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81bbfde980e4a60daafd22de09609e91c261ae4a...d42a8a04e8d73b75110ad376149ac071987481dd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 12:45:24 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 08 Apr 2024 08:45:24 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Fixup: rename name tables Message-ID: <6613e6e4c8ba2_1da3db1cf08b8128571@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 72116c2a by Fendor at 2024-04-08T14:42:55+02:00 Fixup: rename name tables - - - - - e79b4636 by Fendor at 2024-04-08T14:45:17+02:00 Fixup: add note about deduplication - - - - - 1 changed file: - compiler/GHC/Iface/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -159,7 +159,7 @@ getWithUserData name_cache bh = do getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do fsReaderTable <- initFastStringReaderTable - nameReaderTable <- (initReadNameCachedBinary name_cache) + nameReaderTable <- initNameReaderTable name_cache -- The order of these deserialisation matters! @@ -237,7 +237,7 @@ putWithUserData traceBinIface bh payload = do putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable - (name_wt, nameWriter) <- initWriteNameTable + (name_wt, nameWriter) <- initNameWriterTable let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter @@ -277,8 +277,8 @@ binaryInterfaceMagic platform Note [Iface Binary Serialisation] ~~~~~~~~~~~~~~~~~~~ When we serialise a 'ModIface', many symbols are redundant. -For example, there can be duplicated 'FastString's and 'Name's. -To save space, we deduplicate some symbols, such as 'FastString' and 'Name', +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', by maintaining a table of already seen symbols. When serialising a symbol, we lookup whether we have encountered the symbol before. If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. @@ -286,6 +286,48 @@ If yes, we write the index of the symbol, otherwise we generate a new index and Besides saving a lot of disk space, this additionally enables us to automatically share these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: + +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser instead of + directly serialising itself. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + +* Whenever a value of 'IfaceTyCon' is serialised, the real serialisation function needs to + be configured in the User Data. + + For example, for 'IfaceTyCon': + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + Now, here we can introduce the deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a 'Map' and remembers the offset + of each value we have already seen. + Instead of serialising the full 'IfaceTyCon', we only write the index of the value to disk. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + Note [Iface Binary Serialiser Order] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. @@ -336,8 +378,8 @@ Here, a visualisation of the table structure we currently have: -- -initReadNameCachedBinary :: NameCache -> IO (ReaderTable Name) -initReadNameCachedBinary cache = do +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do return $ ReaderTable { getTable = \bh -> getSymbolTable bh cache @@ -350,8 +392,8 @@ data BinSymbolTable = BinSymbolTable { -- indexed by Name } -initWriteNameTable :: IO (WriterTable, BinaryWriter Name) -initWriteNameTable = do +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do symtab_next <- newFastMutInt 0 symtab_map <- newIORef emptyUFM let bin_symtab = View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/adf68fbabc8b0654e324959421496a59d85deb14...e79b463691f12528ca6e4bf7b1744388c248d183 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/adf68fbabc8b0654e324959421496a59d85deb14...e79b463691f12528ca6e4bf7b1744388c248d183 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 13:04:05 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 09:04:05 -0400 Subject: [Git][ghc/ghc][master] Avoid UArray when indexing is not required Message-ID: <6613eb457b8d5_1da3db20ab9bc132573@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - 6 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - testsuite/tests/ghci/should_run/BinaryArray.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive @@ -224,7 +224,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64 +mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) + let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + insns + bitmap + (mkBCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOByteArray(..), mkBCOByteArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -34,10 +37,10 @@ import GHCi.BreakArray import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq +import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray ) import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -153,8 +156,8 @@ data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !(BCOByteArray Word16), -- insns + unlinkedBCOBitmap :: !(BCOByteArray Word), -- bitmap unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) + , mkBCOByteArray ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +14,19 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts +import Data.Array.Base (UArray(..)) + +import GHC.IO #include "MachDeps.h" @@ -32,19 +43,35 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word, -- bitmap + resolvedBCOLits :: BCOByteArray Word, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +mkBCOByteArray :: UArray Int a -> BCOByteArray a +mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word) where + showsPrec _ _ = showString "BCOByteArray Word" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +81,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +106,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/88cb3e1079e88ba10065ce260a96095ae96d58e8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/88cb3e1079e88ba10065ce260a96095ae96d58e8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 13:04:49 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 09:04:49 -0400 Subject: [Git][ghc/ghc][master] Never UNPACK `FastMutInt` for counting z-encoded `FastString`s Message-ID: <6613eb7178794_1da3db2264ac413634d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - 1 changed file: - compiler/GHC/Data/FastString.hs Changes: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2cc1107790d42fee1a11d5b16bc282d31ea6f78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2cc1107790d42fee1a11d5b16bc282d31ea6f78 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 15:42:28 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 08 Apr 2024 11:42:28 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 9 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <6614106444fd4_1facd059a7f482818@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - e2688e0c by Rodrigo Mesquita at 2024-04-08T16:41:09+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 0ad72f29 by Alexis King at 2024-04-08T16:42:10+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - aa6a1201 by Rodrigo Mesquita at 2024-04-08T16:42:11+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 51593f58 by Rodrigo Mesquita at 2024-04-08T16:42:11+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 0e12f612 by Ben Gamari at 2024-04-08T16:42:11+01:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/ResolvedBCO.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de52433e3d2259cf227252cd0ccedce0ad09ec98...0e12f612d7b3890b075324d4e847c28ab7449663 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de52433e3d2259cf227252cd0ccedce0ad09ec98...0e12f612d7b3890b075324d4e847c28ab7449663 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:07:10 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 13:07:10 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Avoid UArray when indexing is not required Message-ID: <6614243e47be9_1facd013ddb54177552@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - f16c3f7d by Matthew Pickering at 2024-04-08T13:06:45-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - f5d9ed32 by Fendor at 2024-04-08T13:06:45-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 9688e341 by Alan Zimmerman at 2024-04-08T13:06:45-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 91341c46 by Alan Zimmerman at 2024-04-08T13:06:45-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 17 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - ghc/GHCi/UI.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - testsuite/tests/ghci/should_run/BinaryArray.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive @@ -224,7 +224,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64 +mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) + let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + insns + bitmap + (mkBCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOByteArray(..), mkBCOByteArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -34,10 +37,10 @@ import GHCi.BreakArray import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq +import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray ) import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -153,8 +156,8 @@ data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !(BCOByteArray Word16), -- insns + unlinkedBCOBitmap :: !(BCOByteArray Word), -- bitmap unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -595,8 +595,8 @@ fromIfaceWarnings = \case fromIfaceWarningTxt :: IfaceWarningTxt -> WarningTxt GhcRn fromIfaceWarningTxt = \case - IfWarningTxt mb_cat src strs -> WarningTxt (noLoc . fromWarningCategory <$> mb_cat) src (noLoc <$> map fromIfaceStringLiteralWithNames strs) - IfDeprecatedTxt src strs -> DeprecatedTxt src (noLoc <$> map fromIfaceStringLiteralWithNames strs) + IfWarningTxt mb_cat src strs -> WarningTxt (noLocA . fromWarningCategory <$> mb_cat) src (noLocA <$> map fromIfaceStringLiteralWithNames strs) + IfDeprecatedTxt src strs -> DeprecatedTxt src (noLocA <$> map fromIfaceStringLiteralWithNames strs) fromIfaceStringLiteralWithNames :: (IfaceStringLiteral, [IfExtName]) -> WithHsDocIdentifiers StringLiteral GhcRn fromIfaceStringLiteralWithNames (str, names) = WithHsDocIdentifiers (fromIfaceStringLiteral str) (map noLoc names) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,9 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl + -- Force this field access, as `main_name` thunk will otherwise + -- be retained in the thunk created by `forkM`. -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the ===================================== compiler/GHC/Parser.y ===================================== @@ -1964,9 +1964,9 @@ maybe_warning_pragma :: { Maybe (LWarningTxt GhcPs) } (AnnPragma (mo $1) (mc $4) (fst $ unLoc $3))} | {- empty -} { Nothing } -warning_category :: { Maybe (Located InWarningCategory) } - : 'in' STRING { Just (sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) - (sL1 $2 $ mkWarningCategory (getSTRING $2))) } +warning_category :: { Maybe (LocatedE InWarningCategory) } + : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) + (reLoc $ sL1 $2 $ mkWarningCategory (getSTRING $2))) } | {- empty -} { Nothing } warnings :: { OrdList (LWarnDecl GhcPs) } @@ -4131,8 +4131,8 @@ getSCC lt = do let s = getSTRING lt then addFatalError $ mkPlainErrorMsgEnvelope (getLoc lt) $ PsErrSpaceInSCC else return s -stringLiteralToHsDocWst :: Located StringLiteral -> Located (WithHsDocIdentifiers StringLiteral GhcPs) -stringLiteralToHsDocWst = lexStringLiteral parseIdentifier +stringLiteralToHsDocWst :: Located StringLiteral -> LocatedE (WithHsDocIdentifiers StringLiteral GhcPs) +stringLiteralToHsDocWst sl = reLoc $ lexStringLiteral parseIdentifier sl -- Utilities for combining source spans comb2 :: (HasLoc a, HasLoc b) => a -> b -> SrcSpan @@ -4560,7 +4560,7 @@ addTrailingCommaN (L anns a) span = do addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral addTrailingCommaS (L l sl) span - = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaToNoCommentsLocation span) }) -- ------------------------------------- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -454,27 +454,8 @@ instance Outputable EpaComment where -- annotation. data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq) --- | The anchor for an @'AnnKeywordId'@. The Parser inserts the --- @'EpaSpan'@ variant, giving the exact location of the original item --- in the parsed source. This can be replaced by the @'EpaDelta'@ --- version, to provide a position for the item relative to the end of --- the previous item in the source. This is useful when editing an --- AST prior to exact printing the changed one. The list of comments --- in the @'EpaDelta'@ variant captures any comments between the prior --- output and the thing being marked here, since we cannot otherwise --- sort the relative order. - -data EpaLocation' a = EpaSpan !SrcSpan - | EpaDelta !DeltaPos !a - deriving (Data,Eq,Show) - type EpaLocation = EpaLocation' [LEpaComment] -type NoCommentsLocation = EpaLocation' NoComments - -data NoComments = NoComments - deriving (Data,Eq,Ord,Show) - epaToNoCommentsLocation :: EpaLocation -> NoCommentsLocation epaToNoCommentsLocation (EpaSpan ss) = EpaSpan ss epaToNoCommentsLocation (EpaDelta dp []) = EpaDelta dp NoComments @@ -492,34 +473,6 @@ data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation instance Outputable a => Outputable (GenLocated TokenLocation a) where ppr (L _ x) = ppr x --- | Spacing between output items when exact printing. It captures --- the spacing from the current print position on the page to the --- position required for the thing about to be printed. This is --- either on the same line in which case is is simply the number of --- spaces to emit, or it is some number of lines down, with a given --- column offset. The exact printing algorithm keeps track of the --- column offset pertaining to the current anchor position, so the --- `deltaColumn` is the additional spaces to add in this case. See --- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for --- details. -data DeltaPos - = SameLine { deltaColumn :: !Int } - | DifferentLine - { deltaLine :: !Int, -- ^ deltaLine should always be > 0 - deltaColumn :: !Int - } deriving (Show,Eq,Ord,Data) - --- | Smart constructor for a 'DeltaPos'. It preserves the invariant --- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. -deltaPos :: Int -> Int -> DeltaPos -deltaPos l c = case l of - 0 -> SameLine c - _ -> DifferentLine l c - -getDeltaLine :: DeltaPos -> Int -getDeltaLine (SameLine _) = 0 -getDeltaLine (DifferentLine r _) = r - -- | Used in the parser only, extract the 'RealSrcSpan' from an -- 'EpaLocation'. The parser will never insert a 'DeltaPos', so the -- partial function is safe. @@ -527,13 +480,6 @@ epaLocationRealSrcSpan :: EpaLocation -> RealSrcSpan epaLocationRealSrcSpan (EpaSpan (RealSrcSpan r _)) = r epaLocationRealSrcSpan _ = panic "epaLocationRealSrcSpan" -instance Outputable NoComments where - ppr NoComments = text "NoComments" - -instance (Outputable a) => Outputable (EpaLocation' a) where - ppr (EpaSpan r) = text "EpaSpan" <+> ppr r - ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs - instance Outputable AddEpAnn where ppr (AddEpAnn kw ss) = text "AddEpAnn" <+> ppr kw <+> ppr ss @@ -1419,10 +1365,6 @@ instance (Outputable a) => Outputable (EpAnn a) where instance Outputable NoEpAnns where ppr NoEpAnns = text "NoEpAnns" -instance Outputable DeltaPos where - ppr (SameLine c) = text "SameLine" <+> ppr c - ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c - instance Outputable (GenLocated NoCommentsLocation EpaComment) where ppr (L l c) = text "L" <+> ppr l <+> ppr c ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -310,7 +310,7 @@ rnWarningTxt :: WarningTxt GhcPs -> RnM (WarningTxt GhcRn) rnWarningTxt (WarningTxt mb_cat st wst) = do forM_ mb_cat $ \(L _ (InWarningCategory _ _ (L loc cat))) -> unless (validWarningCategory cat) $ - addErrAt loc (TcRnInvalidWarningCategory cat) + addErrAt (locA loc) (TcRnInvalidWarningCategory cat) wst' <- traverse (traverse rnHsDoc) wst pure (WarningTxt mb_cat st wst') rnWarningTxt (DeprecatedTxt st wst) = do ===================================== compiler/GHC/Types/SourceText.hs ===================================== @@ -305,17 +305,13 @@ data StringLiteral = StringLiteral { sl_st :: SourceText, -- literal raw source. -- See Note [Literal source text] sl_fs :: FastString, -- literal string value - sl_tc :: Maybe RealSrcSpan -- Location of + sl_tc :: Maybe NoCommentsLocation + -- Location of -- possible -- trailing comma -- AZ: if we could have a LocatedA -- StringLiteral we would not need sl_tc, but -- that would cause import loops. - - -- AZ:2: sl_tc should be an EpaAnchor, to allow - -- editing and reprinting the AST. Need a more - -- robust solution. - } deriving Data instance Eq StringLiteral where ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -109,6 +109,10 @@ module GHC.Types.SrcLoc ( mkSrcSpanPs, combineRealSrcSpans, psLocatedToLocated, + + -- * Exact print locations + EpaLocation'(..), NoCommentsLocation, NoComments(..), + DeltaPos(..), deltaPos, getDeltaLine, ) where import GHC.Prelude @@ -894,3 +898,70 @@ psSpanEnd (PsSpan r b) = PsLoc (realSrcSpanEnd r) (bufSpanEnd b) mkSrcSpanPs :: PsSpan -> SrcSpan mkSrcSpanPs (PsSpan r b) = RealSrcSpan r (Strict.Just b) + +-- --------------------------------------------------------------------- +-- The following section contains basic types related to exact printing. +-- See https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +-- This is only s subset, to prevent import loops. The balance are in +-- GHC.Parser.Annotation +-- --------------------------------------------------------------------- + + +-- | The anchor for an @'AnnKeywordId'@. The Parser inserts the +-- @'EpaSpan'@ variant, giving the exact location of the original item +-- in the parsed source. This can be replaced by the @'EpaDelta'@ +-- version, to provide a position for the item relative to the end of +-- the previous item in the source. This is useful when editing an +-- AST prior to exact printing the changed one. The list of comments +-- in the @'EpaDelta'@ variant captures any comments between the prior +-- output and the thing being marked here, since we cannot otherwise +-- sort the relative order. + +data EpaLocation' a = EpaSpan !SrcSpan + | EpaDelta !DeltaPos !a + deriving (Data,Eq,Show) + +type NoCommentsLocation = EpaLocation' NoComments + +data NoComments = NoComments + deriving (Data,Eq,Ord,Show) + +-- | Spacing between output items when exact printing. It captures +-- the spacing from the current print position on the page to the +-- position required for the thing about to be printed. This is +-- either on the same line in which case is is simply the number of +-- spaces to emit, or it is some number of lines down, with a given +-- column offset. The exact printing algorithm keeps track of the +-- column offset pertaining to the current anchor position, so the +-- `deltaColumn` is the additional spaces to add in this case. See +-- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +data DeltaPos + = SameLine { deltaColumn :: !Int } + | DifferentLine + { deltaLine :: !Int, -- ^ deltaLine should always be > 0 + deltaColumn :: !Int + } deriving (Show,Eq,Ord,Data) + +-- | Smart constructor for a 'DeltaPos'. It preserves the invariant +-- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. +deltaPos :: Int -> Int -> DeltaPos +deltaPos l c = case l of + 0 -> SameLine c + _ -> DifferentLine l c + +getDeltaLine :: DeltaPos -> Int +getDeltaLine (SameLine _) = 0 +getDeltaLine (DifferentLine r _) = r + +instance Outputable NoComments where + ppr NoComments = text "NoComments" + +instance (Outputable a) => Outputable (EpaLocation' a) where + ppr (EpaSpan r) = text "EpaSpan" <+> ppr r + ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs + +instance Outputable DeltaPos where + ppr (SameLine c) = text "SameLine" <+> ppr c + ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c ===================================== compiler/GHC/Unit/Module/Warnings.hs ===================================== @@ -121,11 +121,11 @@ data InWarningCategory = InWarningCategory { iwc_in :: !(EpToken "in"), iwc_st :: !SourceText, - iwc_wc :: (Located WarningCategory) + iwc_wc :: (LocatedE WarningCategory) } deriving Data fromWarningCategory :: WarningCategory -> InWarningCategory -fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLoc wc) +fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLocA wc) -- See Note [Warning categories] @@ -201,14 +201,14 @@ type LWarningTxt pass = XRec pass (WarningTxt pass) -- reason/explanation from a WARNING or DEPRECATED pragma data WarningTxt pass = WarningTxt - (Maybe (Located InWarningCategory)) + (Maybe (LocatedE InWarningCategory)) -- ^ Warning category attached to this WARNING pragma, if any; -- see Note [Warning categories] SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] | DeprecatedTxt SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] deriving Generic -- | To which warning category does this WARNING or DEPRECATED pragma belong? @@ -218,7 +218,7 @@ warningTxtCategory (WarningTxt (Just (L _ (InWarningCategory _ _ (L _ cat)))) _ warningTxtCategory _ = defaultWarningCategory -- | The message that the WarningTxt was specified to output -warningTxtMessage :: WarningTxt p -> [Located (WithHsDocIdentifiers StringLiteral p)] +warningTxtMessage :: WarningTxt p -> [LocatedE (WithHsDocIdentifiers StringLiteral p)] warningTxtMessage (WarningTxt _ _ m) = m warningTxtMessage (DeprecatedTxt _ m) = m @@ -260,7 +260,7 @@ instance Outputable (WarningTxt pass) where NoSourceText -> pp_ws ds SourceText src -> ftext src <+> pp_ws ds <+> text "#-}" -pp_ws :: [Located (WithHsDocIdentifiers StringLiteral pass)] -> SDoc +pp_ws :: [LocatedE (WithHsDocIdentifiers StringLiteral pass)] -> SDoc pp_ws [l] = ppr $ unLoc l pp_ws ws = text "[" ===================================== ghc/GHCi/UI.hs ===================================== @@ -557,7 +557,8 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) + , mkBCOByteArray ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +14,19 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts +import Data.Array.Base (UArray(..)) + +import GHC.IO #include "MachDeps.h" @@ -32,19 +43,35 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word, -- bitmap + resolvedBCOLits :: BCOByteArray Word, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +mkBCOByteArray :: UArray Int a -> BCOByteArray a +mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word) where + showsPrec _ _ = showString "BCOByteArray Word" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +81,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +106,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -711,6 +711,11 @@ printStringAtMLocL (EpAnn anc an cs) l s = do printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation printStringAtAA el str = printStringAtAAC CaptureComments el str +printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation +printStringAtNC el str = do + el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str + return (epaToNoCommentsLocation el') + printStringAtAAL :: (Monad m, Monoid w) => a -> Lens a EpaLocation -> String -> EP w m a printStringAtAAL an l str = do @@ -2117,10 +2122,10 @@ instance ExactPrint StringLiteral where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact l@(StringLiteral src fs mcomma) = do + exact (StringLiteral src fs mcomma) = do printSourceTextAA src (show (unpackFS fs)) - mapM_ (\r -> printStringAtRs r ",") mcomma - return l + mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma + return (StringLiteral src fs mcomma') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d42a8a04e8d73b75110ad376149ac071987481dd...91341c467bc898ae151816bc89b82ca93d27101e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d42a8a04e8d73b75110ad376149ac071987481dd...91341c467bc898ae151816bc89b82ca93d27101e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:17:02 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 13:17:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24403 Message-ID: <6614268e280b1_1facd0156c9c0180770@gitlab.mail> Ben Gamari pushed new branch wip/T24403 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24403 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:23:13 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Mon, 08 Apr 2024 13:23:13 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] 170 commits: Rephrase error message to say "visible arguments" (#24318) Message-ID: <66142801174f_1facd0179e4dc185434@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - f9b6ffc2 by Mikolaj Konarski at 2024-04-08T19:04:06+02:00 Add DCoVarSet to PluginProv Add the only remaining piece of feedback from git add src/Flavour.hs Help CI check some more of the patch Fix the 3 plugin tests that fail Explain better how shallowCoVarsOfCosDSet is entangled with a hundreds of lines bit-rotten refactoring Fix according to the first round of Simon's instruction Fix according to the second round of Simon's instruction Remove a question-comment that's probably absurd Fix according to the third round of Simon's instruction Make sure the foldl' accumulators are strict Fix the horrid perf bug in coVarsOfType See #24591 Touch up the new Note Try out a variant of Simon's fix to the second perf problem Ajust a single test in testsuite that uses PluginProv - - - - - 88234812 by Mikolaj Konarski at 2024-04-08T19:22:51+02:00 Adjust according to Ben's feedback - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/318499d81e685fd6ad9bb39c80f5bc217276301e...882348122856f2fd5fb935d3cbae9699f4ec23c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/318499d81e685fd6ad9bb39c80f5bc217276301e...882348122856f2fd5fb935d3cbae9699f4ec23c9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:39:24 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 13:39:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T21461 Message-ID: <66142bcca4d49_1facd01aa278c19093c@gitlab.mail> Ben Gamari pushed new branch wip/T21461 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T21461 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:40:24 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 13:40:24 -0400 Subject: [Git][ghc/ghc][wip/T21461] base: Deprecate GHC.Pack Message-ID: <66142c08a3ba_1facd01b2fa7419276f@gitlab.mail> Ben Gamari pushed to branch wip/T21461 at Glasgow Haskell Compiler / GHC Commits: edc76b48 by Ben Gamari at 2024-04-08T13:40:06-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 2 changed files: - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs Changes: ===================================== libraries/base/changelog.md ===================================== @@ -4,6 +4,7 @@ * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edc76b48146b70eb372c38c43ca55538d5160953 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edc76b48146b70eb372c38c43ca55538d5160953 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 17:46:50 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 13:46:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24609 Message-ID: <66142d8a1add2_1facd01cc0884193121@gitlab.mail> Ben Gamari pushed new branch wip/T24609 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24609 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 18:04:44 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 14:04:44 -0400 Subject: [Git][ghc/ghc][wip/T24403] testsuite: Add test of IPE information for unpackCString# Message-ID: <661431bcc8e3f_1facd01ff58ec2230b4@gitlab.mail> Ben Gamari pushed to branch wip/T24403 at Glasgow Haskell Compiler / GHC Commits: 9fdecc70 by Ben Gamari at 2024-04-08T14:04:32-04:00 testsuite: Add test of IPE information for unpackCString# See #24403. - - - - - 3 changed files: - + testsuite/tests/rts/T24403.hs - + testsuite/tests/rts/T24403.stdout - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/rts/T24403.hs ===================================== @@ -0,0 +1,7 @@ +import GHC.InfoProv + +hello :: String +hello = "hello" + +main :: IO () +main = whereFrom hello >>= print ===================================== testsuite/tests/rts/T24403.stdout ===================================== @@ -0,0 +1 @@ +Just (InfoProv {ipName = "stg_unpack_cstring_info", ipDesc = THUNK_STATIC, ipTyDesc = "", ipLabel = "", ipUnitId = "rts", ipMod = "Cmm$rts/StgStdThunks.cmm", ipSrcFile = "", ipSrcSpan = ""}) ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,5 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24403', only_ways('optasm'), compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9fdecc7028e4b75edb04fc7404016027d5816826 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9fdecc7028e4b75edb04fc7404016027d5816826 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 18:21:30 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 14:21:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23680 Message-ID: <661435aa909a1_1facd02303dcc234258@gitlab.mail> Ben Gamari pushed new branch wip/T23680 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23680 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 18:50:23 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 14:50:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T20201 Message-ID: <66143c6fb565d_1facd02755de42499ac@gitlab.mail> Ben Gamari pushed new branch wip/T20201 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T20201 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 18:54:06 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 14:54:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24127 Message-ID: <66143d4edcfcd_1facd02815d6025331a@gitlab.mail> Ben Gamari pushed new branch wip/T24127 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24127 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 19:03:35 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 15:03:35 -0400 Subject: [Git][ghc/ghc][wip/T23895] 743 commits: Move lib{numa, dw} defines to RTS configure Message-ID: <66143f8781bd9_1facd02a8805c2671e7@gitlab.mail> Ben Gamari pushed to branch wip/T23895 at Glasgow Haskell Compiler / GHC Commits: 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - cd488d38 by Ben Gamari at 2024-04-08T15:03:19-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - 21 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/merge_request_templates/Default.md - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - .gitlab/test-metrics.sh - .gitmodules - CODEOWNERS - compiler/CodeGen.Platform.h - compiler/GHC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d9837b2abe6ea72dde7ff037b293e4980f63517c...cd488d388158b64c8584b01d80a5be5fc94016e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d9837b2abe6ea72dde7ff037b293e4980f63517c...cd488d388158b64c8584b01d80a5be5fc94016e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 19:27:19 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Mon, 08 Apr 2024 15:27:19 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Try to fix the user guide ref Message-ID: <66144517a9f6e_1facd02e17d582727b3@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 5295319e by Mikolaj Konarski at 2024-04-08T21:27:13+02:00 Try to fix the user guide ref - - - - - 1 changed file: - docs/users_guide/9.12.1-notes.rst Changes: ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -20,7 +20,7 @@ for typing plugins, gets an extra `DCoVarSet` argument. The argument is intended to contain the in-scope coercion variables that the the proof represented by the coercion makes use of. See Note [The importance of tracking free coercion variables] -or :ref:`Constraint solving with plugins` or the migration guide. +or :ref:`constraint-solving-with-plugins` or the migration guide. GHCi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5295319e2636c388cdbdb082a5fe9560ec126aaf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5295319e2636c388cdbdb082a5fe9560ec126aaf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:01:12 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 16:01:12 -0400 Subject: [Git][ghc/ghc][wip/T23680] rts: Implement set_initial_registers for AArch64 Message-ID: <66144d0876eb5_1facd0329d8502748c2@gitlab.mail> Ben Gamari pushed to branch wip/T23680 at Glasgow Haskell Compiler / GHC Commits: 12d5987a by Ben Gamari at 2024-04-08T16:01:06-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 1 changed file: - rts/Libdw.c Changes: ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x100]\n\t" + "str x21, [%0, 0x108]\n\t" + "str x22, [%0, 0x110]\n\t" + "str x23, [%0, 0x118]\n\t" + "str x24, [%0, 0x120]\n\t" + "str x25, [%0, 0x128]\n\t" + "str x26, [%0, 0x130]\n\t" + "str x27, [%0, 0x138]\n\t" + "str x28, [%0, 0x140]\n\t" + "str x29, [%0, 0x148]\n\t" + "str x30, [%0, 0x150]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x158]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x160]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/12d5987a77600bb818b5bb61302420b85bc57e62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/12d5987a77600bb818b5bb61302420b85bc57e62 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:02:11 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 16:02:11 -0400 Subject: [Git][ghc/ghc][wip/T23680] rts: Implement set_initial_registers for AArch64 Message-ID: <66144d437744_1facd03334610275218@gitlab.mail> Ben Gamari pushed to branch wip/T23680 at Glasgow Haskell Compiler / GHC Commits: 04815d38 by Ben Gamari at 2024-04-08T16:02:02-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 1 changed file: - rts/Libdw.c Changes: ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x100]\n\t" + "str x21, [%0, 0x108]\n\t" + "str x22, [%0, 0x110]\n\t" + "str x23, [%0, 0x118]\n\t" + "str x24, [%0, 0x120]\n\t" + "str x25, [%0, 0x128]\n\t" + "str x26, [%0, 0x130]\n\t" + "str x27, [%0, 0x138]\n\t" + "str x28, [%0, 0x140]\n\t" + "str x29, [%0, 0x148]\n\t" + "str x30, [%0, 0x150]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x158]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x160]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04815d382dfb7a68af2e05d59197ae0fda0c6a9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04815d382dfb7a68af2e05d59197ae0fda0c6a9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:07:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 16:07:25 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Force in_multi to avoid retaining entire hsc_env Message-ID: <66144e7db0000_1facd035c83f4282763@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 2 changed files: - compiler/GHC/IfaceToCore.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,9 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl + -- Force this field access, as `main_name` thunk will otherwise + -- be retained in the thunk created by `forkM`. -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the ===================================== ghc/GHCi/UI.hs ===================================== @@ -557,7 +557,8 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2cc1107790d42fee1a11d5b16bc282d31ea6f78...fbb91a6371308fffca926f0ab45ae0a14e7c6847 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2cc1107790d42fee1a11d5b16bc282d31ea6f78...fbb91a6371308fffca926f0ab45ae0a14e7c6847 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:08:08 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 16:08:08 -0400 Subject: [Git][ghc/ghc][master] 2 commits: EPA: Use EpaLocation in WarningTxt Message-ID: <66144ea850cc0_1facd0377e4a0286068@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 8 changed files: - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -595,8 +595,8 @@ fromIfaceWarnings = \case fromIfaceWarningTxt :: IfaceWarningTxt -> WarningTxt GhcRn fromIfaceWarningTxt = \case - IfWarningTxt mb_cat src strs -> WarningTxt (noLoc . fromWarningCategory <$> mb_cat) src (noLoc <$> map fromIfaceStringLiteralWithNames strs) - IfDeprecatedTxt src strs -> DeprecatedTxt src (noLoc <$> map fromIfaceStringLiteralWithNames strs) + IfWarningTxt mb_cat src strs -> WarningTxt (noLocA . fromWarningCategory <$> mb_cat) src (noLocA <$> map fromIfaceStringLiteralWithNames strs) + IfDeprecatedTxt src strs -> DeprecatedTxt src (noLocA <$> map fromIfaceStringLiteralWithNames strs) fromIfaceStringLiteralWithNames :: (IfaceStringLiteral, [IfExtName]) -> WithHsDocIdentifiers StringLiteral GhcRn fromIfaceStringLiteralWithNames (str, names) = WithHsDocIdentifiers (fromIfaceStringLiteral str) (map noLoc names) ===================================== compiler/GHC/Parser.y ===================================== @@ -1964,9 +1964,9 @@ maybe_warning_pragma :: { Maybe (LWarningTxt GhcPs) } (AnnPragma (mo $1) (mc $4) (fst $ unLoc $3))} | {- empty -} { Nothing } -warning_category :: { Maybe (Located InWarningCategory) } - : 'in' STRING { Just (sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) - (sL1 $2 $ mkWarningCategory (getSTRING $2))) } +warning_category :: { Maybe (LocatedE InWarningCategory) } + : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) + (reLoc $ sL1 $2 $ mkWarningCategory (getSTRING $2))) } | {- empty -} { Nothing } warnings :: { OrdList (LWarnDecl GhcPs) } @@ -4131,8 +4131,8 @@ getSCC lt = do let s = getSTRING lt then addFatalError $ mkPlainErrorMsgEnvelope (getLoc lt) $ PsErrSpaceInSCC else return s -stringLiteralToHsDocWst :: Located StringLiteral -> Located (WithHsDocIdentifiers StringLiteral GhcPs) -stringLiteralToHsDocWst = lexStringLiteral parseIdentifier +stringLiteralToHsDocWst :: Located StringLiteral -> LocatedE (WithHsDocIdentifiers StringLiteral GhcPs) +stringLiteralToHsDocWst sl = reLoc $ lexStringLiteral parseIdentifier sl -- Utilities for combining source spans comb2 :: (HasLoc a, HasLoc b) => a -> b -> SrcSpan @@ -4560,7 +4560,7 @@ addTrailingCommaN (L anns a) span = do addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral addTrailingCommaS (L l sl) span - = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaToNoCommentsLocation span) }) -- ------------------------------------- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -454,27 +454,8 @@ instance Outputable EpaComment where -- annotation. data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq) --- | The anchor for an @'AnnKeywordId'@. The Parser inserts the --- @'EpaSpan'@ variant, giving the exact location of the original item --- in the parsed source. This can be replaced by the @'EpaDelta'@ --- version, to provide a position for the item relative to the end of --- the previous item in the source. This is useful when editing an --- AST prior to exact printing the changed one. The list of comments --- in the @'EpaDelta'@ variant captures any comments between the prior --- output and the thing being marked here, since we cannot otherwise --- sort the relative order. - -data EpaLocation' a = EpaSpan !SrcSpan - | EpaDelta !DeltaPos !a - deriving (Data,Eq,Show) - type EpaLocation = EpaLocation' [LEpaComment] -type NoCommentsLocation = EpaLocation' NoComments - -data NoComments = NoComments - deriving (Data,Eq,Ord,Show) - epaToNoCommentsLocation :: EpaLocation -> NoCommentsLocation epaToNoCommentsLocation (EpaSpan ss) = EpaSpan ss epaToNoCommentsLocation (EpaDelta dp []) = EpaDelta dp NoComments @@ -492,34 +473,6 @@ data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation instance Outputable a => Outputable (GenLocated TokenLocation a) where ppr (L _ x) = ppr x --- | Spacing between output items when exact printing. It captures --- the spacing from the current print position on the page to the --- position required for the thing about to be printed. This is --- either on the same line in which case is is simply the number of --- spaces to emit, or it is some number of lines down, with a given --- column offset. The exact printing algorithm keeps track of the --- column offset pertaining to the current anchor position, so the --- `deltaColumn` is the additional spaces to add in this case. See --- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for --- details. -data DeltaPos - = SameLine { deltaColumn :: !Int } - | DifferentLine - { deltaLine :: !Int, -- ^ deltaLine should always be > 0 - deltaColumn :: !Int - } deriving (Show,Eq,Ord,Data) - --- | Smart constructor for a 'DeltaPos'. It preserves the invariant --- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. -deltaPos :: Int -> Int -> DeltaPos -deltaPos l c = case l of - 0 -> SameLine c - _ -> DifferentLine l c - -getDeltaLine :: DeltaPos -> Int -getDeltaLine (SameLine _) = 0 -getDeltaLine (DifferentLine r _) = r - -- | Used in the parser only, extract the 'RealSrcSpan' from an -- 'EpaLocation'. The parser will never insert a 'DeltaPos', so the -- partial function is safe. @@ -527,13 +480,6 @@ epaLocationRealSrcSpan :: EpaLocation -> RealSrcSpan epaLocationRealSrcSpan (EpaSpan (RealSrcSpan r _)) = r epaLocationRealSrcSpan _ = panic "epaLocationRealSrcSpan" -instance Outputable NoComments where - ppr NoComments = text "NoComments" - -instance (Outputable a) => Outputable (EpaLocation' a) where - ppr (EpaSpan r) = text "EpaSpan" <+> ppr r - ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs - instance Outputable AddEpAnn where ppr (AddEpAnn kw ss) = text "AddEpAnn" <+> ppr kw <+> ppr ss @@ -1419,10 +1365,6 @@ instance (Outputable a) => Outputable (EpAnn a) where instance Outputable NoEpAnns where ppr NoEpAnns = text "NoEpAnns" -instance Outputable DeltaPos where - ppr (SameLine c) = text "SameLine" <+> ppr c - ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c - instance Outputable (GenLocated NoCommentsLocation EpaComment) where ppr (L l c) = text "L" <+> ppr l <+> ppr c ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -310,7 +310,7 @@ rnWarningTxt :: WarningTxt GhcPs -> RnM (WarningTxt GhcRn) rnWarningTxt (WarningTxt mb_cat st wst) = do forM_ mb_cat $ \(L _ (InWarningCategory _ _ (L loc cat))) -> unless (validWarningCategory cat) $ - addErrAt loc (TcRnInvalidWarningCategory cat) + addErrAt (locA loc) (TcRnInvalidWarningCategory cat) wst' <- traverse (traverse rnHsDoc) wst pure (WarningTxt mb_cat st wst') rnWarningTxt (DeprecatedTxt st wst) = do ===================================== compiler/GHC/Types/SourceText.hs ===================================== @@ -305,17 +305,13 @@ data StringLiteral = StringLiteral { sl_st :: SourceText, -- literal raw source. -- See Note [Literal source text] sl_fs :: FastString, -- literal string value - sl_tc :: Maybe RealSrcSpan -- Location of + sl_tc :: Maybe NoCommentsLocation + -- Location of -- possible -- trailing comma -- AZ: if we could have a LocatedA -- StringLiteral we would not need sl_tc, but -- that would cause import loops. - - -- AZ:2: sl_tc should be an EpaAnchor, to allow - -- editing and reprinting the AST. Need a more - -- robust solution. - } deriving Data instance Eq StringLiteral where ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -109,6 +109,10 @@ module GHC.Types.SrcLoc ( mkSrcSpanPs, combineRealSrcSpans, psLocatedToLocated, + + -- * Exact print locations + EpaLocation'(..), NoCommentsLocation, NoComments(..), + DeltaPos(..), deltaPos, getDeltaLine, ) where import GHC.Prelude @@ -894,3 +898,70 @@ psSpanEnd (PsSpan r b) = PsLoc (realSrcSpanEnd r) (bufSpanEnd b) mkSrcSpanPs :: PsSpan -> SrcSpan mkSrcSpanPs (PsSpan r b) = RealSrcSpan r (Strict.Just b) + +-- --------------------------------------------------------------------- +-- The following section contains basic types related to exact printing. +-- See https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +-- This is only s subset, to prevent import loops. The balance are in +-- GHC.Parser.Annotation +-- --------------------------------------------------------------------- + + +-- | The anchor for an @'AnnKeywordId'@. The Parser inserts the +-- @'EpaSpan'@ variant, giving the exact location of the original item +-- in the parsed source. This can be replaced by the @'EpaDelta'@ +-- version, to provide a position for the item relative to the end of +-- the previous item in the source. This is useful when editing an +-- AST prior to exact printing the changed one. The list of comments +-- in the @'EpaDelta'@ variant captures any comments between the prior +-- output and the thing being marked here, since we cannot otherwise +-- sort the relative order. + +data EpaLocation' a = EpaSpan !SrcSpan + | EpaDelta !DeltaPos !a + deriving (Data,Eq,Show) + +type NoCommentsLocation = EpaLocation' NoComments + +data NoComments = NoComments + deriving (Data,Eq,Ord,Show) + +-- | Spacing between output items when exact printing. It captures +-- the spacing from the current print position on the page to the +-- position required for the thing about to be printed. This is +-- either on the same line in which case is is simply the number of +-- spaces to emit, or it is some number of lines down, with a given +-- column offset. The exact printing algorithm keeps track of the +-- column offset pertaining to the current anchor position, so the +-- `deltaColumn` is the additional spaces to add in this case. See +-- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +data DeltaPos + = SameLine { deltaColumn :: !Int } + | DifferentLine + { deltaLine :: !Int, -- ^ deltaLine should always be > 0 + deltaColumn :: !Int + } deriving (Show,Eq,Ord,Data) + +-- | Smart constructor for a 'DeltaPos'. It preserves the invariant +-- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. +deltaPos :: Int -> Int -> DeltaPos +deltaPos l c = case l of + 0 -> SameLine c + _ -> DifferentLine l c + +getDeltaLine :: DeltaPos -> Int +getDeltaLine (SameLine _) = 0 +getDeltaLine (DifferentLine r _) = r + +instance Outputable NoComments where + ppr NoComments = text "NoComments" + +instance (Outputable a) => Outputable (EpaLocation' a) where + ppr (EpaSpan r) = text "EpaSpan" <+> ppr r + ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs + +instance Outputable DeltaPos where + ppr (SameLine c) = text "SameLine" <+> ppr c + ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c ===================================== compiler/GHC/Unit/Module/Warnings.hs ===================================== @@ -121,11 +121,11 @@ data InWarningCategory = InWarningCategory { iwc_in :: !(EpToken "in"), iwc_st :: !SourceText, - iwc_wc :: (Located WarningCategory) + iwc_wc :: (LocatedE WarningCategory) } deriving Data fromWarningCategory :: WarningCategory -> InWarningCategory -fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLoc wc) +fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLocA wc) -- See Note [Warning categories] @@ -201,14 +201,14 @@ type LWarningTxt pass = XRec pass (WarningTxt pass) -- reason/explanation from a WARNING or DEPRECATED pragma data WarningTxt pass = WarningTxt - (Maybe (Located InWarningCategory)) + (Maybe (LocatedE InWarningCategory)) -- ^ Warning category attached to this WARNING pragma, if any; -- see Note [Warning categories] SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] | DeprecatedTxt SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] deriving Generic -- | To which warning category does this WARNING or DEPRECATED pragma belong? @@ -218,7 +218,7 @@ warningTxtCategory (WarningTxt (Just (L _ (InWarningCategory _ _ (L _ cat)))) _ warningTxtCategory _ = defaultWarningCategory -- | The message that the WarningTxt was specified to output -warningTxtMessage :: WarningTxt p -> [Located (WithHsDocIdentifiers StringLiteral p)] +warningTxtMessage :: WarningTxt p -> [LocatedE (WithHsDocIdentifiers StringLiteral p)] warningTxtMessage (WarningTxt _ _ m) = m warningTxtMessage (DeprecatedTxt _ m) = m @@ -260,7 +260,7 @@ instance Outputable (WarningTxt pass) where NoSourceText -> pp_ws ds SourceText src -> ftext src <+> pp_ws ds <+> text "#-}" -pp_ws :: [Located (WithHsDocIdentifiers StringLiteral pass)] -> SDoc +pp_ws :: [LocatedE (WithHsDocIdentifiers StringLiteral pass)] -> SDoc pp_ws [l] = ppr $ unLoc l pp_ws ws = text "[" ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -711,6 +711,11 @@ printStringAtMLocL (EpAnn anc an cs) l s = do printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation printStringAtAA el str = printStringAtAAC CaptureComments el str +printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation +printStringAtNC el str = do + el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str + return (epaToNoCommentsLocation el') + printStringAtAAL :: (Monad m, Monoid w) => a -> Lens a EpaLocation -> String -> EP w m a printStringAtAAL an l str = do @@ -2117,10 +2122,10 @@ instance ExactPrint StringLiteral where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact l@(StringLiteral src fs mcomma) = do + exact (StringLiteral src fs mcomma) = do printSourceTextAA src (show (unpackFS fs)) - mapM_ (\r -> printStringAtRs r ",") mcomma - return l + mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma + return (StringLiteral src fs mcomma') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fbb91a6371308fffca926f0ab45ae0a14e7c6847...12b997df559365e6188824fb10f5f61c2e9075e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fbb91a6371308fffca926f0ab45ae0a14e7c6847...12b997df559365e6188824fb10f5f61c2e9075e4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:28:12 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 08 Apr 2024 16:28:12 -0400 Subject: [Git][ghc/ghc][wip/T23680] rts: Implement set_initial_registers for AArch64 Message-ID: <6614535c18f52_e67f1d129484619@gitlab.mail> Ben Gamari pushed to branch wip/T23680 at Glasgow Haskell Compiler / GHC Commits: de154045 by Ben Gamari at 2024-04-08T16:28:06-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 1 changed file: - rts/Libdw.c Changes: ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x0a0]\n\t" + "str x21, [%0, 0x0a8]\n\t" + "str x22, [%0, 0x0b0]\n\t" + "str x23, [%0, 0x0b8]\n\t" + "str x24, [%0, 0x0c0]\n\t" + "str x25, [%0, 0x0c8]\n\t" + "str x26, [%0, 0x0d0]\n\t" + "str x27, [%0, 0x0d8]\n\t" + "str x28, [%0, 0x0e0]\n\t" + "str x29, [%0, 0x0e8]\n\t" + "str x30, [%0, 0x0f0]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x0f8]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x100]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de1540458866d0398a348feee11f08229195a3c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de1540458866d0398a348feee11f08229195a3c1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:33:29 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Mon, 08 Apr 2024 16:33:29 -0400 Subject: [Git][ghc/ghc][wip/az/epa-T24533-3] 7 commits: Avoid UArray when indexing is not required Message-ID: <661454994ab41_e67f37499885378@gitlab.mail> Alan Zimmerman pushed to branch wip/az/epa-T24533-3 at Glasgow Haskell Compiler / GHC Commits: 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - e8396e86 by Alan Zimmerman at 2024-04-08T21:10:31+01:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 20 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - ghc/GHCi/UI.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - testsuite/tests/ghci/should_run/BinaryArray.hs - testsuite/tests/printer/Test24533.hs - testsuite/tests/printer/Test24533.stdout - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive @@ -224,7 +224,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64 +mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) + let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + insns + bitmap + (mkBCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOByteArray(..), mkBCOByteArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -34,10 +37,10 @@ import GHCi.BreakArray import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq +import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray ) import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -153,8 +156,8 @@ data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !(BCOByteArray Word16), -- insns + unlinkedBCOBitmap :: !(BCOByteArray Word), -- bitmap unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -595,8 +595,8 @@ fromIfaceWarnings = \case fromIfaceWarningTxt :: IfaceWarningTxt -> WarningTxt GhcRn fromIfaceWarningTxt = \case - IfWarningTxt mb_cat src strs -> WarningTxt (noLoc . fromWarningCategory <$> mb_cat) src (noLoc <$> map fromIfaceStringLiteralWithNames strs) - IfDeprecatedTxt src strs -> DeprecatedTxt src (noLoc <$> map fromIfaceStringLiteralWithNames strs) + IfWarningTxt mb_cat src strs -> WarningTxt (noLocA . fromWarningCategory <$> mb_cat) src (noLocA <$> map fromIfaceStringLiteralWithNames strs) + IfDeprecatedTxt src strs -> DeprecatedTxt src (noLocA <$> map fromIfaceStringLiteralWithNames strs) fromIfaceStringLiteralWithNames :: (IfaceStringLiteral, [IfExtName]) -> WithHsDocIdentifiers StringLiteral GhcRn fromIfaceStringLiteralWithNames (str, names) = WithHsDocIdentifiers (fromIfaceStringLiteral str) (map noLoc names) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,9 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl + -- Force this field access, as `main_name` thunk will otherwise + -- be retained in the thunk created by `forkM`. -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the ===================================== compiler/GHC/Parser.y ===================================== @@ -1964,9 +1964,9 @@ maybe_warning_pragma :: { Maybe (LWarningTxt GhcPs) } (AnnPragma (mo $1) (mc $4) (fst $ unLoc $3))} | {- empty -} { Nothing } -warning_category :: { Maybe (Located InWarningCategory) } - : 'in' STRING { Just (sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) - (sL1 $2 $ mkWarningCategory (getSTRING $2))) } +warning_category :: { Maybe (LocatedE InWarningCategory) } + : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) + (reLoc $ sL1 $2 $ mkWarningCategory (getSTRING $2))) } | {- empty -} { Nothing } warnings :: { OrdList (LWarnDecl GhcPs) } @@ -4131,8 +4131,8 @@ getSCC lt = do let s = getSTRING lt then addFatalError $ mkPlainErrorMsgEnvelope (getLoc lt) $ PsErrSpaceInSCC else return s -stringLiteralToHsDocWst :: Located StringLiteral -> Located (WithHsDocIdentifiers StringLiteral GhcPs) -stringLiteralToHsDocWst = lexStringLiteral parseIdentifier +stringLiteralToHsDocWst :: Located StringLiteral -> LocatedE (WithHsDocIdentifiers StringLiteral GhcPs) +stringLiteralToHsDocWst sl = reLoc $ lexStringLiteral parseIdentifier sl -- Utilities for combining source spans comb2 :: (HasLoc a, HasLoc b) => a -> b -> SrcSpan @@ -4560,7 +4560,7 @@ addTrailingCommaN (L anns a) span = do addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral addTrailingCommaS (L l sl) span - = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaToNoCommentsLocation span) }) -- ------------------------------------- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -454,27 +454,8 @@ instance Outputable EpaComment where -- annotation. data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq) --- | The anchor for an @'AnnKeywordId'@. The Parser inserts the --- @'EpaSpan'@ variant, giving the exact location of the original item --- in the parsed source. This can be replaced by the @'EpaDelta'@ --- version, to provide a position for the item relative to the end of --- the previous item in the source. This is useful when editing an --- AST prior to exact printing the changed one. The list of comments --- in the @'EpaDelta'@ variant captures any comments between the prior --- output and the thing being marked here, since we cannot otherwise --- sort the relative order. - -data EpaLocation' a = EpaSpan !SrcSpan - | EpaDelta !DeltaPos !a - deriving (Data,Eq,Show) - type EpaLocation = EpaLocation' [LEpaComment] -type NoCommentsLocation = EpaLocation' NoComments - -data NoComments = NoComments - deriving (Data,Eq,Ord,Show) - epaToNoCommentsLocation :: EpaLocation -> NoCommentsLocation epaToNoCommentsLocation (EpaSpan ss) = EpaSpan ss epaToNoCommentsLocation (EpaDelta dp []) = EpaDelta dp NoComments @@ -492,34 +473,6 @@ data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation instance Outputable a => Outputable (GenLocated TokenLocation a) where ppr (L _ x) = ppr x --- | Spacing between output items when exact printing. It captures --- the spacing from the current print position on the page to the --- position required for the thing about to be printed. This is --- either on the same line in which case is is simply the number of --- spaces to emit, or it is some number of lines down, with a given --- column offset. The exact printing algorithm keeps track of the --- column offset pertaining to the current anchor position, so the --- `deltaColumn` is the additional spaces to add in this case. See --- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for --- details. -data DeltaPos - = SameLine { deltaColumn :: !Int } - | DifferentLine - { deltaLine :: !Int, -- ^ deltaLine should always be > 0 - deltaColumn :: !Int - } deriving (Show,Eq,Ord,Data) - --- | Smart constructor for a 'DeltaPos'. It preserves the invariant --- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. -deltaPos :: Int -> Int -> DeltaPos -deltaPos l c = case l of - 0 -> SameLine c - _ -> DifferentLine l c - -getDeltaLine :: DeltaPos -> Int -getDeltaLine (SameLine _) = 0 -getDeltaLine (DifferentLine r _) = r - -- | Used in the parser only, extract the 'RealSrcSpan' from an -- 'EpaLocation'. The parser will never insert a 'DeltaPos', so the -- partial function is safe. @@ -527,13 +480,6 @@ epaLocationRealSrcSpan :: EpaLocation -> RealSrcSpan epaLocationRealSrcSpan (EpaSpan (RealSrcSpan r _)) = r epaLocationRealSrcSpan _ = panic "epaLocationRealSrcSpan" -instance Outputable NoComments where - ppr NoComments = text "NoComments" - -instance (Outputable a) => Outputable (EpaLocation' a) where - ppr (EpaSpan r) = text "EpaSpan" <+> ppr r - ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs - instance Outputable AddEpAnn where ppr (AddEpAnn kw ss) = text "AddEpAnn" <+> ppr kw <+> ppr ss @@ -1419,10 +1365,6 @@ instance (Outputable a) => Outputable (EpAnn a) where instance Outputable NoEpAnns where ppr NoEpAnns = text "NoEpAnns" -instance Outputable DeltaPos where - ppr (SameLine c) = text "SameLine" <+> ppr c - ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c - instance Outputable (GenLocated NoCommentsLocation EpaComment) where ppr (L l c) = text "L" <+> ppr l <+> ppr c ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -942,11 +942,10 @@ checkTyVars pp_what equals_or_where tc tparms -- Keep around an action for adjusting the annotations of extra parens chkParens :: [AddEpAnn] -> [AddEpAnn] -> HsBndrVis GhcPs -> LHsType GhcPs -> P (LHsTyVarBndr (HsBndrVis GhcPs) GhcPs) - chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) + chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) = let (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - lcs = epAnnComments l - lt' = setCommentsEpAnn lt lcs + (_,lt') = transferCommentsOnlyA l lt in chkParens (o:ops) (c:cps) bvis (L lt' ty) chkParens ops cps bvis ty = chk ops cps bvis ty @@ -1053,7 +1052,7 @@ checkTyClHdr :: Bool -- True <=> class header checkTyClHdr is_cls ty = goL ty [] [] [] Prefix where - goL (L l ty) acc ops cps fix = go (locA l) ty acc ops cps fix + goL (L l ty) acc ops cps fix = go l ty acc ops cps fix -- workaround to define '*' despite StarIsType go ll (HsParTy an (L l (HsStarTy _ isUni))) acc ops' cps' fix @@ -1071,11 +1070,11 @@ checkTyClHdr is_cls ty rhs = HsValArg noExtField t2 go l (HsParTy _ ty) acc ops cps fix = goL ty acc (o:ops) (c:cps) fix where - (o,c) = mkParensEpAnn (realSrcSpan l) + (o,c) = mkParensEpAnn (realSrcSpan (locA l)) go _ (HsAppTy _ t1 t2) acc ops cps fix = goL t1 (HsValArg noExtField t2:acc) ops cps fix go _ (HsAppKindTy at ty ki) acc ops cps fix = goL ty (HsTypeArg at ki:acc) ops cps fix go l (HsTupleTy _ HsBoxedOrConstraintTuple ts) [] ops cps fix - = return (L (noAnnSrcSpan l) (nameRdrName tup_name) + = return (L (l2l l) (nameRdrName tup_name) , map (HsValArg noExtField) ts, fix, (reverse ops)++cps) where arity = length ts @@ -1083,17 +1082,17 @@ checkTyClHdr is_cls ty | otherwise = getName (tupleTyCon Boxed arity) -- See Note [Unit tuples] in GHC.Hs.Type (TODO: is this still relevant?) go l _ _ _ _ _ - = addFatalError $ mkPlainErrorMsgEnvelope l $ + = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ (PsErrMalformedTyOrClDecl ty) -- Combine the annotations from the HsParTy and HsStarTy into a -- new one for the LocatedN RdrName - newAnns :: SrcSpan -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN - newAnns l (EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = + newAnns :: SrcSpanAnnA -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN + newAnns l@(EpAnn _ (AnnListItem _) csp0) l1@(EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = let - lr = combineSrcSpans (RealSrcSpan (anchor ap) Strict.Nothing) l + lr = combineSrcSpans (locA l1) (locA l) in - EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) csp + EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) (csp0 Semi.<> csp) -- | Yield a parse error if we have a function applied directly to a do block -- etc. and BlockArguments is not enabled. ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -310,7 +310,7 @@ rnWarningTxt :: WarningTxt GhcPs -> RnM (WarningTxt GhcRn) rnWarningTxt (WarningTxt mb_cat st wst) = do forM_ mb_cat $ \(L _ (InWarningCategory _ _ (L loc cat))) -> unless (validWarningCategory cat) $ - addErrAt loc (TcRnInvalidWarningCategory cat) + addErrAt (locA loc) (TcRnInvalidWarningCategory cat) wst' <- traverse (traverse rnHsDoc) wst pure (WarningTxt mb_cat st wst') rnWarningTxt (DeprecatedTxt st wst) = do ===================================== compiler/GHC/Types/SourceText.hs ===================================== @@ -305,17 +305,13 @@ data StringLiteral = StringLiteral { sl_st :: SourceText, -- literal raw source. -- See Note [Literal source text] sl_fs :: FastString, -- literal string value - sl_tc :: Maybe RealSrcSpan -- Location of + sl_tc :: Maybe NoCommentsLocation + -- Location of -- possible -- trailing comma -- AZ: if we could have a LocatedA -- StringLiteral we would not need sl_tc, but -- that would cause import loops. - - -- AZ:2: sl_tc should be an EpaAnchor, to allow - -- editing and reprinting the AST. Need a more - -- robust solution. - } deriving Data instance Eq StringLiteral where ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -109,6 +109,10 @@ module GHC.Types.SrcLoc ( mkSrcSpanPs, combineRealSrcSpans, psLocatedToLocated, + + -- * Exact print locations + EpaLocation'(..), NoCommentsLocation, NoComments(..), + DeltaPos(..), deltaPos, getDeltaLine, ) where import GHC.Prelude @@ -894,3 +898,70 @@ psSpanEnd (PsSpan r b) = PsLoc (realSrcSpanEnd r) (bufSpanEnd b) mkSrcSpanPs :: PsSpan -> SrcSpan mkSrcSpanPs (PsSpan r b) = RealSrcSpan r (Strict.Just b) + +-- --------------------------------------------------------------------- +-- The following section contains basic types related to exact printing. +-- See https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +-- This is only s subset, to prevent import loops. The balance are in +-- GHC.Parser.Annotation +-- --------------------------------------------------------------------- + + +-- | The anchor for an @'AnnKeywordId'@. The Parser inserts the +-- @'EpaSpan'@ variant, giving the exact location of the original item +-- in the parsed source. This can be replaced by the @'EpaDelta'@ +-- version, to provide a position for the item relative to the end of +-- the previous item in the source. This is useful when editing an +-- AST prior to exact printing the changed one. The list of comments +-- in the @'EpaDelta'@ variant captures any comments between the prior +-- output and the thing being marked here, since we cannot otherwise +-- sort the relative order. + +data EpaLocation' a = EpaSpan !SrcSpan + | EpaDelta !DeltaPos !a + deriving (Data,Eq,Show) + +type NoCommentsLocation = EpaLocation' NoComments + +data NoComments = NoComments + deriving (Data,Eq,Ord,Show) + +-- | Spacing between output items when exact printing. It captures +-- the spacing from the current print position on the page to the +-- position required for the thing about to be printed. This is +-- either on the same line in which case is is simply the number of +-- spaces to emit, or it is some number of lines down, with a given +-- column offset. The exact printing algorithm keeps track of the +-- column offset pertaining to the current anchor position, so the +-- `deltaColumn` is the additional spaces to add in this case. See +-- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +data DeltaPos + = SameLine { deltaColumn :: !Int } + | DifferentLine + { deltaLine :: !Int, -- ^ deltaLine should always be > 0 + deltaColumn :: !Int + } deriving (Show,Eq,Ord,Data) + +-- | Smart constructor for a 'DeltaPos'. It preserves the invariant +-- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. +deltaPos :: Int -> Int -> DeltaPos +deltaPos l c = case l of + 0 -> SameLine c + _ -> DifferentLine l c + +getDeltaLine :: DeltaPos -> Int +getDeltaLine (SameLine _) = 0 +getDeltaLine (DifferentLine r _) = r + +instance Outputable NoComments where + ppr NoComments = text "NoComments" + +instance (Outputable a) => Outputable (EpaLocation' a) where + ppr (EpaSpan r) = text "EpaSpan" <+> ppr r + ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs + +instance Outputable DeltaPos where + ppr (SameLine c) = text "SameLine" <+> ppr c + ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c ===================================== compiler/GHC/Unit/Module/Warnings.hs ===================================== @@ -121,11 +121,11 @@ data InWarningCategory = InWarningCategory { iwc_in :: !(EpToken "in"), iwc_st :: !SourceText, - iwc_wc :: (Located WarningCategory) + iwc_wc :: (LocatedE WarningCategory) } deriving Data fromWarningCategory :: WarningCategory -> InWarningCategory -fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLoc wc) +fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLocA wc) -- See Note [Warning categories] @@ -201,14 +201,14 @@ type LWarningTxt pass = XRec pass (WarningTxt pass) -- reason/explanation from a WARNING or DEPRECATED pragma data WarningTxt pass = WarningTxt - (Maybe (Located InWarningCategory)) + (Maybe (LocatedE InWarningCategory)) -- ^ Warning category attached to this WARNING pragma, if any; -- see Note [Warning categories] SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] | DeprecatedTxt SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] deriving Generic -- | To which warning category does this WARNING or DEPRECATED pragma belong? @@ -218,7 +218,7 @@ warningTxtCategory (WarningTxt (Just (L _ (InWarningCategory _ _ (L _ cat)))) _ warningTxtCategory _ = defaultWarningCategory -- | The message that the WarningTxt was specified to output -warningTxtMessage :: WarningTxt p -> [Located (WithHsDocIdentifiers StringLiteral p)] +warningTxtMessage :: WarningTxt p -> [LocatedE (WithHsDocIdentifiers StringLiteral p)] warningTxtMessage (WarningTxt _ _ m) = m warningTxtMessage (DeprecatedTxt _ m) = m @@ -260,7 +260,7 @@ instance Outputable (WarningTxt pass) where NoSourceText -> pp_ws ds SourceText src -> ftext src <+> pp_ws ds <+> text "#-}" -pp_ws :: [Located (WithHsDocIdentifiers StringLiteral pass)] -> SDoc +pp_ws :: [LocatedE (WithHsDocIdentifiers StringLiteral pass)] -> SDoc pp_ws [l] = ppr $ unLoc l pp_ws ws = text "[" ===================================== ghc/GHCi/UI.hs ===================================== @@ -557,7 +557,8 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) + , mkBCOByteArray ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +14,19 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts +import Data.Array.Base (UArray(..)) + +import GHC.IO #include "MachDeps.h" @@ -32,19 +43,35 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word, -- bitmap + resolvedBCOLits :: BCOByteArray Word, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +mkBCOByteArray :: UArray Int a -> BCOByteArray a +mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word) where + showsPrec _ _ = showString "BCOByteArray Word" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +81,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +106,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) ===================================== testsuite/tests/printer/Test24533.hs ===================================== @@ -7,7 +7,9 @@ instance ) => Read (a, b) -class Foo (a :: Type {- Weird -}) +{- Weird before -} +class {- Weird0 -} Foo {- Weird1 -} ({- Weird2 -} a {- Weird3 -} :: {- Weird4 -} Type {- Weird5 -}) {- Weird6 -} +{- Weird after -} instance Eq Foo where -- Weird ===================================== testsuite/tests/printer/Test24533.stdout ===================================== @@ -13,8 +13,8 @@ [] (Just ((,) - { Test24533.hs:15:1 } - { Test24533.hs:14:16-19 }))) + { Test24533.hs:17:1 } + { Test24533.hs:16:16-19 }))) (EpaCommentsBalanced [(L (EpaSpan @@ -276,22 +276,42 @@ (Nothing))))) ,(L (EpAnn - (EpaSpan { Test24533.hs:10:1-33 }) + (EpaSpan { Test24533.hs:11:1-99 }) (AnnListItem []) (EpaComments - [])) + [(L + (EpaSpan + { Test24533.hs:10:1-18 }) + (EpaComment + (EpaBlockComment + "{- Weird before -}") + { Test24533.hs:8:13 })) + ,(L + (EpaSpan + { Test24533.hs:11:7-18 }) + (EpaComment + (EpaBlockComment + "{- Weird0 -}") + { Test24533.hs:11:1-5 })) + ,(L + (EpaSpan + { Test24533.hs:11:24-35 }) + (EpaComment + (EpaBlockComment + "{- Weird1 -}") + { Test24533.hs:11:20-22 }))])) (TyClD (NoExtField) (ClassDecl ((,,) - [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:10:1-5 }))] + [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:11:1-5 }))] (EpNoLayout) (NoAnnSortKey)) (Nothing) (L (EpAnn - (EpaSpan { Test24533.hs:10:7-9 }) + (EpaSpan { Test24533.hs:11:20-22 }) (NameAnnTrailing []) (EpaComments @@ -302,26 +322,47 @@ (NoExtField) [(L (EpAnn - (EpaSpan { Test24533.hs:10:11-33 }) + (EpaSpan { Test24533.hs:11:37-99 }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:10:22-32 }) + { Test24533.hs:11:38-49 }) + (EpaComment + (EpaBlockComment + "{- Weird2 -}") + { Test24533.hs:11:37 })) + ,(L + (EpaSpan + { Test24533.hs:11:87-98 }) (EpaComment (EpaBlockComment - "{- Weird -}") - { Test24533.hs:10:17-20 }))])) + "{- Weird5 -}") + { Test24533.hs:11:82-85 })) + ,(L + (EpaSpan + { Test24533.hs:11:53-64 }) + (EpaComment + (EpaBlockComment + "{- Weird3 -}") + { Test24533.hs:11:51 })) + ,(L + (EpaSpan + { Test24533.hs:11:69-80 }) + (EpaComment + (EpaBlockComment + "{- Weird4 -}") + { Test24533.hs:11:66-67 }))])) (KindedTyVar - [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:10:11 })) - ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:10:33 })) - ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:10:14-15 }))] + [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:11:37 })) + ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:11:99 })) + ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:11:66-67 }))] (HsBndrRequired (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:10:12 }) + (EpaSpan { Test24533.hs:11:51 }) (NameAnnTrailing []) (EpaComments @@ -330,7 +371,7 @@ {OccName: a})) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (AnnListItem []) (EpaComments @@ -340,7 +381,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (NameAnnTrailing []) (EpaComments @@ -357,17 +398,31 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:(12,1)-(14,19) }) + (EpaSpan { Test24533.hs:(14,1)-(16,19) }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:13:3-10 }) + { Test24533.hs:15:3-10 }) (EpaComment (EpaLineComment "-- Weird") - { Test24533.hs:12:17-21 }))])) + { Test24533.hs:14:17-21 })) + ,(L + (EpaSpan + { Test24533.hs:11:101-112 }) + (EpaComment + (EpaBlockComment + "{- Weird6 -}") + { Test24533.hs:11:99 })) + ,(L + (EpaSpan + { Test24533.hs:12:1-17 }) + (EpaComment + (EpaBlockComment + "{- Weird after -}") + { Test24533.hs:11:101-112 }))])) (InstD (NoExtField) (ClsInstD @@ -375,12 +430,12 @@ (ClsInstDecl ((,,) (Nothing) - [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:12:1-8 })) - ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:12:17-21 }))] + [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:14:1-8 })) + ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:14:17-21 }))] (NoAnnSortKey)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -391,7 +446,7 @@ (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -400,7 +455,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (AnnListItem []) (EpaComments @@ -410,7 +465,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (NameAnnTrailing []) (EpaComments @@ -419,7 +474,7 @@ {OccName: Eq})))) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (AnnListItem []) (EpaComments @@ -429,7 +484,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (NameAnnTrailing []) (EpaComments @@ -439,7 +494,7 @@ {Bag(LocatedA (HsBind GhcPs)): [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -448,7 +503,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -459,7 +514,7 @@ (FromSource) (L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnList (Nothing) (Nothing) @@ -470,7 +525,7 @@ [])) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -480,7 +535,7 @@ (FunRhs (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -491,7 +546,7 @@ (NoSrcStrict)) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (AnnListItem []) (EpaComments @@ -500,7 +555,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (NameAnnTrailing []) (EpaComments @@ -512,7 +567,7 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (AnnListItem []) (EpaComments @@ -521,7 +576,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (NameAnnTrailing []) (EpaComments @@ -536,22 +591,22 @@ []) [(L (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (NoEpAnns) (EpaComments [])) (GRHS (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (GrhsAnn (Nothing) - (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:14:14 }))) + (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:16:14 }))) (EpaComments [])) [] (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (AnnListItem []) (EpaComments @@ -560,7 +615,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (NameAnnTrailing []) (EpaComments ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -711,6 +711,11 @@ printStringAtMLocL (EpAnn anc an cs) l s = do printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation printStringAtAA el str = printStringAtAAC CaptureComments el str +printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation +printStringAtNC el str = do + el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str + return (epaToNoCommentsLocation el') + printStringAtAAL :: (Monad m, Monoid w) => a -> Lens a EpaLocation -> String -> EP w m a printStringAtAAL an l str = do @@ -2117,10 +2122,10 @@ instance ExactPrint StringLiteral where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact l@(StringLiteral src fs mcomma) = do + exact (StringLiteral src fs mcomma) = do printSourceTextAA src (show (unpackFS fs)) - mapM_ (\r -> printStringAtRs r ",") mcomma - return l + mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma + return (StringLiteral src fs mcomma') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53e7333f58ea53198d8d9c1a6acaa131316a559d...e8396e869ba5c3812c4a9fd9127075ef1ee8ed83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53e7333f58ea53198d8d9c1a6acaa131316a559d...e8396e869ba5c3812c4a9fd9127075ef1ee8ed83 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 20:38:31 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 16:38:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Force in_multi to avoid retaining entire hsc_env Message-ID: <661455c79745_e67f6bd3e88835b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 0a832a7a by Fendor at 2024-04-08T16:38:21-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - cdd4c305 by Rodrigo Mesquita at 2024-04-08T16:38:21-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 965a4b38 by Alexis King at 2024-04-08T16:38:21-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - d50b99d9 by Rodrigo Mesquita at 2024-04-08T16:38:21-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 13b78b41 by Rodrigo Mesquita at 2024-04-08T16:38:21-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - d06cdbb5 by Ben Gamari at 2024-04-08T16:38:21-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - ghc/GHCi/UI.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91341c467bc898ae151816bc89b82ca93d27101e...d06cdbb5ee5cbabec81daaeca9414d6867250133 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91341c467bc898ae151816bc89b82ca93d27101e...d06cdbb5ee5cbabec81daaeca9414d6867250133 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 21:25:35 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Mon, 08 Apr 2024 17:25:35 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] 7 commits: Force in_multi to avoid retaining entire hsc_env Message-ID: <661460cfd68f4_e67fe5f0741070bb@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 5c5670d4 by Mikolaj Konarski at 2024-04-08T23:24:13+02:00 Add DCoVarSet to PluginProv Add the only remaining piece of feedback from git add src/Flavour.hs Help CI check some more of the patch Fix the 3 plugin tests that fail Explain better how shallowCoVarsOfCosDSet is entangled with a hundreds of lines bit-rotten refactoring Fix according to the first round of Simon's instruction Fix according to the second round of Simon's instruction Remove a question-comment that's probably absurd Fix according to the third round of Simon's instruction Make sure the foldl' accumulators are strict Fix the horrid perf bug in coVarsOfType See #24591 Touch up the new Note Try out a variant of Simon's fix to the second perf problem Ajust a single test in testsuite that uses PluginProv - - - - - aa048323 by Mikolaj Konarski at 2024-04-08T23:24:13+02:00 Adjust according to Ben's feedback - - - - - 2453254a by Mikolaj Konarski at 2024-04-08T23:24:13+02:00 Try to fix the user guide ref - - - - - 30 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Var/Set.hs - compiler/GHC/Unit/Module/Warnings.hs - compiler/GHC/Utils/FV.hs - docs/users_guide/9.12.1-notes.rst - docs/users_guide/extending_ghc.rst - ghc/GHCi/UI.hs - testsuite/tests/pmcheck/should_compile/T11195.hs - testsuite/tests/tcplugins/CtIdPlugin.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5295319e2636c388cdbdb082a5fe9560ec126aaf...2453254a81611531d38582a18c9ab53b10bd93ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5295319e2636c388cdbdb082a5fe9560ec126aaf...2453254a81611531d38582a18c9ab53b10bd93ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 8 21:26:06 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Mon, 08 Apr 2024 17:26:06 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Docs tweak courtesy of Ben Message-ID: <661460eeb3c3f_e67ff03b4c107975@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: a549f643 by Ben Gamari at 2024-04-08T21:26:05+00:00 Docs tweak courtesy of Ben - - - - - 1 changed file: - docs/users_guide/9.12.1-notes.rst Changes: ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -15,12 +15,12 @@ Language Compiler ~~~~~~~~ -- Constructor `PluginProv` of type `UnivCoProvenance`, relevant -for typing plugins, gets an extra `DCoVarSet` argument. +- Constructor ``PluginProv`` of type ``UnivCoProvenance``, relevant +for typing plugins, gets an extra ``DCoVarSet`` argument. The argument is intended to contain the in-scope coercion variables that the the proof represented by the coercion makes use of. -See Note [The importance of tracking free coercion variables] -or :ref:`constraint-solving-with-plugins` or the migration guide. +See ``Note [The importance of tracking free coercion variables]`` in ``GHC.Core.TyCo.Rep``, + :ref:`constraint-solving-with-plugins`, and the migration guide. GHCi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a549f6439673134fb609666cb8e85c73645c8586 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a549f6439673134fb609666cb8e85c73645c8586 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 00:29:21 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 08 Apr 2024 20:29:21 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Prefer packed representation for CompiledByteCode Message-ID: <66148be14fddf_e67f2718f701264d7@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cdb6f870 by Fendor at 2024-04-08T20:29:05-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - f9b7e2ef by Rodrigo Mesquita at 2024-04-08T20:29:05-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 57751952 by Alexis King at 2024-04-08T20:29:05-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 21e29f91 by Rodrigo Mesquita at 2024-04-08T20:29:05-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 3c2e8fc3 by Rodrigo Mesquita at 2024-04-08T20:29:05-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 5bcbb4d9 by Ben Gamari at 2024-04-08T20:29:05-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToByteCode.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - testsuite/tests/rts/linker/T2615.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d06cdbb5ee5cbabec81daaeca9414d6867250133...5bcbb4d9027438a77a0befd265a269be3b7c4c53 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d06cdbb5ee5cbabec81daaeca9414d6867250133...5bcbb4d9027438a77a0befd265a269be3b7c4c53 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 05:57:15 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Tue, 09 Apr 2024 01:57:15 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] 3 commits: Try to avoid a Sphinx error Message-ID: <6614d8bbabb2d_e67f4d834801511a4@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: f9e9d150 by Mikolaj Konarski at 2024-04-09T07:45:47+02:00 Try to avoid a Sphinx error - - - - - b021b7e9 by Mikolaj Konarski at 2024-04-09T07:48:09+02:00 Retitle a note - - - - - 3dc19098 by Mikolaj Konarski at 2024-04-09T07:56:22+02:00 Mention a note and tweak existing comments - - - - - 4 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Types/TyThing/Ppr.hs - docs/users_guide/9.12.1-notes.rst Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -177,7 +177,7 @@ toIfaceTypeX :: VarSet -> Type -> IfaceType -- translates the tyvars in 'free' as IfaceFreeTyVars -- -- Synonyms are retained in the interface type -toIfaceTypeX fr (TyVarTy tv) -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type +toIfaceTypeX fr (TyVarTy tv) -- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type | tv `elemVarSet` fr = IfaceFreeTyVar tv | otherwise = IfaceTyVar (toIfaceTyVar tv) toIfaceTypeX fr ty@(AppTy {}) = @@ -284,7 +284,7 @@ toIfaceCoercionX fr co go (Refl ty) = IfaceReflCo (toIfaceTypeX fr ty) go (GRefl r ty mco) = IfaceGReflCo r (toIfaceTypeX fr ty) (go_mco mco) go (CoVarCo cv) - -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type + -- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type | cv `elemVarSet` fr = IfaceFreeCoVar cv | otherwise = IfaceCoVarCo (toIfaceCoVar cv) go (HoleCo h) = IfaceHoleCo (coHoleCoVar h) ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -155,7 +155,7 @@ type IfaceKind = IfaceType -- Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType' -- before being printed. See Note [Pretty printing via Iface syntax] in "GHC.Types.TyThing.Ppr" data IfaceType - = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType] + = IfaceFreeTyVar TyVar -- See Note [Free TyVars and CoVars in IfaceType] | IfaceTyVar IfLclName -- Type/coercion variable only, not tycon | IfaceLitTy IfaceTyLit | IfaceAppTy IfaceType IfaceAppArgs @@ -285,7 +285,7 @@ instance Outputable IfaceTyConSort where ppr (IfaceSumTyCon n) = text "sum:" <> ppr n ppr IfaceEqualityTyCon = text "equality" -{- Note [Free tyvars in IfaceType] +{- Note [Free TyVars and CoVars in IfaceType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nowadays (since Nov 16, 2016) we pretty-print a Type by converting to an IfaceType and pretty printing that. This eliminates a lot of @@ -433,7 +433,7 @@ data IfaceCoercion | IfaceCoVarCo IfLclName | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion] | IfaceAxiomRuleCo IfLclName [IfaceCoercion] - -- There are only a fixed number of CoAxiomRules, so it suffices + -- ^ There are only a fixed number of CoAxiomRules, so it suffices -- to use an IfaceLclName to distinguish them. -- See Note [Adding built-in type families] in GHC.Builtin.Types.Literals | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType @@ -444,15 +444,15 @@ data IfaceCoercion | IfaceInstCo IfaceCoercion IfaceCoercion | IfaceKindCo IfaceCoercion | IfaceSubCo IfaceCoercion - | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] + | IfaceFreeCoVar CoVar -- ^ See Note [Free TyVars and CoVars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String [IfLclName] [Var] - -- Local covars and open (free) covars resp - -- See Note [Free tyvars in IfaceType] + -- ^ Local covars and open (free) covars resp + -- See Note [Free TyVars and CoVars in IfaceType] {- Note [Holes in IfaceCoercion] @@ -1027,7 +1027,7 @@ ppr_ty ctxt_prec ty | not (isIfaceRhoType ty) = ppr_sigma ShowForAllMust ctxt_prec ty ppr_ty _ (IfaceForAllTy {}) = panic "ppr_ty" -- Covered by not.isIfaceRhoType ppr_ty _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar! -ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [Free tyvars in IfaceType] +ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [Free TyVars and CoVars in IfaceType] ppr_ty ctxt_prec (IfaceTyConApp tc tys) = pprTyTcApp ctxt_prec tc tys ppr_ty ctxt_prec (IfaceTupleTy i p tys) = ppr_tuple ctxt_prec i p tys -- always fully saturated ppr_ty _ (IfaceLitTy n) = pprIfaceTyLit n @@ -1959,7 +1959,7 @@ ppr_co ctxt_prec co@(IfaceForAllCo {}) = let (tvs, co'') = split_co co' in ((name,kind_co,visL,visR):tvs,co'') split_co co' = ([], co') --- Why these three? See Note [Free tyvars in IfaceType] +-- Why these three? See Note [Free TyVars and CoVars in IfaceType] ppr_co _ (IfaceFreeCoVar covar) = ppr covar ppr_co _ (IfaceCoVarCo covar) = ppr covar ppr_co _ (IfaceHoleCo covar) = braces (ppr covar) @@ -2176,6 +2176,7 @@ ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where put_ _ (IfaceFreeTyVar tv) = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ bh (IfaceForAllTy aa ab) = do putByte bh 0 @@ -2324,9 +2325,10 @@ instance Binary IfaceCoercion where put_ bh b put_ _ (IfaceFreeCoVar cv) = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ _ (IfaceHoleCo cv) = pprPanic "Can't serialise IfaceHoleCo" (ppr cv) - -- See Note [Holes in IfaceCoercion] + -- See Note [Holes in IfaceCoercion] get bh = do tag <- getByte bh @@ -2399,6 +2401,7 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a cvs fcvs) = do putByte bh 3 put_ bh a + -- See Note [Free TyVars and CoVars in IfaceType] assertPpr (null fcvs) (ppr cvs $$ ppr fcvs) $ put_ bh cvs ===================================== compiler/GHC/Types/TyThing/Ppr.hs ===================================== @@ -98,7 +98,7 @@ Consequences: (in GHC.IfaceToCore). For example, IfaceClosedSynFamilyTyCon stores a [IfaceAxBranch] that is used only for pretty-printing. -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type +- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type See #7730, #8776 for details -} ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -19,8 +19,9 @@ Compiler for typing plugins, gets an extra ``DCoVarSet`` argument. The argument is intended to contain the in-scope coercion variables that the the proof represented by the coercion makes use of. -See ``Note [The importance of tracking free coercion variables]`` in ``GHC.Core.TyCo.Rep``, - :ref:`constraint-solving-with-plugins`, and the migration guide. +See ``Note [The importance of tracking free coercion variables]`` +in ``GHC.Core.TyCo.Rep``, :ref:`constraint-solving-with-plugins` +and the migration guide. GHCi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a549f6439673134fb609666cb8e85c73645c8586...3dc19098d999738cc236450caf33016948e9eef8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a549f6439673134fb609666cb8e85c73645c8586...3dc19098d999738cc236450caf33016948e9eef8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 06:18:34 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Tue, 09 Apr 2024 02:18:34 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Mention a note and tweak existing comments Message-ID: <6614ddba3bb7a_3f2cf4ec7846576f@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: a0a7470c by Mikolaj Konarski at 2024-04-09T08:18:22+02:00 Mention a note and tweak existing comments - - - - - 1 changed file: - compiler/GHC/Iface/Type.hs Changes: ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -433,7 +433,7 @@ data IfaceCoercion | IfaceCoVarCo IfLclName | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion] | IfaceAxiomRuleCo IfLclName [IfaceCoercion] - -- There are only a fixed number of CoAxiomRules, so it suffices + -- ^ There are only a fixed number of CoAxiomRules, so it suffices -- to use an IfaceLclName to distinguish them. -- See Note [Adding built-in type families] in GHC.Builtin.Types.Literals | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType @@ -444,14 +444,14 @@ data IfaceCoercion | IfaceInstCo IfaceCoercion IfaceCoercion | IfaceKindCo IfaceCoercion | IfaceSubCo IfaceCoercion - | IfaceFreeCoVar CoVar -- See Note [Free TyVars and CoVars in IfaceType] + | IfaceFreeCoVar CoVar -- ^ See Note [Free TyVars and CoVars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String [IfLclName] [Var] - -- Local covars and open (free) covars resp + -- ^ Local covars and open (free) covars resp -- See Note [Free TyVars and CoVars in IfaceType] @@ -2176,6 +2176,7 @@ ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where put_ _ (IfaceFreeTyVar tv) = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ bh (IfaceForAllTy aa ab) = do putByte bh 0 @@ -2324,9 +2325,10 @@ instance Binary IfaceCoercion where put_ bh b put_ _ (IfaceFreeCoVar cv) = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ _ (IfaceHoleCo cv) = pprPanic "Can't serialise IfaceHoleCo" (ppr cv) - -- See Note [Holes in IfaceCoercion] + -- See Note [Holes in IfaceCoercion] get bh = do tag <- getByte bh @@ -2399,6 +2401,7 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a cvs fcvs) = do putByte bh 3 put_ bh a + -- See Note [Free TyVars and CoVars in IfaceType] assertPpr (null fcvs) (ppr cvs $$ ppr fcvs) $ put_ bh cvs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0a7470c55c9351bed908d5f0d09ba7b7a87c359 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0a7470c55c9351bed908d5f0d09ba7b7a87c359 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 08:27:55 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 09 Apr 2024 04:27:55 -0400 Subject: [Git][ghc/ghc][wip/T24463] 17 commits: testsuite: Introduce template-haskell-exports test Message-ID: <6614fc0ba579f_3f2cf4105b7248258e@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24463 at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - d83279f3 by Simon Peyton Jones at 2024-04-09T09:27:32+01:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19be874ddb1318946d3332adc0264ac0f3074145...d83279f3cf970a94029c42f644740b2041032872 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19be874ddb1318946d3332adc0264ac0f3074145...d83279f3cf970a94029c42f644740b2041032872 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 09:03:32 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 09 Apr 2024 05:03:32 -0400 Subject: [Git][ghc/ghc][wip/romes/rts-linker-direct-symbol-lookup] 9 commits: Force in_multi to avoid retaining entire hsc_env Message-ID: <661504649198b_3f2cf4153c6bc849ca@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/rts-linker-direct-symbol-lookup at Glasgow Haskell Compiler / GHC Commits: c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 00cc8483 by Rodrigo Mesquita at 2024-04-09T10:03:21+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - db0b443e by Alexis King at 2024-04-09T10:03:21+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - ef323487 by Rodrigo Mesquita at 2024-04-09T10:03:21+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 6634b53b by Rodrigo Mesquita at 2024-04-09T10:03:21+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 7b2dd9e7 by Ben Gamari at 2024-04-09T10:03:21+01:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - ghc/GHCi/UI.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e12f612d7b3890b075324d4e847c28ab7449663...7b2dd9e723833ae6532cef4a4ff468d9895f3ae1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e12f612d7b3890b075324d4e847c28ab7449663...7b2dd9e723833ae6532cef4a4ff468d9895f3ae1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 10:31:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 06:31:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Prefer packed representation for CompiledByteCode Message-ID: <6615191c275c6_3f2cf420e1d7892959@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f8a90f17 by Fendor at 2024-04-09T06:31:41-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - 2db51264 by Alan Zimmerman at 2024-04-09T06:31:41-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 8 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/StgToByteCode.hs - testsuite/tests/printer/Test24533.hs - testsuite/tests/printer/Test24533.stdout Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -34,6 +34,7 @@ import GHC.Utils.Panic import GHC.Core.TyCon import GHC.Data.FastString +import GHC.Data.FlatBag import GHC.Data.SizedSeq import GHC.StgToCmm.Layout ( ArgRep(..) ) @@ -90,7 +91,7 @@ bcoFreeNames bco assembleBCOs :: Interp -> Profile - -> [ProtoBCO Name] + -> FlatBag (ProtoBCO Name) -> [TyCon] -> AddrEnv -> Maybe ModBreaks @@ -129,7 +130,7 @@ assembleBCOs interp profile proto_bcos tycons top_strs modbreaks = do -- top-level string literal bindings] in GHC.StgToByteCode for some discussion -- about why. -- -mallocStrings :: Interp -> [UnlinkedBCO] -> IO [UnlinkedBCO] +mallocStrings :: Interp -> FlatBag UnlinkedBCO -> IO (FlatBag UnlinkedBCO) mallocStrings interp ulbcos = do let bytestrings = reverse (execState (mapM_ collect ulbcos) []) ptrs <- interpCmd interp (MallocStrings bytestrings) @@ -170,7 +171,7 @@ assembleOneBCO interp profile pbco = do -- TODO: the profile should be bundled with the interpreter: the rts ways are -- fixed for an interpreter ubco <- assembleBCO (profilePlatform profile) pbco - [ubco'] <- mallocStrings interp [ubco] + UnitFlatBag ubco' <- mallocStrings interp (UnitFlatBag ubco) return ubco' assembleBCO :: Platform -> ProtoBCO Name -> IO UnlinkedBCO ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -54,7 +54,7 @@ import Language.Haskell.Syntax.Module.Name (ModuleName) -- Compiled Byte Code data CompiledByteCode = CompiledByteCode - { bc_bcos :: [UnlinkedBCO] -- Bunch of interpretable bindings + { bc_bcos :: FlatBag UnlinkedBCO -- Bunch of interpretable bindings , bc_itbls :: ItblEnv -- A mapping from DataCons to their itbls , bc_ffis :: [FFIInfo] -- ffi blocks we allocated , bc_strs :: AddrEnv -- malloc'd top-level strings @@ -66,7 +66,7 @@ newtype FFIInfo = FFIInfo (RemotePtr C_ffi_cif) deriving (Show, NFData) instance Outputable CompiledByteCode where - ppr CompiledByteCode{..} = ppr bc_bcos + ppr CompiledByteCode{..} = ppr $ elemsFlatBag bc_bcos -- Not a real NFData instance, because ModBreaks contains some things -- we can't rnf ===================================== compiler/GHC/Data/FlatBag.hs ===================================== @@ -1,6 +1,6 @@ {-# LANGUAGE UnboxedTuples #-} module GHC.Data.FlatBag - ( FlatBag + ( FlatBag(EmptyFlatBag, UnitFlatBag, TupleFlatBag) , emptyFlatBag , unitFlatBag , sizeFlatBag ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -92,6 +92,7 @@ import Control.Monad import qualified Data.Set as Set import Data.Char (isSpace) +import qualified Data.Foldable as Foldable import Data.IORef import Data.List (intercalate, isPrefixOf, nub, partition) import Data.Maybe @@ -923,7 +924,8 @@ linkSomeBCOs :: Interp linkSomeBCOs interp le mods = foldr fun do_link mods [] where - fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) + fun CompiledByteCode{..} inner accum = + inner (Foldable.toList bc_bcos : accum) do_link [] = return [] do_link mods = do ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -942,11 +942,10 @@ checkTyVars pp_what equals_or_where tc tparms -- Keep around an action for adjusting the annotations of extra parens chkParens :: [AddEpAnn] -> [AddEpAnn] -> HsBndrVis GhcPs -> LHsType GhcPs -> P (LHsTyVarBndr (HsBndrVis GhcPs) GhcPs) - chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) + chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) = let (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - lcs = epAnnComments l - lt' = setCommentsEpAnn lt lcs + (_,lt') = transferCommentsOnlyA l lt in chkParens (o:ops) (c:cps) bvis (L lt' ty) chkParens ops cps bvis ty = chk ops cps bvis ty @@ -1053,7 +1052,7 @@ checkTyClHdr :: Bool -- True <=> class header checkTyClHdr is_cls ty = goL ty [] [] [] Prefix where - goL (L l ty) acc ops cps fix = go (locA l) ty acc ops cps fix + goL (L l ty) acc ops cps fix = go l ty acc ops cps fix -- workaround to define '*' despite StarIsType go ll (HsParTy an (L l (HsStarTy _ isUni))) acc ops' cps' fix @@ -1071,11 +1070,11 @@ checkTyClHdr is_cls ty rhs = HsValArg noExtField t2 go l (HsParTy _ ty) acc ops cps fix = goL ty acc (o:ops) (c:cps) fix where - (o,c) = mkParensEpAnn (realSrcSpan l) + (o,c) = mkParensEpAnn (realSrcSpan (locA l)) go _ (HsAppTy _ t1 t2) acc ops cps fix = goL t1 (HsValArg noExtField t2:acc) ops cps fix go _ (HsAppKindTy at ty ki) acc ops cps fix = goL ty (HsTypeArg at ki:acc) ops cps fix go l (HsTupleTy _ HsBoxedOrConstraintTuple ts) [] ops cps fix - = return (L (noAnnSrcSpan l) (nameRdrName tup_name) + = return (L (l2l l) (nameRdrName tup_name) , map (HsValArg noExtField) ts, fix, (reverse ops)++cps) where arity = length ts @@ -1083,17 +1082,17 @@ checkTyClHdr is_cls ty | otherwise = getName (tupleTyCon Boxed arity) -- See Note [Unit tuples] in GHC.Hs.Type (TODO: is this still relevant?) go l _ _ _ _ _ - = addFatalError $ mkPlainErrorMsgEnvelope l $ + = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ (PsErrMalformedTyOrClDecl ty) -- Combine the annotations from the HsParTy and HsStarTy into a -- new one for the LocatedN RdrName - newAnns :: SrcSpan -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN - newAnns l (EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = + newAnns :: SrcSpanAnnA -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN + newAnns l@(EpAnn _ (AnnListItem _) csp0) l1@(EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = let - lr = combineSrcSpans (RealSrcSpan (anchor ap) Strict.Nothing) l + lr = combineSrcSpans (locA l1) (locA l) in - EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) csp + EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) (csp0 Semi.<> csp) -- | Yield a parse error if we have a function applied directly to a do block -- etc. and BlockArguments is not enabled. ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -63,6 +63,7 @@ import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, idPrimRepU, import GHC.StgToCmm.Layout import GHC.Runtime.Heap.Layout hiding (WordOff, ByteOff, wordsToBytes) import GHC.Data.Bitmap +import GHC.Data.FlatBag as FlatBag import GHC.Data.OrdList import GHC.Data.Maybe import GHC.Types.Name.Env (mkNameEnv) @@ -119,14 +120,14 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks (BcM_State{..}, proto_bcos) <- runBc hsc_env this_mod mb_modBreaks $ do let flattened_binds = concatMap flattenBind (reverse lifted_binds) - mapM schemeTopBind flattened_binds + FlatBag.fromList (fromIntegral $ length flattened_binds) <$> mapM schemeTopBind flattened_binds when (notNull ffis) (panic "GHC.StgToByteCode.byteCodeGen: missing final emitBc?") putDumpFileMaybe logger Opt_D_dump_BCOs "Proto-BCOs" FormatByteCode - (vcat (intersperse (char ' ') (map ppr proto_bcos))) + (vcat (intersperse (char ' ') (map ppr $ elemsFlatBag proto_bcos))) cbc <- assembleBCOs interp profile proto_bcos tycs stringPtrs (case modBreaks of ===================================== testsuite/tests/printer/Test24533.hs ===================================== @@ -7,7 +7,9 @@ instance ) => Read (a, b) -class Foo (a :: Type {- Weird -}) +{- Weird before -} +class {- Weird0 -} Foo {- Weird1 -} ({- Weird2 -} a {- Weird3 -} :: {- Weird4 -} Type {- Weird5 -}) {- Weird6 -} +{- Weird after -} instance Eq Foo where -- Weird ===================================== testsuite/tests/printer/Test24533.stdout ===================================== @@ -13,8 +13,8 @@ [] (Just ((,) - { Test24533.hs:15:1 } - { Test24533.hs:14:16-19 }))) + { Test24533.hs:17:1 } + { Test24533.hs:16:16-19 }))) (EpaCommentsBalanced [(L (EpaSpan @@ -276,22 +276,42 @@ (Nothing))))) ,(L (EpAnn - (EpaSpan { Test24533.hs:10:1-33 }) + (EpaSpan { Test24533.hs:11:1-99 }) (AnnListItem []) (EpaComments - [])) + [(L + (EpaSpan + { Test24533.hs:10:1-18 }) + (EpaComment + (EpaBlockComment + "{- Weird before -}") + { Test24533.hs:8:13 })) + ,(L + (EpaSpan + { Test24533.hs:11:7-18 }) + (EpaComment + (EpaBlockComment + "{- Weird0 -}") + { Test24533.hs:11:1-5 })) + ,(L + (EpaSpan + { Test24533.hs:11:24-35 }) + (EpaComment + (EpaBlockComment + "{- Weird1 -}") + { Test24533.hs:11:20-22 }))])) (TyClD (NoExtField) (ClassDecl ((,,) - [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:10:1-5 }))] + [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:11:1-5 }))] (EpNoLayout) (NoAnnSortKey)) (Nothing) (L (EpAnn - (EpaSpan { Test24533.hs:10:7-9 }) + (EpaSpan { Test24533.hs:11:20-22 }) (NameAnnTrailing []) (EpaComments @@ -302,26 +322,47 @@ (NoExtField) [(L (EpAnn - (EpaSpan { Test24533.hs:10:11-33 }) + (EpaSpan { Test24533.hs:11:37-99 }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:10:22-32 }) + { Test24533.hs:11:38-49 }) + (EpaComment + (EpaBlockComment + "{- Weird2 -}") + { Test24533.hs:11:37 })) + ,(L + (EpaSpan + { Test24533.hs:11:87-98 }) (EpaComment (EpaBlockComment - "{- Weird -}") - { Test24533.hs:10:17-20 }))])) + "{- Weird5 -}") + { Test24533.hs:11:82-85 })) + ,(L + (EpaSpan + { Test24533.hs:11:53-64 }) + (EpaComment + (EpaBlockComment + "{- Weird3 -}") + { Test24533.hs:11:51 })) + ,(L + (EpaSpan + { Test24533.hs:11:69-80 }) + (EpaComment + (EpaBlockComment + "{- Weird4 -}") + { Test24533.hs:11:66-67 }))])) (KindedTyVar - [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:10:11 })) - ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:10:33 })) - ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:10:14-15 }))] + [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:11:37 })) + ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:11:99 })) + ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:11:66-67 }))] (HsBndrRequired (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:10:12 }) + (EpaSpan { Test24533.hs:11:51 }) (NameAnnTrailing []) (EpaComments @@ -330,7 +371,7 @@ {OccName: a})) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (AnnListItem []) (EpaComments @@ -340,7 +381,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (NameAnnTrailing []) (EpaComments @@ -357,17 +398,31 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:(12,1)-(14,19) }) + (EpaSpan { Test24533.hs:(14,1)-(16,19) }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:13:3-10 }) + { Test24533.hs:15:3-10 }) (EpaComment (EpaLineComment "-- Weird") - { Test24533.hs:12:17-21 }))])) + { Test24533.hs:14:17-21 })) + ,(L + (EpaSpan + { Test24533.hs:11:101-112 }) + (EpaComment + (EpaBlockComment + "{- Weird6 -}") + { Test24533.hs:11:99 })) + ,(L + (EpaSpan + { Test24533.hs:12:1-17 }) + (EpaComment + (EpaBlockComment + "{- Weird after -}") + { Test24533.hs:11:101-112 }))])) (InstD (NoExtField) (ClsInstD @@ -375,12 +430,12 @@ (ClsInstDecl ((,,) (Nothing) - [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:12:1-8 })) - ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:12:17-21 }))] + [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:14:1-8 })) + ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:14:17-21 }))] (NoAnnSortKey)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -391,7 +446,7 @@ (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -400,7 +455,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (AnnListItem []) (EpaComments @@ -410,7 +465,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (NameAnnTrailing []) (EpaComments @@ -419,7 +474,7 @@ {OccName: Eq})))) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (AnnListItem []) (EpaComments @@ -429,7 +484,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (NameAnnTrailing []) (EpaComments @@ -439,7 +494,7 @@ {Bag(LocatedA (HsBind GhcPs)): [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -448,7 +503,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -459,7 +514,7 @@ (FromSource) (L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnList (Nothing) (Nothing) @@ -470,7 +525,7 @@ [])) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -480,7 +535,7 @@ (FunRhs (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -491,7 +546,7 @@ (NoSrcStrict)) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (AnnListItem []) (EpaComments @@ -500,7 +555,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (NameAnnTrailing []) (EpaComments @@ -512,7 +567,7 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (AnnListItem []) (EpaComments @@ -521,7 +576,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (NameAnnTrailing []) (EpaComments @@ -536,22 +591,22 @@ []) [(L (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (NoEpAnns) (EpaComments [])) (GRHS (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (GrhsAnn (Nothing) - (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:14:14 }))) + (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:16:14 }))) (EpaComments [])) [] (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (AnnListItem []) (EpaComments @@ -560,7 +615,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (NameAnnTrailing []) (EpaComments View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5bcbb4d9027438a77a0befd265a269be3b7c4c53...2db51264f9ae91845953563879b1935c408fc1cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5bcbb4d9027438a77a0befd265a269be3b7c4c53...2db51264f9ae91845953563879b1935c408fc1cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 10:48:45 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 09 Apr 2024 06:48:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mpickering-triemap Message-ID: <66151d0d50d37_3f2cf423ac418983ae@gitlab.mail> Matthew Pickering pushed new branch wip/mpickering-triemap at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mpickering-triemap You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 11:02:01 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 09 Apr 2024 07:02:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/mi_extra_decls_lazy_put_get Message-ID: <661520295d01a_3f2cf42547610985d6@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/mi_extra_decls_lazy_put_get at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/mi_extra_decls_lazy_put_get You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 12:52:21 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 08:52:21 -0400 Subject: [Git][ghc/ghc][master] Prefer packed representation for CompiledByteCode Message-ID: <66153a0515c60_286d75747a34107540@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - 5 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/StgToByteCode.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -34,6 +34,7 @@ import GHC.Utils.Panic import GHC.Core.TyCon import GHC.Data.FastString +import GHC.Data.FlatBag import GHC.Data.SizedSeq import GHC.StgToCmm.Layout ( ArgRep(..) ) @@ -90,7 +91,7 @@ bcoFreeNames bco assembleBCOs :: Interp -> Profile - -> [ProtoBCO Name] + -> FlatBag (ProtoBCO Name) -> [TyCon] -> AddrEnv -> Maybe ModBreaks @@ -129,7 +130,7 @@ assembleBCOs interp profile proto_bcos tycons top_strs modbreaks = do -- top-level string literal bindings] in GHC.StgToByteCode for some discussion -- about why. -- -mallocStrings :: Interp -> [UnlinkedBCO] -> IO [UnlinkedBCO] +mallocStrings :: Interp -> FlatBag UnlinkedBCO -> IO (FlatBag UnlinkedBCO) mallocStrings interp ulbcos = do let bytestrings = reverse (execState (mapM_ collect ulbcos) []) ptrs <- interpCmd interp (MallocStrings bytestrings) @@ -170,7 +171,7 @@ assembleOneBCO interp profile pbco = do -- TODO: the profile should be bundled with the interpreter: the rts ways are -- fixed for an interpreter ubco <- assembleBCO (profilePlatform profile) pbco - [ubco'] <- mallocStrings interp [ubco] + UnitFlatBag ubco' <- mallocStrings interp (UnitFlatBag ubco) return ubco' assembleBCO :: Platform -> ProtoBCO Name -> IO UnlinkedBCO ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -54,7 +54,7 @@ import Language.Haskell.Syntax.Module.Name (ModuleName) -- Compiled Byte Code data CompiledByteCode = CompiledByteCode - { bc_bcos :: [UnlinkedBCO] -- Bunch of interpretable bindings + { bc_bcos :: FlatBag UnlinkedBCO -- Bunch of interpretable bindings , bc_itbls :: ItblEnv -- A mapping from DataCons to their itbls , bc_ffis :: [FFIInfo] -- ffi blocks we allocated , bc_strs :: AddrEnv -- malloc'd top-level strings @@ -66,7 +66,7 @@ newtype FFIInfo = FFIInfo (RemotePtr C_ffi_cif) deriving (Show, NFData) instance Outputable CompiledByteCode where - ppr CompiledByteCode{..} = ppr bc_bcos + ppr CompiledByteCode{..} = ppr $ elemsFlatBag bc_bcos -- Not a real NFData instance, because ModBreaks contains some things -- we can't rnf ===================================== compiler/GHC/Data/FlatBag.hs ===================================== @@ -1,6 +1,6 @@ {-# LANGUAGE UnboxedTuples #-} module GHC.Data.FlatBag - ( FlatBag + ( FlatBag(EmptyFlatBag, UnitFlatBag, TupleFlatBag) , emptyFlatBag , unitFlatBag , sizeFlatBag ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -92,6 +92,7 @@ import Control.Monad import qualified Data.Set as Set import Data.Char (isSpace) +import qualified Data.Foldable as Foldable import Data.IORef import Data.List (intercalate, isPrefixOf, nub, partition) import Data.Maybe @@ -923,7 +924,8 @@ linkSomeBCOs :: Interp linkSomeBCOs interp le mods = foldr fun do_link mods [] where - fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) + fun CompiledByteCode{..} inner accum = + inner (Foldable.toList bc_bcos : accum) do_link [] = return [] do_link mods = do ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -63,6 +63,7 @@ import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, idPrimRepU, import GHC.StgToCmm.Layout import GHC.Runtime.Heap.Layout hiding (WordOff, ByteOff, wordsToBytes) import GHC.Data.Bitmap +import GHC.Data.FlatBag as FlatBag import GHC.Data.OrdList import GHC.Data.Maybe import GHC.Types.Name.Env (mkNameEnv) @@ -119,14 +120,14 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks (BcM_State{..}, proto_bcos) <- runBc hsc_env this_mod mb_modBreaks $ do let flattened_binds = concatMap flattenBind (reverse lifted_binds) - mapM schemeTopBind flattened_binds + FlatBag.fromList (fromIntegral $ length flattened_binds) <$> mapM schemeTopBind flattened_binds when (notNull ffis) (panic "GHC.StgToByteCode.byteCodeGen: missing final emitBc?") putDumpFileMaybe logger Opt_D_dump_BCOs "Proto-BCOs" FormatByteCode - (vcat (intersperse (char ' ') (map ppr proto_bcos))) + (vcat (intersperse (char ' ') (map ppr $ elemsFlatBag proto_bcos))) cbc <- assembleBCOs interp profile proto_bcos tycs stringPtrs (case modBreaks of View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/868c8a78432459dc2821f1ce70c9a97f7fb31394 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/868c8a78432459dc2821f1ce70c9a97f7fb31394 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 12:53:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 08:53:00 -0400 Subject: [Git][ghc/ghc][master] EPA: Capture all comments in a ClassDecl Message-ID: <66153a2cddd3a_286d758ec9841108a5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3 changed files: - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Test24533.hs - testsuite/tests/printer/Test24533.stdout Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -942,11 +942,10 @@ checkTyVars pp_what equals_or_where tc tparms -- Keep around an action for adjusting the annotations of extra parens chkParens :: [AddEpAnn] -> [AddEpAnn] -> HsBndrVis GhcPs -> LHsType GhcPs -> P (LHsTyVarBndr (HsBndrVis GhcPs) GhcPs) - chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) + chkParens ops cps bvis (L l (HsParTy _ (L lt ty))) = let (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - lcs = epAnnComments l - lt' = setCommentsEpAnn lt lcs + (_,lt') = transferCommentsOnlyA l lt in chkParens (o:ops) (c:cps) bvis (L lt' ty) chkParens ops cps bvis ty = chk ops cps bvis ty @@ -1053,7 +1052,7 @@ checkTyClHdr :: Bool -- True <=> class header checkTyClHdr is_cls ty = goL ty [] [] [] Prefix where - goL (L l ty) acc ops cps fix = go (locA l) ty acc ops cps fix + goL (L l ty) acc ops cps fix = go l ty acc ops cps fix -- workaround to define '*' despite StarIsType go ll (HsParTy an (L l (HsStarTy _ isUni))) acc ops' cps' fix @@ -1071,11 +1070,11 @@ checkTyClHdr is_cls ty rhs = HsValArg noExtField t2 go l (HsParTy _ ty) acc ops cps fix = goL ty acc (o:ops) (c:cps) fix where - (o,c) = mkParensEpAnn (realSrcSpan l) + (o,c) = mkParensEpAnn (realSrcSpan (locA l)) go _ (HsAppTy _ t1 t2) acc ops cps fix = goL t1 (HsValArg noExtField t2:acc) ops cps fix go _ (HsAppKindTy at ty ki) acc ops cps fix = goL ty (HsTypeArg at ki:acc) ops cps fix go l (HsTupleTy _ HsBoxedOrConstraintTuple ts) [] ops cps fix - = return (L (noAnnSrcSpan l) (nameRdrName tup_name) + = return (L (l2l l) (nameRdrName tup_name) , map (HsValArg noExtField) ts, fix, (reverse ops)++cps) where arity = length ts @@ -1083,17 +1082,17 @@ checkTyClHdr is_cls ty | otherwise = getName (tupleTyCon Boxed arity) -- See Note [Unit tuples] in GHC.Hs.Type (TODO: is this still relevant?) go l _ _ _ _ _ - = addFatalError $ mkPlainErrorMsgEnvelope l $ + = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ (PsErrMalformedTyOrClDecl ty) -- Combine the annotations from the HsParTy and HsStarTy into a -- new one for the LocatedN RdrName - newAnns :: SrcSpan -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN - newAnns l (EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = + newAnns :: SrcSpanAnnA -> SrcSpanAnnA -> AnnParen -> SrcSpanAnnN + newAnns l@(EpAnn _ (AnnListItem _) csp0) l1@(EpAnn ap (AnnListItem ta) csp) (AnnParen _ o c) = let - lr = combineSrcSpans (RealSrcSpan (anchor ap) Strict.Nothing) l + lr = combineSrcSpans (locA l1) (locA l) in - EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) csp + EpAnn (EpaSpan lr) (NameAnn NameParens o ap c ta) (csp0 Semi.<> csp) -- | Yield a parse error if we have a function applied directly to a do block -- etc. and BlockArguments is not enabled. ===================================== testsuite/tests/printer/Test24533.hs ===================================== @@ -7,7 +7,9 @@ instance ) => Read (a, b) -class Foo (a :: Type {- Weird -}) +{- Weird before -} +class {- Weird0 -} Foo {- Weird1 -} ({- Weird2 -} a {- Weird3 -} :: {- Weird4 -} Type {- Weird5 -}) {- Weird6 -} +{- Weird after -} instance Eq Foo where -- Weird ===================================== testsuite/tests/printer/Test24533.stdout ===================================== @@ -13,8 +13,8 @@ [] (Just ((,) - { Test24533.hs:15:1 } - { Test24533.hs:14:16-19 }))) + { Test24533.hs:17:1 } + { Test24533.hs:16:16-19 }))) (EpaCommentsBalanced [(L (EpaSpan @@ -276,22 +276,42 @@ (Nothing))))) ,(L (EpAnn - (EpaSpan { Test24533.hs:10:1-33 }) + (EpaSpan { Test24533.hs:11:1-99 }) (AnnListItem []) (EpaComments - [])) + [(L + (EpaSpan + { Test24533.hs:10:1-18 }) + (EpaComment + (EpaBlockComment + "{- Weird before -}") + { Test24533.hs:8:13 })) + ,(L + (EpaSpan + { Test24533.hs:11:7-18 }) + (EpaComment + (EpaBlockComment + "{- Weird0 -}") + { Test24533.hs:11:1-5 })) + ,(L + (EpaSpan + { Test24533.hs:11:24-35 }) + (EpaComment + (EpaBlockComment + "{- Weird1 -}") + { Test24533.hs:11:20-22 }))])) (TyClD (NoExtField) (ClassDecl ((,,) - [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:10:1-5 }))] + [(AddEpAnn AnnClass (EpaSpan { Test24533.hs:11:1-5 }))] (EpNoLayout) (NoAnnSortKey)) (Nothing) (L (EpAnn - (EpaSpan { Test24533.hs:10:7-9 }) + (EpaSpan { Test24533.hs:11:20-22 }) (NameAnnTrailing []) (EpaComments @@ -302,26 +322,47 @@ (NoExtField) [(L (EpAnn - (EpaSpan { Test24533.hs:10:11-33 }) + (EpaSpan { Test24533.hs:11:37-99 }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:10:22-32 }) + { Test24533.hs:11:38-49 }) + (EpaComment + (EpaBlockComment + "{- Weird2 -}") + { Test24533.hs:11:37 })) + ,(L + (EpaSpan + { Test24533.hs:11:87-98 }) (EpaComment (EpaBlockComment - "{- Weird -}") - { Test24533.hs:10:17-20 }))])) + "{- Weird5 -}") + { Test24533.hs:11:82-85 })) + ,(L + (EpaSpan + { Test24533.hs:11:53-64 }) + (EpaComment + (EpaBlockComment + "{- Weird3 -}") + { Test24533.hs:11:51 })) + ,(L + (EpaSpan + { Test24533.hs:11:69-80 }) + (EpaComment + (EpaBlockComment + "{- Weird4 -}") + { Test24533.hs:11:66-67 }))])) (KindedTyVar - [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:10:11 })) - ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:10:33 })) - ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:10:14-15 }))] + [(AddEpAnn AnnOpenP (EpaSpan { Test24533.hs:11:37 })) + ,(AddEpAnn AnnCloseP (EpaSpan { Test24533.hs:11:99 })) + ,(AddEpAnn AnnDcolon (EpaSpan { Test24533.hs:11:66-67 }))] (HsBndrRequired (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:10:12 }) + (EpaSpan { Test24533.hs:11:51 }) (NameAnnTrailing []) (EpaComments @@ -330,7 +371,7 @@ {OccName: a})) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (AnnListItem []) (EpaComments @@ -340,7 +381,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:10:17-20 }) + (EpaSpan { Test24533.hs:11:82-85 }) (NameAnnTrailing []) (EpaComments @@ -357,17 +398,31 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:(12,1)-(14,19) }) + (EpaSpan { Test24533.hs:(14,1)-(16,19) }) (AnnListItem []) (EpaComments [(L (EpaSpan - { Test24533.hs:13:3-10 }) + { Test24533.hs:15:3-10 }) (EpaComment (EpaLineComment "-- Weird") - { Test24533.hs:12:17-21 }))])) + { Test24533.hs:14:17-21 })) + ,(L + (EpaSpan + { Test24533.hs:11:101-112 }) + (EpaComment + (EpaBlockComment + "{- Weird6 -}") + { Test24533.hs:11:99 })) + ,(L + (EpaSpan + { Test24533.hs:12:1-17 }) + (EpaComment + (EpaBlockComment + "{- Weird after -}") + { Test24533.hs:11:101-112 }))])) (InstD (NoExtField) (ClsInstD @@ -375,12 +430,12 @@ (ClsInstDecl ((,,) (Nothing) - [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:12:1-8 })) - ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:12:17-21 }))] + [(AddEpAnn AnnInstance (EpaSpan { Test24533.hs:14:1-8 })) + ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:14:17-21 }))] (NoAnnSortKey)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -391,7 +446,7 @@ (NoExtField)) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-15 }) + (EpaSpan { Test24533.hs:14:10-15 }) (AnnListItem []) (EpaComments @@ -400,7 +455,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (AnnListItem []) (EpaComments @@ -410,7 +465,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:10-11 }) + (EpaSpan { Test24533.hs:14:10-11 }) (NameAnnTrailing []) (EpaComments @@ -419,7 +474,7 @@ {OccName: Eq})))) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (AnnListItem []) (EpaComments @@ -429,7 +484,7 @@ (NotPromoted) (L (EpAnn - (EpaSpan { Test24533.hs:12:13-15 }) + (EpaSpan { Test24533.hs:14:13-15 }) (NameAnnTrailing []) (EpaComments @@ -439,7 +494,7 @@ {Bag(LocatedA (HsBind GhcPs)): [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -448,7 +503,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -459,7 +514,7 @@ (FromSource) (L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnList (Nothing) (Nothing) @@ -470,7 +525,7 @@ [])) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-19 }) + (EpaSpan { Test24533.hs:16:3-19 }) (AnnListItem []) (EpaComments @@ -480,7 +535,7 @@ (FunRhs (L (EpAnn - (EpaSpan { Test24533.hs:14:7-8 }) + (EpaSpan { Test24533.hs:16:7-8 }) (NameAnnTrailing []) (EpaComments @@ -491,7 +546,7 @@ (NoSrcStrict)) [(L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (AnnListItem []) (EpaComments @@ -500,7 +555,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:3-5 }) + (EpaSpan { Test24533.hs:16:3-5 }) (NameAnnTrailing []) (EpaComments @@ -512,7 +567,7 @@ []))) ,(L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (AnnListItem []) (EpaComments @@ -521,7 +576,7 @@ [] (L (EpAnn - (EpaSpan { Test24533.hs:14:10-12 }) + (EpaSpan { Test24533.hs:16:10-12 }) (NameAnnTrailing []) (EpaComments @@ -536,22 +591,22 @@ []) [(L (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (NoEpAnns) (EpaComments [])) (GRHS (EpAnn - (EpaSpan { Test24533.hs:14:14-19 }) + (EpaSpan { Test24533.hs:16:14-19 }) (GrhsAnn (Nothing) - (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:14:14 }))) + (AddEpAnn AnnEqual (EpaSpan { Test24533.hs:16:14 }))) (EpaComments [])) [] (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (AnnListItem []) (EpaComments @@ -560,7 +615,7 @@ (NoExtField) (L (EpAnn - (EpaSpan { Test24533.hs:14:16-19 }) + (EpaSpan { Test24533.hs:16:16-19 }) (NameAnnTrailing []) (EpaComments View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be3bdddebdf119007d753bebe32709a1ce726cc0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be3bdddebdf119007d753bebe32709a1ce726cc0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 14:48:02 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 09 Apr 2024 10:48:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t24631 Message-ID: <66155522348a6_3eb5a296cea4144516@gitlab.mail> Matthew Pickering pushed new branch wip/t24631 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t24631 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 15:03:29 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 09 Apr 2024 11:03:29 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mpickering-iface-tests Message-ID: <661558c1ca398_3eb5a2c4d03816267e@gitlab.mail> Matthew Pickering pushed new branch wip/mpickering-iface-tests at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mpickering-iface-tests You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 15:14:32 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Tue, 09 Apr 2024 11:14:32 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] fixup! Make template-haskell a stage1 package Message-ID: <66155b586c245_1002b4dbc048136d@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 1f9392ad by Teo Camarasu at 2024-04-09T16:14:11+01:00 fixup! Make template-haskell a stage1 package - - - - - 1 changed file: - compiler/GHC/Tc/Gen/Splice.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2919,105 +2919,125 @@ tcGetInterp = do -- Note [Bootstrapping Template Haskell] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Template Haskell requires special attention when bootstrapping GHC. +-- The boot compiler (stage0) comes bundled with one version of +-- `template-haskell`. The bootstrap (stage1) compiler transitions to +-- using the in-tree version, which we distribute with our final compiler +-- (stage2). This is tricky because implementing Template Haskell requires cross +-- stage dependencies. We can divide Template Haskell into 3 capabilitie: +-- implementing running splices either using the internal interpreter, or the +-- external interpreter, and desugaring quote syntax. A splice (next stage) depends on the +-- interface of the `template-haskell` library (built in previous stage), which +-- must match the version built into the compiler, in order for that splice to +-- be runnable. The exposed interface includes the `Q` monad, the `Quasi` and +-- `Quote` typeclasses, and the TH AST. To desugar quote syntax, we use a sort +-- of late binding where we emit references to known-key definitions in +-- `GHC.Builtin.Names.TH` pointing to identifiers matching the in-tree library. -- --- Template Haskell requires special attention when compiling GHC. --- The implementation of the Template Haskell set of features requires tight --- coupling between the compiler and the `template-haskell` library. --- This complicates the bootstrapping story as compatibility constraints are --- placed on the version of `template-haskell` used to compile GHC during a --- particular stage and the version bundled with it. +-- In our current implementation we resolve these constraints by vendoring the +-- in-tree `template-haskell` library into the `ghc-boot` package while +-- compiling the stage1 compiler. This allows the stage1 compiler to depend on +-- the in-tree version of the interface without requiring the `template-haskell` +-- library to be built in stage0. -- --- These constraints can be divided by the features they are used to implement, --- namely running splices either directly or via the external interpreter, and --- desugaring bracket syntax. +-- Let's illustrate how Template Haskell works through an example. +-- Take the following code, which uses both quotes and splices. +-- > main = print $([|unwords ["hello", "world"]|]) -- --- (C1) Executing splices within the compiler: In order to execute a splice --- within the compiler, we must be able to compile and load code built against --- the same version of the `template-haskell` library as the compiler. This --- is an ABI compatibility constraint between the `template-haskell` version of --- the compiler and the splice. --- (C2) Executing splices through the external interpreter: In order to execute --- a splice via the external interpreter, we serialise bytecode, run it with the --- external interpreter, and communicate back the result through a binary --- serialised interface. This is a binary serialisation compatibilty constraint --- between the `template-haskell` version of the compiler and the splice. --- (C3) Desugaring bracket syntax: Bracket syntax is desugared by referring to a --- special wired-in package whose package id is `template-haskell`. So for --- instance an expression `'Just` gets desugared to something of type --- `template-haskell:Language.Haskell.TH.Syntax.Name`. Importantly, while this --- identifier is wired-in, the identity of the `template-haskell` package is --- not. So for instance we can successfully use an expression like --- `'Just :: Name` while compiling the `template-haskell` package as long as its --- package id is set to `template-haskell` as `Name` will resolve the the local --- identifier in the package (and the LHS and RHS will align). On the other --- hand, if we don't set the special package id, the type of the expression will --- be `template-haskell:...Name` while the `Name` on the RHS will resolve to the --- local identifier and we will get a type error. So, bracket syntax assumes the --- presence of a particular API in the `template-haskell` package, but it allows --- --- These constraints are ranked from strongest to weakest. They only apply if we --- want to support the particular feature associated with them. +-- The splice is run during renaming. This consists of the following steps. +-- 1. The quote is desugared becoming something equivalent to +-- `varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")]` +-- Notice we are introducing references to identifiers from the +-- `template-haskell` library. +-- This desguaring is implemented in `GHC.HsToCore.Quote.dsBracket`. +-- 2. The core expression of the quote is turned into bytecode. +-- 3. The bytecode is run in the interpreter. If we are using the internal +-- interpreter this is the `ghc` executable. If we are using the external +-- interpreter this is the `ghc-iserv` executable. +-- 4. Optionally the interpreter must load object code for packages mentioned in +-- the bytecode. In this instance that is just `template-haskell`. +-- 5. The bytecode is run. +-- 6. The result is a TH AST, which we convert back to a GHC AST using the +-- functions from `GHC.ThToHs`. -- --- The tricky case is what do to when building the bootstrapping (stage1) GHC. --- The stage2 GHC is simpler as it can use the in-tree `template-haskell` --- package built by the stage1 GHC. +-- At several points in the process different features required depending on the +-- `template-haskell` library. These constraints conditionally apply to any version of the +-- compiler that enables the relevant feature. -- --- We should note that we cannot feasibly use the internal interpreter with a --- stage1 GHC. This is because the stage1 GHC was compiled with the stage0 GHC, --- which we assume is a different version. In order to run a splice that too --- would need to be compiled with the stage0 GHC, and so would all its --- dependencies. --- This allows us to disregard (C1) for the stage1 case. +-- (C1) running a splice using the internal interpreter: if we run a splice by +-- loading the bytecode into the internal interpreter, then our compiler must be +-- linked against the same version of the `template-haskell` library as the +-- splice. For the stage2 compiler, this means a user splice (stage3) is linked +-- against the in-tree `template-haskell` library (stage1), which is the same +-- as what the stage2 compiler is linked against. +-- This constraint is introduced by step 4 and step 6. Usages of `reify` +-- functions from `Quasi` would also entail this constraint. If there were a +-- discrepancy between these two versions of `template-haskell`, for instance if +-- the splice's AST laccked the `StringE` constructor, then we would run into a +-- runtime or linker error. This constraint doesn't apply to the stage1 compiler +-- because we currently don't support using the internal interpreter at that +-- stage at all. -- --- In the past, we used to build the stage1 GHC and all its dependencies against --- the in-tree `template-haskell` library. This meant that we sacrificed (C2) --- because they are likely not serialisation compatible. We could not sacrifice --- (C3) because dependencies of GHC (such as `containers` and --- `template-haskell`) used bracket syntax to define `Lift` instances. This --- meant that the interface assumed by the boot compiler to implement bracket --- desugaring could not be modified (not even through CPP as (C1) would --- constrain us in future stages where we do support the internal interpreter). --- Yet, bracket syntax did work and gave us splices that desugared to code that --- referenced the in-tree version of `template-haskell` not the one the boot --- compiler required. So they could never be run. +-- (C2) running a splice using the external interpreter: if we run a splice by +-- loading the bytecode into the external interpreter, then our `iserv` +-- executable must be linked against the same version of the `template-haskell` +-- library as the splice. The compiler on the other hand only needs to be depend +-- on a binary serialisation that is compatible with `template-haskell` library. +-- This is a similar but weaker constraint on the compiler than the previous +-- one. It is possible to use this with the stage1 compiler by using an `iserv` +-- executable that is compiled against the stage1 `template-haskell` in-tree +-- library. If there is a discrepancy in the binary interface then we will run +-- into a runtime error if we fail to parse a message. -- --- Our current strategy is to not build `template-haskell` as a stage0 package. --- All of GHCs dependencies depend on the boot compilers version, and produce --- runnable splices. How do we deal with the stage1 compiler's dependency on --- `template-haskell`? There are two options. (D1) depend on the boot --- compiler's version for stage1 and then depend on the in-tree one in stage2. --- This violates (C1) and (C2), so we wouldn't be able to run splices at all --- with the stage1 compiler. Additionally this would introduce quite a bit of --- CPP into the compiler and mean we would have to stub out much of the --- template-haskell machinery or have an unrunable compatibilty shim. Or (D2) --- depend on the in-tree version. +-- (C3) desugaring quote syntax: the desugaring of quote syntax is hard coded +-- into each version of the compiler. `GHC.Builtin.Names.TH` declares many names +-- as known-key, inducing a coupling relationship quite to that of `ghc-internal`. +-- This is so that quotes can be desugared to calls to TH AST (smart) +-- constructors and uses of the Lift type class. +-- Furthermore, name quotes such as `'Just` are resolved relative to the module +-- under compilation and then desugar to a +-- `template-haskell:Language.Haskell.TH.Syntax.Name`, where the exact location +-- is determined by `GHC.Builtin.Names.TH`. This location must match the +-- `template-haskell` library against which the quote is linked. +-- This implements a sort of late binding, where identifiers will be mapped to +-- whatever package called `template-haskell` is in scope. +-- The late binding makes it possible to use quotes while compiling the +-- `template-haskell` library itself as identifiers will correctly be mapped to +-- the current package, rather than the one from the previous stage. +-- If we attempt to use quotes, but don't have a `template-haskell` package in +-- the package db with the appropriate interface we will run into type errors. +-- For instance if it lacked the `varE` function or had a function with the +-- wrong arity, then we would encounter an error when a module using the quote +-- is compiled. -- --- (D2) is what we implement, but it is complicated by the fact that it means we --- practically have two versions of `template-haskell` in the dependency graph --- of the stage1 compiler. To avoid this, we recall that we only need --- serliasation compatibility (as per (C2)), so we can avoid a direct dependency --- on the in-tree version by vendoring it. We choose to vendor it into the --- `ghc-boot` package as both `lib:ghc` and `ghci` require a dependency on the --- `template-haskell` interface as they define the two ends of the protocol. --- This allows us to still run splices through the external interpreter. +-- These 3 constraints inform our implementation strategy when building the +-- stage1 compiler. We are making use of the stage0 compiler, so if we want to +-- keep the possibility of using Template Haskell in the bootstrapping process +-- open (#22069), then our package DB must contain the `template-haskell` +-- library that our stage0 compiler is linked against (C1-3). +-- Yet, for the stage1 compiler, (C1) doesn't apply as we cannot use the +-- internal interpreter. We do not need to link the stage1 compiler against +-- the exact same `template-haskell` library that user splices compiled using +-- the stage1 compiler will need to use. Therefore, we vendor the modules from +-- the in-tree `template-haskell` library into the `ghc-boot` package. As a +-- common dependency of both, this allows the `ghc` and `ghci` libraries to +-- depend on the interface and serialisation from the in-tree `template-haskell` +-- library. This comes with a trade-off: we cannot make use of quotes while +-- compiling these modules as the identifiers would resolve to reflect the +-- stage0 compiler's expected structure (C3). -- --- We should note a futher edge-case with this approach. When compiling our --- vendored `template-haskell` library, we run afoul of (C3). The library --- defines several `Name`s using bracket syntax. As this package doesn't claim --- to be the wired-in package but it defines its own `Name` type, we get a type --- discrepancy with the `Name` type from the boot compiler's `template-haskell` --- library. Most of these are only used to define `Lift` instances, so in the --- vendored case we simply hide them behind CPP. Yet, there is one distinct use --- of a `Name`. We have a `Name` for the constructors of the `Multiplicity` --- type, which are also used in the pretty-printing module. We construct these --- manulally instead. This allows us to completely avoid using bracket syntax --- for compiling the vendored `template-haskell` package. +-- Then the stage1 compiler is used to compile the in-tree `template-haskell` +-- library, which is linked into the stage2 compiler and distributed alongside +-- it. -- --- To summarise, our current approach allows us to use the external interpreter --- to run splices and allows bracket syntax to be desugared correctly. In order --- to implement this we vendor the `template-haskell` library into `ghc-boot` --- and take special care to not use bracket syntax in those modules as that --- would incorrectly produce code that uses identifiers from the boot compiler's --- `template-haskell` library. +-- Historically, we used to build the in-tree `template-haskell` library in +-- stage0. This meant that qoutes would resolve to splices that couldn't be run +-- by the stage0 compiler (C1-2), eg, the in-tree library might contain a new +-- constructor the stage0 compiler wasn't aware of. It also made it difficult to +-- refactor the `template-haskell` library as it needed to be conservative with +-- regard to the identifiers the stage0 compiler was expecting in order to +-- desugar quotes (C3). See #23536. -- --- See #23536. +-- The current setup allows both stage0 and stage2 to use the full gamut of +-- Template Haskell functionality, while stage1 can use all but the internal +-- interpreter to run splices. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f9392adfba41999c47bc632379f101bef7d9eed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f9392adfba41999c47bc632379f101bef7d9eed You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 15:19:39 2024 From: gitlab at gitlab.haskell.org (Finley McIlwaine (@FinleyMcIlwaine)) Date: Tue, 09 Apr 2024 11:19:39 -0400 Subject: [Git][ghc/ghc][wip/t24277] 189 commits: add -fprof-late-overloaded and -fprof-late-overloaded-calls Message-ID: <66155c8b907a9_1002b42841a083893@gitlab.mail> Finley McIlwaine pushed to branch wip/t24277 at Glasgow Haskell Compiler / GHC Commits: 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 18ade573 by Finley McIlwaine at 2024-04-08T16:05:14-07:00 base: Add CostCentreId, currentCallStackIds, ccsToIds, ccId Add functions for gettings the IDs of cost centres to the interface of `GHC.Stack`, `GHC.Stack.CCS`, and `GHC.Exts`. Also add an opaque type for cost center ids, `CostCentreId`, with appropriate instances. Implements CLC proposal 235. Resolves #24277 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC.hs - + compiler/GHC/Core/LateCC/OverloadedCalls.hs - + compiler/GHC/Core/LateCC/TopLevelBinds.hs - + compiler/GHC/Core/LateCC/Types.hs - + compiler/GHC/Core/LateCC/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0f9cb82b786a7007604a6abcc3b603f56458393...18ade57396eaa7e6bf0b4c053c25e6c932e034ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0f9cb82b786a7007604a6abcc3b603f56458393...18ade57396eaa7e6bf0b4c053c25e6c932e034ce You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 15:24:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 11:24:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Prefer packed representation for CompiledByteCode Message-ID: <66155dbd5139b_1002b43f512485740@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - dbe5c833 by Rodrigo Mesquita at 2024-04-09T11:24:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - a4b6d693 by Alexis King at 2024-04-09T11:24:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 75802c3a by Rodrigo Mesquita at 2024-04-09T11:24:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 4a43cfbe by Rodrigo Mesquita at 2024-04-09T11:24:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - f01c44dd by Ben Gamari at 2024-04-09T11:24:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 5587bb5d by Zejun Wu at 2024-04-09T11:24:34-04:00 Make renamer to be more flexible with parens in the LHS of the rules We used to reject LHS like `(f a) b` in RULES and requires it to be written as `f a b`. It will be handy to allow both as the expression may be more readable with extra parens in some cases when infix operator is involved. Espceially when TemplateHaskell is used, extra parens may be added out of user's control and result in "valid" rules being rejected and there are not always ways to workaround it. Fixes #24621 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToByteCode.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2db51264f9ae91845953563879b1935c408fc1cb...5587bb5d8a28c19f08a7439d155212cf82702aeb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2db51264f9ae91845953563879b1935c408fc1cb...5587bb5d8a28c19f08a7439d155212cf82702aeb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 16:30:19 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 09 Apr 2024 12:30:19 -0400 Subject: [Git][ghc/ghc][wip/T23109] 22 commits: testsuite: Introduce template-haskell-exports test Message-ID: <66156d1bb4ec2_1002b4b8ee58111668@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 69671b6e by Simon Peyton Jones at 2024-04-09T17:30:05+01:00 Make newtype instances opaque I think this will help with #23109 Wibbles Allow SelCo for newtype classes Experimental change Wibble Furher wibbles Further improvments Further wibbles esp exprIsConLike Run classop rule first Newtype classops are small needs comments - - - - - 9eb63300 by Simon Peyton Jones at 2024-04-09T17:30:05+01:00 Wibble imports - - - - - b7c88cd8 by Simon Peyton Jones at 2024-04-09T17:30:05+01:00 Wibbles Notably: define and use mkNewTypeDictApp - - - - - bc54e506 by Simon Peyton Jones at 2024-04-09T17:30:05+01:00 Make newtype-class data constructors not inline This variant tries * Making the data constructor for a newtype class not inline * exprIsConApp_maybe treats it like a normal data constructor * CoreToStg discards it (perhaps CorePrep should do that instead) * Some as-it-turns-out unforced changes to corePrepPgm that makes it pass all TyCons, not just the data tycons * Significantly simpler story in mkNewTypeDictApp - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - + compiler/GHC/Data/FlatBag.hs - compiler/GHC/Data/SmallArray.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b27f6c8cc59bf576089c3c66ab0bed174aa65e6e...bc54e506e114d40aa1a9a2f8ba95ea7afcbaa3cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b27f6c8cc59bf576089c3c66ab0bed174aa65e6e...bc54e506e114d40aa1a9a2f8ba95ea7afcbaa3cd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 16:47:37 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Tue, 09 Apr 2024 12:47:37 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Fix invalid Haddock Message-ID: <661571297827a_1002b4e105dc12075b@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 8f3a60e4 by Sven Tennie at 2024-04-09T16:47:06+00:00 Fix invalid Haddock - - - - - 1 changed file: - compiler/GHC/CmmToAsm/RV64.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64.hs ===================================== @@ -41,7 +41,7 @@ ncgRV64 config where platform = ncgPlatform config - -- | Instruction instance for RV64 +-- | Instruction instance for RV64 instance Instruction RV64.Instr where regUsageOfInstr = RV64.regUsageOfInstr patchRegsOfInstr = RV64.patchRegsOfInstr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f3a60e4817be80b5443d9dc3df3549d7fcb0d5b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f3a60e4817be80b5443d9dc3df3549d7fcb0d5b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 17:30:59 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 09 Apr 2024 13:30:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-completesig-no-srcspan Message-ID: <66157b531bce0_1002b413590e8123661@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-completesig-no-srcspan at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-completesig-no-srcspan You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 18:35:01 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 14:35:01 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: rts: free error message before returning Message-ID: <66158a55d091f_1002b41d3ada013963@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f1e9a03b by Rodrigo Mesquita at 2024-04-09T14:34:54-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 288cd038 by Alexis King at 2024-04-09T14:34:54-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 85564765 by Rodrigo Mesquita at 2024-04-09T14:34:54-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 8afb3ded by Rodrigo Mesquita at 2024-04-09T14:34:54-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - f62f869c by Ben Gamari at 2024-04-09T14:34:54-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 7867e9c3 by Zejun Wu at 2024-04-09T14:34:56-04:00 Make renamer to be more flexible with parens in the LHS of the rules We used to reject LHS like `(f a) b` in RULES and requires it to be written as `f a b`. It will be handy to allow both as the expression may be more readable with extra parens in some cases when infix operator is involved. Espceially when TemplateHaskell is used, extra parens may be added out of user's control and result in "valid" rules being rejected and there are not always ways to workaround it. Fixes #24621 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - + testsuite/tests/rename/should_compile/T24621.hs - testsuite/tests/rename/should_compile/all.T - testsuite/tests/rts/linker/T2615.hs - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5587bb5d8a28c19f08a7439d155212cf82702aeb...7867e9c33e842466230461c47ed6a634194bf80e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5587bb5d8a28c19f08a7439d155212cf82702aeb...7867e9c33e842466230461c47ed6a634194bf80e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 18:50:27 2024 From: gitlab at gitlab.haskell.org (Finley McIlwaine (@FinleyMcIlwaine)) Date: Tue, 09 Apr 2024 14:50:27 -0400 Subject: [Git][ghc/ghc][wip/t24277] base: Add CostCentreId, currentCallStackIds, ccsToIds, ccId Message-ID: <66158df3dc173_1002b4201d0041447d0@gitlab.mail> Finley McIlwaine pushed to branch wip/t24277 at Glasgow Haskell Compiler / GHC Commits: 0206cc7c by Finley McIlwaine at 2024-04-09T11:49:34-07:00 base: Add CostCentreId, currentCallStackIds, ccsToIds, ccId Add functions for gettings the IDs of cost centres to the interface of `GHC.Stack`, `GHC.Stack.CCS`, and `GHC.Exts`. Also add an opaque type for cost center ids, `CostCentreId`, with appropriate instances. Implements CLC proposal 235. Resolves #24277 - - - - - 12 changed files: - docs/users_guide/9.12.1-notes.rst - libraries/base/changelog.md - libraries/base/src/GHC/Exts.hs - libraries/base/src/GHC/Stack.hs - libraries/base/src/GHC/Stack/CCS.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Stack.hs - libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 Changes: ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -26,6 +26,11 @@ Runtime system ``base`` library ~~~~~~~~~~~~~~~~ +- The ``CostCentreId`` type and ``currentCallStackIds :: IO [CostCentreId]`` + function for getting the IDs of the cost centers on the current stack are now + exported from ``GHC.Exts``. In addition to those, the ``ccId`` and + ``ccsToIds`` functions for getting a ``CostCentreId`` are also exported from + ``GHC.Stack`` and ``GHC.Stack.CCS`` ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/changelog.md ===================================== @@ -65,6 +65,17 @@ reflect the new RTS flags: `-he` profiling mode, `-he` selector and `--automatic-era-increment`. ([CLC proposal #254](https://github.com/haskell/core-libraries-committee/issues/254)) + * Add the following exports to `GHC.Stack` and `GHC.Stack.CCS`: + + - Opaque `CostCentreId` newtype. + - `currentCallStackIds :: IO [CostCentreId]` + - `ccsToIds :: Ptr CostCentreStack -> IO [CostCentreId]` + - `ccId :: Ptr CostCentre -> IO CostCentreId` + + Also add the `CostCentreId` and `currentCallStackIds` exports to GHC.Exts:. + See [CLC proposal + #235](https://github.com/haskell/core-libraries-committee/issues/235) + ## 4.19.0.0 *October 2023* * Add `{-# WARNING in "x-partial" #-}` to `Data.List.{head,tail}`. Use `{-# OPTIONS_GHC -Wno-x-partial #-}` to disable it. ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -84,6 +84,8 @@ module GHC.Exts traceEvent, -- ** The call stack currentCallStack, + currentCallStackIds, + CostCentreId, -- * Ids with special behaviour inline, noinline, ===================================== libraries/base/src/GHC/Stack.hs ===================================== @@ -18,6 +18,7 @@ module GHC.Stack (errorWithStackTrace, -- * Profiling call stacks currentCallStack, + currentCallStackIds, whoCreated, -- * HasCallStack call stacks CallStack, @@ -37,14 +38,17 @@ module GHC.Stack -- * Internals CostCentreStack, CostCentre, + CostCentreId, getCurrentCCS, getCCSOf, clearCCS, ccsCC, ccsParent, + ccId, ccLabel, ccModule, ccSrcSpan, + ccsToIds, ccsToStrings, renderStack ) where ===================================== libraries/base/src/GHC/Stack/CCS.hs ===================================== @@ -16,11 +16,13 @@ module GHC.Stack.CCS ( -- * Call stacks currentCallStack, + currentCallStackIds, whoCreated, -- * Internals CostCentreStack, CostCentre, + CostCentreId, getCurrentCCS, getCCSOf, clearCCS, @@ -28,7 +30,9 @@ module GHC.Stack.CCS ( ccsParent, ccLabel, ccModule, + ccId, ccSrcSpan, + ccsToIds, ccsToStrings, renderStack, ) where ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -103,6 +103,8 @@ module GHC.Internal.Exts -- ** The call stack currentCallStack, + currentCallStackIds, + CostCentreId, -- * Ids with special behaviour inline, noinline, lazy, oneShot, considerAccessible, ===================================== libraries/ghc-internal/src/GHC/Internal/Stack.hs ===================================== @@ -24,6 +24,7 @@ module GHC.Internal.Stack ( -- * Profiling call stacks currentCallStack, + currentCallStackIds, whoCreated, -- * HasCallStack call stacks @@ -38,14 +39,17 @@ module GHC.Internal.Stack ( -- * Internals CostCentreStack, CostCentre, + CostCentreId, getCurrentCCS, getCCSOf, clearCCS, ccsCC, ccsParent, + ccId, ccLabel, ccModule, ccSrcSpan, + ccsToIds, ccsToStrings, renderStack ) where ===================================== libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc ===================================== @@ -16,14 +16,17 @@ ----------------------------------------------------------------------------- {-# LANGUAGE UnboxedTuples, MagicHash, NoImplicitPrelude #-} +{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving #-} module GHC.Internal.Stack.CCS ( -- * Call stacks currentCallStack, + currentCallStackIds, whoCreated, -- * Internals CostCentreStack, CostCentre, + CostCentreId, getCurrentCCS, getCCSOf, clearCCS, @@ -31,7 +34,9 @@ module GHC.Internal.Stack.CCS ( ccsParent, ccLabel, ccModule, + ccId, ccSrcSpan, + ccsToIds, ccsToStrings, renderStack, ) where @@ -44,6 +49,12 @@ import GHC.Internal.Base import GHC.Internal.Ptr import GHC.Internal.IO.Encoding import GHC.Internal.List ( concatMap, reverse ) +import GHC.Internal.Word ( Word32 ) +import GHC.Internal.Show +import GHC.Internal.Read +import GHC.Internal.Enum +import GHC.Internal.Real +import GHC.Internal.Num #define PROFILING #include "Rts.h" @@ -54,6 +65,13 @@ data CostCentreStack -- | A cost-centre from GHC's cost-center profiler. data CostCentre +-- | Cost centre identifier +-- +-- @since 4.20.0.0 +newtype CostCentreId = CostCentreId Word32 + deriving (Show, Read) + deriving newtype (Eq, Ord, Bounded, Enum, Integral, Num, Real) + -- | Returns the current 'CostCentreStack' (value is @nullPtr@ if the current -- program was not compiled with profiling support). Takes a dummy argument -- which can be used to avoid the call to @getCurrentCCS@ being floated out by @@ -83,6 +101,12 @@ ccsCC p = peekByteOff p 4 ccsParent :: Ptr CostCentreStack -> IO (Ptr CostCentreStack) ccsParent p = peekByteOff p 8 +-- | Get the 'CostCentreId' of a 'CostCentre'. +-- +-- @since 4.20.0.0 +ccId :: Ptr CostCentre -> IO CostCentreId +ccId p = fmap CostCentreId $ peekByteOff p 0 + ccLabel :: Ptr CostCentre -> IO CString ccLabel p = peekByteOff p 4 @@ -99,6 +123,12 @@ ccsCC p = (# peek CostCentreStack, cc) p ccsParent :: Ptr CostCentreStack -> IO (Ptr CostCentreStack) ccsParent p = (# peek CostCentreStack, prevStack) p +-- | Get the 'CostCentreId' of a 'CostCentre'. +-- +-- @since 4.20.0.0 +ccId :: Ptr CostCentre -> IO CostCentreId +ccId p = fmap CostCentreId $ (# peek CostCentre, ccID) p + -- | Get the label of a 'CostCentre'. ccLabel :: Ptr CostCentre -> IO CString ccLabel p = (# peek CostCentre, label) p @@ -125,6 +155,19 @@ ccSrcSpan p = (# peek CostCentre, srcloc) p currentCallStack :: IO [String] currentCallStack = ccsToStrings =<< getCurrentCCS () +-- | Returns a @[CostCentreId]@ representing the current call stack. This +-- can be useful for debugging. +-- +-- The implementation uses the call-stack simulation maintained by the +-- profiler, so it only works if the program was compiled with @-prof@ +-- and contains suitable SCC annotations (e.g. by using @-fprof-late@). +-- Otherwise, the list returned is likely to be empty or +-- uninformative. +-- +-- @since 4.20.0.0 +currentCallStackIds :: IO [CostCentreId] +currentCallStackIds = ccsToIds =<< getCurrentCCS () + -- | Format a 'CostCentreStack' as a list of lines. ccsToStrings :: Ptr CostCentreStack -> IO [String] ccsToStrings ccs0 = go ccs0 [] @@ -141,6 +184,24 @@ ccsToStrings ccs0 = go ccs0 [] then return acc else go parent ((mdl ++ '.':lbl ++ ' ':'(':loc ++ ")") : acc) +-- | Format a 'CostCentreStack' as a list of cost centre IDs. +-- +-- @since 4.20.0.0 +ccsToIds :: Ptr CostCentreStack -> IO [CostCentreId] +ccsToIds ccs0 = go ccs0 [] + where + go ccs acc + | ccs == nullPtr = return acc + | otherwise = do + cc <- ccsCC ccs + cc_id <- ccId cc + lbl <- GHC.peekCString utf8 =<< ccLabel cc + mdl <- GHC.peekCString utf8 =<< ccModule cc + parent <- ccsParent ccs + if (mdl == "MAIN" && lbl == "MAIN") + then return acc + else go parent (cc_id : acc) + -- | Get the stack trace attached to an object. -- -- @since base-4.5.0.0 ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -5412,6 +5412,8 @@ module GHC.Exts where data Compact# type Constraint :: * type Constraint = CONSTRAINT LiftedRep + type CostCentreId :: * + newtype CostCentreId = ... type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint class DataToTag a where dataToTag# :: a -> Int# @@ -5797,6 +5799,7 @@ module GHC.Exts where ctz64# :: Word64# -> Word# ctz8# :: Word# -> Word# currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] deRefStablePtr# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) deRefWeak# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) decodeDouble_2Int# :: Double# -> (# Int#, Word#, Word#, Int# #) @@ -9343,6 +9346,8 @@ module GHC.Stack where data CallStack = ... type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack type HasCallStack :: Constraint @@ -9350,14 +9355,17 @@ module GHC.Stack where type SrcLoc :: * data SrcLoc = SrcLoc {srcLocPackage :: [GHC.Types.Char], srcLocModule :: [GHC.Types.Char], srcLocFile :: [GHC.Types.Char], srcLocStartLine :: GHC.Types.Int, srcLocStartCol :: GHC.Types.Int, srcLocEndLine :: GHC.Types.Int, srcLocEndCol :: GHC.Types.Int} callStack :: HasCallStack => CallStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] emptyCallStack :: CallStack errorWithStackTrace :: forall a. GHC.Internal.Base.String -> a freezeCallStack :: CallStack -> CallStack @@ -9377,16 +9385,21 @@ module GHC.Stack.CCS where -- Safety: Safe type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] getCCSOf :: forall a. a -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) getCurrentCCS :: forall dummy. dummy -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) renderStack :: [GHC.Internal.Base.String] -> GHC.Internal.Base.String @@ -11600,6 +11613,7 @@ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CULong -- Define instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Bounded GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.SourceStrictness -- Defined in ‘GHC.Internal.Generics’ @@ -11675,6 +11689,7 @@ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Enum GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Enum GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ @@ -12059,6 +12074,7 @@ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CULong -- Defined in instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Num.Num GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Num.Num GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Int -- Defined in ‘GHC.Internal.Num’ @@ -12170,6 +12186,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Read.Read GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k2 (f :: k2 -> *) k1 (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -12243,6 +12260,7 @@ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULLong -- Defi instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULong -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Integral GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall a k (b :: k). GHC.Internal.Real.Real a => GHC.Internal.Real.Real (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Real (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Real.Real (f (g a)) => GHC.Internal.Real.Real (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -12289,6 +12307,7 @@ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CULong -- Defined i instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Real GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Real.Real GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Real.Real GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance forall a k (b :: k). GHC.Internal.Real.RealFrac a => GHC.Internal.Real.RealFrac (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ @@ -12467,6 +12486,7 @@ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Interna instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Manager.FdKey -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.Manager’ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Manager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.Manager’ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager’ +instance GHC.Internal.Show.Show GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Show.Show GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance GHC.Internal.Show.Show GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Show.Show GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ @@ -12679,6 +12699,7 @@ instance GHC.Classes.Eq ghc-internal-9.1001.0:GHC.Internal.Event.Manager.State - instance GHC.Classes.Eq GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ instance GHC.Classes.Eq ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager’ instance GHC.Classes.Eq GHC.Internal.Stack.Types.SrcLoc -- Defined in ‘GHC.Internal.Stack.Types’ +instance GHC.Classes.Eq GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Eq GHC.Internal.Exts.SpecConstrAnnotation -- Defined in ‘GHC.Internal.Exts’ instance GHC.Classes.Eq GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -12845,6 +12866,7 @@ instance forall a. GHC.Classes.Ord (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) instance forall i e. (GHC.Internal.Ix.Ix i, GHC.Classes.Ord e) => GHC.Classes.Ord (GHC.Internal.Arr.Array i e) -- Defined in ‘GHC.Internal.Arr’ instance GHC.Classes.Ord GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Classes.Ord GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ +instance GHC.Classes.Ord GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Ord GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -234,7 +234,7 @@ module Control.Exception where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -303,7 +303,7 @@ module Control.Exception where module Control.Exception.Annotation where -- Safety: None type ExceptionAnnotation :: * -> Constraint - class ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a => ExceptionAnnotation a where + class ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a => ExceptionAnnotation a where displayExceptionAnnotation :: a -> GHC.Internal.Base.String default displayExceptionAnnotation :: GHC.Internal.Show.Show a => a -> GHC.Internal.Base.String {-# MINIMAL #-} @@ -345,7 +345,7 @@ module Control.Exception.Base where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -848,11 +848,11 @@ module Data.Data where type TyCon :: * data TyCon = ... type TypeRep :: * - type TypeRep = ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + type TypeRep = ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} cast :: forall a b. (Typeable a, Typeable b) => a -> GHC.Internal.Maybe.Maybe b constrFields :: Constr -> [GHC.Internal.Base.String] constrFixity :: Constr -> Fixity @@ -895,7 +895,7 @@ module Data.Data where showConstr :: Constr -> GHC.Internal.Base.String showsTypeRep :: TypeRep -> GHC.Internal.Show.ShowS splitTyConApp :: TypeRep -> (TyCon, [TypeRep]) - trLiftedRep :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep + trLiftedRep :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConModule :: TyCon -> GHC.Internal.Base.String tyConName :: TyCon -> GHC.Internal.Base.String @@ -919,14 +919,14 @@ module Data.Dynamic where -- Safety: Safe type Dynamic :: * data Dynamic where - Dynamic :: forall a. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a -> a -> Dynamic + Dynamic :: forall a. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a -> a -> Dynamic type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} dynApp :: Dynamic -> Dynamic -> Dynamic dynApply :: Dynamic -> Dynamic -> GHC.Internal.Maybe.Maybe Dynamic - dynTypeRep :: Dynamic -> ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + dynTypeRep :: Dynamic -> ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep fromDyn :: forall a. Typeable a => Dynamic -> a -> a fromDynamic :: forall a. Typeable a => Dynamic -> GHC.Internal.Maybe.Maybe a toDyn :: forall a. Typeable a => a -> Dynamic @@ -1809,11 +1809,11 @@ module Data.Typeable where type TyCon :: * data TyCon = ... type TypeRep :: * - type TypeRep = ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + type TypeRep = ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} cast :: forall a b. (Typeable a, Typeable b) => a -> GHC.Internal.Maybe.Maybe b decT :: forall {k} (a :: k) (b :: k). (Typeable a, Typeable b) => GHC.Internal.Data.Either.Either ((a :~: b) -> GHC.Internal.Base.Void) (a :~: b) eqT :: forall {k} (a :: k) (b :: k). (Typeable a, Typeable b) => GHC.Internal.Maybe.Maybe (a :~: b) @@ -1828,7 +1828,7 @@ module Data.Typeable where rnfTypeRep :: TypeRep -> () showsTypeRep :: TypeRep -> GHC.Internal.Show.ShowS splitTyConApp :: TypeRep -> (TyCon, [TypeRep]) - trLiftedRep :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep + trLiftedRep :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConModule :: TyCon -> GHC.Internal.Base.String tyConName :: TyCon -> GHC.Internal.Base.String @@ -5251,9 +5251,9 @@ module GHC.Event.TimeOut where type TimeoutEdit :: * type TimeoutEdit = TimeoutQueue -> TimeoutQueue type TimeoutKey :: * - newtype TimeoutKey = TK ghc-internal-0.1.0.0:GHC.Internal.Event.Unique.Unique + newtype TimeoutKey = TK ghc-internal-9.1001.0:GHC.Internal.Event.Unique.Unique type TimeoutQueue :: * - type TimeoutQueue = ghc-internal-0.1.0.0:GHC.Internal.Event.PSQ.PSQ TimeoutCallback + type TimeoutQueue = ghc-internal-9.1001.0:GHC.Internal.Event.PSQ.PSQ TimeoutCallback module GHC.Exception where -- Safety: Safe @@ -5265,7 +5265,7 @@ module GHC.Exception where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -5294,7 +5294,7 @@ module GHC.Exception.Type where type ArithException :: * data ArithException = Overflow | Underflow | LossOfPrecision | DivideByZero | Denormal | RatioZeroDenominator type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -5381,6 +5381,8 @@ module GHC.Exts where data Compact# type Constraint :: * type Constraint = CONSTRAINT LiftedRep + type CostCentreId :: * + newtype CostCentreId = ... type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint class DataToTag a where dataToTag# :: a -> Int# @@ -5766,6 +5768,7 @@ module GHC.Exts where ctz64# :: Word64# -> Word# ctz8# :: Word# -> Word# currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] deRefStablePtr# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) deRefWeak# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) decodeDouble_2Int# :: Double# -> (# Int#, Word#, Word#, Int# #) @@ -7847,8 +7850,8 @@ module GHC.IO.Handle where hTryLock :: Handle -> LockMode -> GHC.Types.IO GHC.Types.Bool hWaitForInput :: Handle -> GHC.Types.Int -> GHC.Types.IO GHC.Types.Bool isEOF :: GHC.Types.IO GHC.Types.Bool - mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle - mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle + mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle + mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle nativeNewline :: Newline nativeNewlineMode :: NewlineMode noNewlineTranslation :: NewlineMode @@ -7898,11 +7901,11 @@ module GHC.IO.Handle.Internals where ioe_notReadable :: forall a. GHC.Types.IO a ioe_notWritable :: forall a. GHC.Types.IO a ioe_semiclosedHandle :: forall a. GHC.Types.IO a - mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkDuplexHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkFileHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.Handle.Types.HandleType -> GHC.Types.Bool -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Internal.Maybe.Maybe HandleFinalizer -> GHC.Internal.Maybe.Maybe (GHC.Internal.MVar.MVar GHC.Internal.IO.Handle.Types.Handle__) -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkDuplexHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkFileHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.Handle.Types.HandleType -> GHC.Types.Bool -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Internal.Maybe.Maybe HandleFinalizer -> GHC.Internal.Maybe.Maybe (GHC.Internal.MVar.MVar GHC.Internal.IO.Handle.Types.Handle__) -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle openTextEncoding :: forall a. GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.HandleType -> (forall es ds. GHC.Internal.Maybe.Maybe (GHC.Internal.IO.Encoding.Types.TextEncoder es) -> GHC.Internal.Maybe.Maybe (GHC.Internal.IO.Encoding.Types.TextDecoder ds) -> GHC.Types.IO a) -> GHC.Types.IO a readTextDevice :: GHC.Internal.IO.Handle.Types.Handle__ -> GHC.Internal.IO.Buffer.CharBuffer -> GHC.Types.IO GHC.Internal.IO.Buffer.CharBuffer readTextDeviceNonBlocking :: GHC.Internal.IO.Handle.Types.Handle__ -> GHC.Internal.IO.Buffer.CharBuffer -> GHC.Types.IO GHC.Internal.IO.Buffer.CharBuffer @@ -7966,7 +7969,7 @@ module GHC.IO.Handle.Types where type Handle__ :: * data Handle__ = forall dev enc_state dec_state. - (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => + (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => Handle__ {haDevice :: !dev, haType :: HandleType, haByteBuffer :: ! {-# UNPACK #-}(GHC.Internal.IORef.N:IORef[0] _N)(GHC.Internal.IORef.IORef (GHC.Internal.IO.Buffer.Buffer GHC.Internal.Word.Word8)), @@ -12385,6 +12388,8 @@ module GHC.Stack where data CallStack = ... type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack type HasCallStack :: Constraint @@ -12392,14 +12397,17 @@ module GHC.Stack where type SrcLoc :: * data SrcLoc = SrcLoc {srcLocPackage :: [GHC.Types.Char], srcLocModule :: [GHC.Types.Char], srcLocFile :: [GHC.Types.Char], srcLocStartLine :: GHC.Types.Int, srcLocStartCol :: GHC.Types.Int, srcLocEndLine :: GHC.Types.Int, srcLocEndCol :: GHC.Types.Int} callStack :: HasCallStack => CallStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] emptyCallStack :: CallStack errorWithStackTrace :: forall a. GHC.Internal.Base.String -> a freezeCallStack :: CallStack -> CallStack @@ -12419,16 +12427,21 @@ module GHC.Stack.CCS where -- Safety: Safe type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] getCCSOf :: forall a. a -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) getCurrentCCS :: forall dummy. dummy -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) renderStack :: [GHC.Internal.Base.String] -> GHC.Internal.Base.String @@ -12462,7 +12475,7 @@ module GHC.StaticPtr where -- Safety: None type IsStatic :: (* -> *) -> Constraint class IsStatic p where - fromStaticPtr :: forall a. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a => StaticPtr a -> p a + fromStaticPtr :: forall a. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a => StaticPtr a -> p a {-# MINIMAL fromStaticPtr #-} type StaticKey :: * type StaticKey = GHC.Internal.Fingerprint.Type.Fingerprint @@ -13857,8 +13870,8 @@ module Type.Reflection where data (:~~:) a b where HRefl :: forall {k1} (a :: k1). (:~~:) a a pattern App :: forall k2 (t :: k2). () => forall k1 (a :: k1 -> k2) (b :: k1). (t ~ a b) => TypeRep a -> TypeRep b -> TypeRep t - pattern Con :: forall k (a :: k). () => ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> TypeRep a - pattern Con' :: forall k (a :: k). () => ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> [SomeTypeRep] -> TypeRep a + pattern Con :: forall k (a :: k). () => ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> TypeRep a + pattern Con' :: forall k (a :: k). () => ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> [SomeTypeRep] -> TypeRep a pattern Fun :: forall k (fun :: k). () => forall (r1 :: GHC.Types.RuntimeRep) (r2 :: GHC.Types.RuntimeRep) (arg :: TYPE r1) (res :: TYPE r2). (k ~ *, fun ~~ (arg -> res)) => TypeRep arg -> TypeRep res -> TypeRep fun type Module :: * data Module = ... @@ -13875,7 +13888,7 @@ module Type.Reflection where type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} decTypeRep :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> GHC.Internal.Data.Either.Either ((a :~~: b) -> GHC.Internal.Base.Void) (a :~~: b) eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> GHC.Internal.Maybe.Maybe (a :~~: b) moduleName :: Module -> GHC.Internal.Base.String @@ -13910,9 +13923,9 @@ module Type.Reflection.Unsafe where data TypeRep a where ... mkTrApp :: forall k1 k2 (a :: k1 -> k2) (b :: k1). TypeRep a -> TypeRep b -> TypeRep (a b) - mkTrCon :: forall k (a :: k). TyCon -> [ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep] -> TypeRep a + mkTrCon :: forall k (a :: k). TyCon -> [ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep] -> TypeRep a mkTyCon :: GHC.Internal.Base.String -> GHC.Internal.Base.String -> GHC.Internal.Base.String -> GHC.Types.Int -> KindRep -> TyCon - someTypeRepFingerprint :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -> GHC.Internal.Fingerprint.Type.Fingerprint + someTypeRepFingerprint :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -> GHC.Internal.Fingerprint.Type.Fingerprint tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConKindArgs :: TyCon -> GHC.Types.Int tyConKindRep :: TyCon -> KindRep @@ -14425,20 +14438,20 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.First -- Defined instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined in ‘Data.Semigroup’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’ -instance forall (a :: * -> * -> *) b c. (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’ -instance forall (m :: * -> *) a. (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’ +instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’ +instance forall (m :: * -> *) a. (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Internal.Functor.ZipList.ZipList a) -- Defined in ‘GHC.Internal.Functor.ZipList’ instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’ -instance forall s. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable s => GHC.Internal.Data.Data.Data (Data.Array.Byte.MutableByteArray s) -- Defined in ‘Data.Array.Byte’ +instance forall s. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable s => GHC.Internal.Data.Data.Data (Data.Array.Byte.MutableByteArray s) -- Defined in ‘Data.Array.Byte’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Complex.Complex a) -- Defined in ‘Data.Complex’ -instance forall i j (a :: i) (b :: j). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable i, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable j, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b, a ~~ b) => GHC.Internal.Data.Data.Data (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Data’ +instance forall i j (a :: i) (b :: j). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable i, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable j, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b, a ~~ b) => GHC.Internal.Data.Data.Data (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Data’ instance forall a b. (GHC.Internal.Data.Data.Data a, GHC.Internal.Data.Data.Data b, GHC.Internal.Ix.Ix a) => GHC.Internal.Data.Data.Data (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Bool -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Char -- Defined in ‘GHC.Internal.Data.Data’ -instance forall k a (b :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b) => GHC.Internal.Data.Data.Data (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Data’ +instance forall k a (b :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b) => GHC.Internal.Data.Data.Data (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Data’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Double -- Defined in ‘GHC.Internal.Data.Data’ @@ -14486,10 +14499,10 @@ instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word32 -- Defined in ‘G instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word64 -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word8 -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Data.Data’ -instance forall k (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a) => GHC.Internal.Data.Data.Data (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ -instance forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k1, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k2, GHC.Internal.Data.Data.Data (f (g a))) => GHC.Internal.Data.Data.Data (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ -instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ -instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Sum.Sum f g a) -- Defined in ‘Data.Functor.Sum’ +instance forall k (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a) => GHC.Internal.Data.Data.Data (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ +instance forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k1, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k2, GHC.Internal.Data.Data.Data (f (g a))) => GHC.Internal.Data.Data.Data (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ +instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Sum.Sum f g a) -- Defined in ‘Data.Functor.Sum’ instance forall a b. (GHC.Internal.Data.Data.Data a, GHC.Internal.Data.Data.Data b) => GHC.Internal.Data.Data.Data (Data.Semigroup.Arg a b) -- Defined in ‘Data.Semigroup’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Semigroup.First a) -- Defined in ‘Data.Semigroup’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Semigroup.Last a) -- Defined in ‘Data.Semigroup’ @@ -14555,7 +14568,7 @@ instance GHC.Internal.Data.Type.Equality.TestEquality GHC.Internal.TypeLits.SCha instance GHC.Internal.Data.Type.Equality.TestEquality GHC.Internal.TypeLits.SSymbol -- Defined in ‘GHC.Internal.TypeLits’ instance forall k (a :: k). GHC.Internal.Data.Type.Equality.TestEquality ((GHC.Internal.Data.Type.Equality.:~:) a) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k1 k (a :: k1). GHC.Internal.Data.Type.Equality.TestEquality ((GHC.Internal.Data.Type.Equality.:~~:) a) -- Defined in ‘GHC.Internal.Data.Type.Equality’ -instance forall k. GHC.Internal.Data.Type.Equality.TestEquality ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k. GHC.Internal.Data.Type.Equality.TestEquality ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1). GHC.Internal.Data.Type.Equality.TestEquality f => GHC.Internal.Data.Type.Equality.TestEquality (Data.Functor.Compose.Compose f g) -- Defined in ‘Data.Functor.Compose’ instance forall a k (b :: k). GHC.Internal.Enum.Bounded a => GHC.Internal.Enum.Bounded (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall a. GHC.Internal.Enum.Bounded a => GHC.Internal.Enum.Bounded (GHC.Internal.Data.Bits.And a) -- Defined in ‘GHC.Internal.Data.Bits’ @@ -14635,6 +14648,7 @@ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CULong -- Define instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Bounded GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.SourceStrictness -- Defined in ‘GHC.Internal.Generics’ @@ -14710,6 +14724,7 @@ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Enum GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Enum GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ @@ -14752,7 +14767,7 @@ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Ba instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Base.RecUpdError -- Defined in ‘GHC.Internal.Control.Exception.Base’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Base.TypeError -- Defined in ‘GHC.Internal.Control.Exception.Base’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’ -instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common’ +instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.JS.Prim.JSException -- Defined in ‘GHC.Internal.JS.Prim’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.JS.Prim.WouldBlockException -- Defined in ‘GHC.Internal.JS.Prim’ @@ -15096,6 +15111,7 @@ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CULong -- Defined in instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Num.Num GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Num.Num GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Int -- Defined in ‘GHC.Internal.Num’ @@ -15207,6 +15223,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Read.Read GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k2 (f :: k2 -> *) k1 (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -15280,6 +15297,7 @@ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULLong -- Defi instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULong -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Integral GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall a k (b :: k). GHC.Internal.Real.Real a => GHC.Internal.Real.Real (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Real (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Real.Real (f (g a)) => GHC.Internal.Real.Real (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -15326,6 +15344,7 @@ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CULong -- Defined i instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Real GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Real.Real GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Real.Real GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance forall a k (b :: k). GHC.Internal.Real.RealFrac a => GHC.Internal.Real.RealFrac (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ @@ -15425,8 +15444,8 @@ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.DataRep -- Defined in ‘ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.DataType -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.Fixity -- Defined in ‘GHC.Internal.Data.Data’ instance forall k (s :: k). GHC.Internal.Show.Show (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Internal.Show.Show ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Internal.Show.Show (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Internal.Show.Show (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance GHC.Internal.Show.Show GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’ instance forall a b. (GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Show.Show (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ @@ -15497,6 +15516,7 @@ instance GHC.Internal.Show.Show GHC.Internal.Foreign.C.Types.CWchar -- Defined i instance forall a. GHC.Internal.Show.Show (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) -- Defined in ‘GHC.Internal.Foreign.C.ConstPtr’ instance forall a b. (GHC.Internal.Ix.Ix a, GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Arr’ instance GHC.Internal.Show.Show GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Show.Show GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Show.Show GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance GHC.Internal.Show.Show GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Show.Show GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ @@ -15529,7 +15549,7 @@ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.Handle -- Defined i instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.HandleType -- Defined in ‘GHC.Internal.IO.Handle.Types’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’ -instance [safe] GHC.Internal.Show.Show ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common’ +instance [safe] GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.HandlePosn -- Defined in ‘GHC.Internal.IO.Handle’ instance GHC.Internal.Show.Show GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’ instance GHC.Internal.Show.Show GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’ @@ -15626,8 +15646,8 @@ instance GHC.Classes.Eq GHC.Internal.Data.Data.ConstrRep -- Defined in ‘GHC.In instance GHC.Classes.Eq GHC.Internal.Data.Data.DataRep -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Classes.Eq GHC.Internal.Data.Data.Fixity -- Defined in ‘GHC.Internal.Data.Data’ instance forall k (s :: k). GHC.Classes.Eq (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Classes.Eq ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Classes.Eq (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Classes.Eq ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Classes.Eq (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall a b. (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). GHC.Classes.Eq (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Classes.Eq (f (g a)) => GHC.Classes.Eq (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -15705,6 +15725,7 @@ instance forall s i e. GHC.Classes.Eq (GHC.Internal.Arr.STArray s i e) -- Define instance GHC.Classes.Eq GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Classes.Eq GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ instance GHC.Classes.Eq GHC.Internal.Stack.Types.SrcLoc -- Defined in ‘GHC.Internal.Stack.Types’ +instance GHC.Classes.Eq GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Eq GHC.Internal.Exts.SpecConstrAnnotation -- Defined in ‘GHC.Internal.Exts’ instance GHC.Classes.Eq GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -15800,8 +15821,8 @@ instance GHC.Classes.Ord GHC.Internal.Unicode.GeneralCategory -- Defined in ‘G instance forall k (a :: k) (b :: k). GHC.Classes.Ord (a GHC.Internal.Data.Type.Equality.:~: b) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k1 k2 (a :: k1) (b :: k2). GHC.Classes.Ord (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k (s :: k). GHC.Classes.Ord (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Classes.Ord ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Classes.Ord (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Classes.Ord ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Classes.Ord (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall a b. (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). GHC.Classes.Ord (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Classes.Ord (f (g a)) => GHC.Classes.Ord (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -15872,6 +15893,7 @@ instance forall a. GHC.Classes.Ord (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) instance forall i e. (GHC.Internal.Ix.Ix i, GHC.Classes.Ord e) => GHC.Classes.Ord (GHC.Internal.Arr.Array i e) -- Defined in ‘GHC.Internal.Arr’ instance GHC.Classes.Ord GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Classes.Ord GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ +instance GHC.Classes.Ord GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Ord GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -234,7 +234,7 @@ module Control.Exception where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -303,7 +303,7 @@ module Control.Exception where module Control.Exception.Annotation where -- Safety: None type ExceptionAnnotation :: * -> Constraint - class ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a => ExceptionAnnotation a where + class ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a => ExceptionAnnotation a where displayExceptionAnnotation :: a -> GHC.Internal.Base.String default displayExceptionAnnotation :: GHC.Internal.Show.Show a => a -> GHC.Internal.Base.String {-# MINIMAL #-} @@ -345,7 +345,7 @@ module Control.Exception.Base where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -848,11 +848,11 @@ module Data.Data where type TyCon :: * data TyCon = ... type TypeRep :: * - type TypeRep = ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + type TypeRep = ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} cast :: forall a b. (Typeable a, Typeable b) => a -> GHC.Internal.Maybe.Maybe b constrFields :: Constr -> [GHC.Internal.Base.String] constrFixity :: Constr -> Fixity @@ -895,7 +895,7 @@ module Data.Data where showConstr :: Constr -> GHC.Internal.Base.String showsTypeRep :: TypeRep -> GHC.Internal.Show.ShowS splitTyConApp :: TypeRep -> (TyCon, [TypeRep]) - trLiftedRep :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep + trLiftedRep :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConModule :: TyCon -> GHC.Internal.Base.String tyConName :: TyCon -> GHC.Internal.Base.String @@ -919,14 +919,14 @@ module Data.Dynamic where -- Safety: Safe type Dynamic :: * data Dynamic where - Dynamic :: forall a. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a -> a -> Dynamic + Dynamic :: forall a. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a -> a -> Dynamic type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} dynApp :: Dynamic -> Dynamic -> Dynamic dynApply :: Dynamic -> Dynamic -> GHC.Internal.Maybe.Maybe Dynamic - dynTypeRep :: Dynamic -> ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + dynTypeRep :: Dynamic -> ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep fromDyn :: forall a. Typeable a => Dynamic -> a -> a fromDynamic :: forall a. Typeable a => Dynamic -> GHC.Internal.Maybe.Maybe a toDyn :: forall a. Typeable a => a -> Dynamic @@ -1809,11 +1809,11 @@ module Data.Typeable where type TyCon :: * data TyCon = ... type TypeRep :: * - type TypeRep = ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep + type TypeRep = ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} cast :: forall a b. (Typeable a, Typeable b) => a -> GHC.Internal.Maybe.Maybe b decT :: forall {k} (a :: k) (b :: k). (Typeable a, Typeable b) => GHC.Internal.Data.Either.Either ((a :~: b) -> GHC.Internal.Base.Void) (a :~: b) eqT :: forall {k} (a :: k) (b :: k). (Typeable a, Typeable b) => GHC.Internal.Maybe.Maybe (a :~: b) @@ -1828,7 +1828,7 @@ module Data.Typeable where rnfTypeRep :: TypeRep -> () showsTypeRep :: TypeRep -> GHC.Internal.Show.ShowS splitTyConApp :: TypeRep -> (TyCon, [TypeRep]) - trLiftedRep :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep + trLiftedRep :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep GHC.Types.LiftedRep tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConModule :: TyCon -> GHC.Internal.Base.String tyConName :: TyCon -> GHC.Internal.Base.String @@ -5293,9 +5293,9 @@ module GHC.Event.TimeOut where type TimeoutEdit :: * type TimeoutEdit = TimeoutQueue -> TimeoutQueue type TimeoutKey :: * - newtype TimeoutKey = TK ghc-internal-0.1.0.0:GHC.Internal.Event.Unique.Unique + newtype TimeoutKey = TK ghc-internal-9.1001.0:GHC.Internal.Event.Unique.Unique type TimeoutQueue :: * - type TimeoutQueue = ghc-internal-0.1.0.0:GHC.Internal.Event.PSQ.PSQ TimeoutCallback + type TimeoutQueue = ghc-internal-9.1001.0:GHC.Internal.Event.PSQ.PSQ TimeoutCallback module GHC.Event.Windows where -- Safety: None @@ -5306,7 +5306,7 @@ module GHC.Event.Windows where type ConsoleEvent :: * data ConsoleEvent = ControlC | Break | Close | Logoff | Shutdown type HandleData :: * - data HandleData = HandleData {tokenKey :: {-# UNPACK #-}HandleKey, tokenEvents :: ! {-# UNPACK #-}(ghc-internal-0.1.0.0:GHC.Internal.Event.Internal.Types.N:EventLifetime[0])ghc-internal-0.1.0.0:GHC.Internal.Event.Internal.Types.EventLifetime, _handleCallback :: !GHC.Internal.Event.Windows.EventCallback} + data HandleData = HandleData {tokenKey :: {-# UNPACK #-}HandleKey, tokenEvents :: ! {-# UNPACK #-}(ghc-internal-9.1001.0:GHC.Internal.Event.Internal.Types.N:EventLifetime[0])ghc-internal-9.1001.0:GHC.Internal.Event.Internal.Types.EventLifetime, _handleCallback :: !GHC.Internal.Event.Windows.EventCallback} type HandleKey :: * data HandleKey = GHC.Internal.Event.Windows.HandleKey {handleValue :: {-# UNPACK #-}GHC.Internal.Windows.HANDLE, ...} type IOResult :: * -> * @@ -5334,7 +5334,7 @@ module GHC.Event.Windows where ioFailedAny :: forall a b. GHC.Internal.Real.Integral a => a -> GHC.Types.IO (IOResult b) ioSuccess :: forall a. a -> GHC.Types.IO (IOResult a) processRemoteCompletion :: GHC.Types.IO () - registerHandle :: Manager -> GHC.Internal.Event.Windows.EventCallback -> GHC.Internal.Windows.HANDLE -> ghc-internal-0.1.0.0:GHC.Internal.Event.Internal.Types.Event -> ghc-internal-0.1.0.0:GHC.Internal.Event.Internal.Types.Lifetime -> GHC.Types.IO HandleKey + registerHandle :: Manager -> GHC.Internal.Event.Windows.EventCallback -> GHC.Internal.Windows.HANDLE -> ghc-internal-9.1001.0:GHC.Internal.Event.Internal.Types.Event -> ghc-internal-9.1001.0:GHC.Internal.Event.Internal.Types.Lifetime -> GHC.Types.IO HandleKey registerTimeout :: Manager -> GHC.Types.Int -> TimeoutCallback -> GHC.Types.IO TimeoutKey start_console_handler :: GHC.Internal.Word.Word32 -> GHC.Types.IO () toWin32ConsoleEvent :: forall a. (GHC.Classes.Eq a, GHC.Internal.Num.Num a) => a -> GHC.Internal.Maybe.Maybe ConsoleEvent @@ -5393,7 +5393,7 @@ module GHC.Event.Windows.FFI where cancelIoEx :: GHC.Internal.Windows.HANDLE -> LPOVERLAPPED -> GHC.Types.IO () cancelIoEx' :: GHC.Internal.Windows.HANDLE -> LPOVERLAPPED -> GHC.Types.IO GHC.Types.Bool getOverlappedResult :: GHC.Internal.Windows.HANDLE -> GHC.Internal.Ptr.Ptr OVERLAPPED -> GHC.Internal.Windows.BOOL -> GHC.Types.IO (GHC.Internal.Maybe.Maybe GHC.Internal.Windows.DWORD) - getQueuedCompletionStatusEx :: IOCP -> ghc-internal-0.1.0.0:GHC.Internal.Event.Array.Array OVERLAPPED_ENTRY -> GHC.Internal.Windows.DWORD -> GHC.Types.IO GHC.Types.Int + getQueuedCompletionStatusEx :: IOCP -> ghc-internal-9.1001.0:GHC.Internal.Event.Array.Array OVERLAPPED_ENTRY -> GHC.Internal.Windows.DWORD -> GHC.Types.IO GHC.Types.Int getTickCount64 :: GHC.Types.IO GHC.Internal.Word.Word64 newIOCP :: GHC.Types.IO IOCP overlappedIONumBytes :: LPOVERLAPPED -> GHC.Types.IO GHC.Internal.Event.Windows.FFI.ULONG_PTR @@ -5418,8 +5418,8 @@ module GHC.Event.Windows.ManagedThreadPool where thrCallBack :: GHC.Internal.Event.Windows.ManagedThreadPool.WorkerJob, thrActiveThreads :: GHC.Internal.MVar.MVar GHC.Types.Int, thrMonitor :: GHC.Internal.MVar.MVar (), - thrThreadIds :: ! {-# UNPACK #-}(ghc-internal-0.1.0.0:GHC.Internal.Event.Array.N:Array[0] _P - ; GHC.Internal.IORef.N:IORef[0] _N)(ghc-internal-0.1.0.0:GHC.Internal.Event.Array.Array GHC.Internal.Conc.Sync.ThreadId)} + thrThreadIds :: ! {-# UNPACK #-}(ghc-internal-9.1001.0:GHC.Internal.Event.Array.N:Array[0] _P + ; GHC.Internal.IORef.N:IORef[0] _N)(ghc-internal-9.1001.0:GHC.Internal.Event.Array.Array GHC.Internal.Conc.Sync.ThreadId)} monitorThreadPool :: GHC.Internal.MVar.MVar () -> GHC.Types.IO () notifyRunning :: GHC.Internal.Maybe.Maybe ThreadPool -> GHC.Types.IO () notifyWaiting :: GHC.Internal.Maybe.Maybe ThreadPool -> GHC.Types.IO () @@ -5442,7 +5442,7 @@ module GHC.Exception where type ErrorCall :: * data ErrorCall = ErrorCallWithLocation GHC.Internal.Base.String GHC.Internal.Base.String type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -5471,7 +5471,7 @@ module GHC.Exception.Type where type ArithException :: * data ArithException = Overflow | Underflow | LossOfPrecision | DivideByZero | Denormal | RatioZeroDenominator type Exception :: * -> Constraint - class (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where + class (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable e, GHC.Internal.Show.Show e) => Exception e where toException :: e -> SomeException fromException :: SomeException -> GHC.Internal.Maybe.Maybe e displayException :: e -> GHC.Internal.Base.String @@ -5558,6 +5558,8 @@ module GHC.Exts where data Compact# type Constraint :: * type Constraint = CONSTRAINT LiftedRep + type CostCentreId :: * + newtype CostCentreId = ... type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint class DataToTag a where dataToTag# :: a -> Int# @@ -5946,6 +5948,7 @@ module GHC.Exts where ctz64# :: Word64# -> Word# ctz8# :: Word# -> Word# currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] deRefStablePtr# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) deRefWeak# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) decodeDouble_2Int# :: Double# -> (# Int#, Word#, Word#, Int# #) @@ -8048,8 +8051,8 @@ module GHC.IO.Handle where hTryLock :: Handle -> LockMode -> GHC.Types.IO GHC.Types.Bool hWaitForInput :: Handle -> GHC.Types.Int -> GHC.Types.IO GHC.Types.Bool isEOF :: GHC.Types.IO GHC.Types.Bool - mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle - mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle + mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle + mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> NewlineMode -> GHC.Types.IO Handle nativeNewline :: Newline nativeNewlineMode :: NewlineMode noNewlineTranslation :: NewlineMode @@ -8099,11 +8102,11 @@ module GHC.IO.Handle.Internals where ioe_notReadable :: forall a. GHC.Types.IO a ioe_notWritable :: forall a. GHC.Types.IO a ioe_semiclosedHandle :: forall a. GHC.Types.IO a - mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkDuplexHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkFileHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle - mkHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.Handle.Types.HandleType -> GHC.Types.Bool -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Internal.Maybe.Maybe HandleFinalizer -> GHC.Internal.Maybe.Maybe (GHC.Internal.MVar.MVar GHC.Internal.IO.Handle.Types.Handle__) -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkDuplexHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkDuplexHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkFileHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkFileHandleNoFinalizer :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkHandle :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.Handle.Types.HandleType -> GHC.Types.Bool -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.NewlineMode -> GHC.Internal.Maybe.Maybe HandleFinalizer -> GHC.Internal.Maybe.Maybe (GHC.Internal.MVar.MVar GHC.Internal.IO.Handle.Types.Handle__) -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle openTextEncoding :: forall a. GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Internal.IO.Handle.Types.HandleType -> (forall es ds. GHC.Internal.Maybe.Maybe (GHC.Internal.IO.Encoding.Types.TextEncoder es) -> GHC.Internal.Maybe.Maybe (GHC.Internal.IO.Encoding.Types.TextDecoder ds) -> GHC.Types.IO a) -> GHC.Types.IO a readTextDevice :: GHC.Internal.IO.Handle.Types.Handle__ -> GHC.Internal.IO.Buffer.CharBuffer -> GHC.Types.IO GHC.Internal.IO.Buffer.CharBuffer readTextDeviceNonBlocking :: GHC.Internal.IO.Handle.Types.Handle__ -> GHC.Internal.IO.Buffer.CharBuffer -> GHC.Types.IO GHC.Internal.IO.Buffer.CharBuffer @@ -8167,7 +8170,7 @@ module GHC.IO.Handle.Types where type Handle__ :: * data Handle__ = forall dev enc_state dec_state. - (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => + (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => Handle__ {haDevice :: !dev, haType :: HandleType, haByteBuffer :: ! {-# UNPACK #-}(GHC.Internal.IORef.N:IORef[0] _N)(GHC.Internal.IORef.IORef (GHC.Internal.IO.Buffer.Buffer GHC.Internal.Word.Word8)), @@ -8199,7 +8202,7 @@ module GHC.IO.Handle.Types where module GHC.IO.Handle.Windows where -- Safety: Safe-Inferred handleToHANDLE :: GHC.Internal.IO.Handle.Types.Handle -> GHC.Types.IO GHC.Internal.Windows.HANDLE - mkHandleFromHANDLE :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.Device.IODeviceType -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle + mkHandleFromHANDLE :: forall dev. (GHC.Internal.IO.Device.RawIO dev, GHC.Internal.IO.Device.IODevice dev, GHC.Internal.IO.BufferedIO.BufferedIO dev, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable dev) => dev -> GHC.Internal.IO.Device.IODeviceType -> GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Internal.Maybe.Maybe GHC.Internal.IO.Encoding.Types.TextEncoding -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle openBinaryFile :: GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle openFile :: GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle openFileBlocking :: GHC.Internal.IO.FilePath -> GHC.Internal.IO.IOMode.IOMode -> GHC.Types.IO GHC.Internal.IO.Handle.Types.Handle @@ -9567,6 +9570,8 @@ module GHC.Stack where data CallStack = ... type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack type HasCallStack :: Constraint @@ -9574,14 +9579,17 @@ module GHC.Stack where type SrcLoc :: * data SrcLoc = SrcLoc {srcLocPackage :: [GHC.Types.Char], srcLocModule :: [GHC.Types.Char], srcLocFile :: [GHC.Types.Char], srcLocStartLine :: GHC.Types.Int, srcLocStartCol :: GHC.Types.Int, srcLocEndLine :: GHC.Types.Int, srcLocEndCol :: GHC.Types.Int} callStack :: HasCallStack => CallStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] emptyCallStack :: CallStack errorWithStackTrace :: forall a. GHC.Internal.Base.String -> a freezeCallStack :: CallStack -> CallStack @@ -9601,16 +9609,21 @@ module GHC.Stack.CCS where -- Safety: Safe type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] getCCSOf :: forall a. a -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) getCurrentCCS :: forall dummy. dummy -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) renderStack :: [GHC.Internal.Base.String] -> GHC.Internal.Base.String @@ -9644,7 +9657,7 @@ module GHC.StaticPtr where -- Safety: None type IsStatic :: (* -> *) -> Constraint class IsStatic p where - fromStaticPtr :: forall a. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a => StaticPtr a -> p a + fromStaticPtr :: forall a. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a => StaticPtr a -> p a {-# MINIMAL fromStaticPtr #-} type StaticKey :: * type StaticKey = GHC.Internal.Fingerprint.Type.Fingerprint @@ -11084,8 +11097,8 @@ module Type.Reflection where data (:~~:) a b where HRefl :: forall {k1} (a :: k1). (:~~:) a a pattern App :: forall k2 (t :: k2). () => forall k1 (a :: k1 -> k2) (b :: k1). (t ~ a b) => TypeRep a -> TypeRep b -> TypeRep t - pattern Con :: forall k (a :: k). () => ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> TypeRep a - pattern Con' :: forall k (a :: k). () => ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> [SomeTypeRep] -> TypeRep a + pattern Con :: forall k (a :: k). () => ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> TypeRep a + pattern Con' :: forall k (a :: k). () => ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.NotApplication a => TyCon -> [SomeTypeRep] -> TypeRep a pattern Fun :: forall k (fun :: k). () => forall (r1 :: GHC.Types.RuntimeRep) (r2 :: GHC.Types.RuntimeRep) (arg :: TYPE r1) (res :: TYPE r2). (k ~ *, fun ~~ (arg -> res)) => TypeRep arg -> TypeRep res -> TypeRep fun type Module :: * data Module = ... @@ -11102,7 +11115,7 @@ module Type.Reflection where type Typeable :: forall k. k -> Constraint class Typeable a where ... - {-# MINIMAL ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} + {-# MINIMAL ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.typeRep# #-} decTypeRep :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> GHC.Internal.Data.Either.Either ((a :~~: b) -> GHC.Internal.Base.Void) (a :~~: b) eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> GHC.Internal.Maybe.Maybe (a :~~: b) moduleName :: Module -> GHC.Internal.Base.String @@ -11137,9 +11150,9 @@ module Type.Reflection.Unsafe where data TypeRep a where ... mkTrApp :: forall k1 k2 (a :: k1 -> k2) (b :: k1). TypeRep a -> TypeRep b -> TypeRep (a b) - mkTrCon :: forall k (a :: k). TyCon -> [ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep] -> TypeRep a + mkTrCon :: forall k (a :: k). TyCon -> [ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep] -> TypeRep a mkTyCon :: GHC.Internal.Base.String -> GHC.Internal.Base.String -> GHC.Internal.Base.String -> GHC.Types.Int -> KindRep -> TyCon - someTypeRepFingerprint :: ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -> GHC.Internal.Fingerprint.Type.Fingerprint + someTypeRepFingerprint :: ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -> GHC.Internal.Fingerprint.Type.Fingerprint tyConFingerprint :: TyCon -> GHC.Internal.Fingerprint.Type.Fingerprint tyConKindArgs :: TyCon -> GHC.Types.Int tyConKindRep :: TyCon -> KindRep @@ -11654,20 +11667,20 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.First -- Defined instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined in ‘Data.Semigroup’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’ -instance forall (a :: * -> * -> *) b c. (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’ -instance forall (m :: * -> *) a. (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’ +instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’ +instance forall (m :: * -> *) a. (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Internal.Functor.ZipList.ZipList a) -- Defined in ‘GHC.Internal.Functor.ZipList’ instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’ -instance forall s. ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable s => GHC.Internal.Data.Data.Data (Data.Array.Byte.MutableByteArray s) -- Defined in ‘Data.Array.Byte’ +instance forall s. ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable s => GHC.Internal.Data.Data.Data (Data.Array.Byte.MutableByteArray s) -- Defined in ‘Data.Array.Byte’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Complex.Complex a) -- Defined in ‘Data.Complex’ -instance forall i j (a :: i) (b :: j). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable i, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable j, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b, a ~~ b) => GHC.Internal.Data.Data.Data (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Data’ +instance forall i j (a :: i) (b :: j). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable i, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable j, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b, a ~~ b) => GHC.Internal.Data.Data.Data (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Data’ instance forall a b. (GHC.Internal.Data.Data.Data a, GHC.Internal.Data.Data.Data b, GHC.Internal.Ix.Ix a) => GHC.Internal.Data.Data.Data (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Bool -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Char -- Defined in ‘GHC.Internal.Data.Data’ -instance forall k a (b :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable b) => GHC.Internal.Data.Data.Data (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Data’ +instance forall k a (b :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable b) => GHC.Internal.Data.Data.Data (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Data’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Types.Double -- Defined in ‘GHC.Internal.Data.Data’ @@ -11715,10 +11728,10 @@ instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word32 -- Defined in ‘G instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word64 -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Word.Word8 -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Data.Data.Data GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Data.Data’ -instance forall k (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a) => GHC.Internal.Data.Data.Data (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ -instance forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k1, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k2, GHC.Internal.Data.Data.Data (f (g a))) => GHC.Internal.Data.Data.Data (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ -instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ -instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Sum.Sum f g a) -- Defined in ‘Data.Functor.Sum’ +instance forall k (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a) => GHC.Internal.Data.Data.Data (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ +instance forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k1, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k2, GHC.Internal.Data.Data.Data (f (g a))) => GHC.Internal.Data.Data.Data (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ +instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance [safe] forall k (f :: k -> *) (g :: k -> *) (a :: k). (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable f, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable g, ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.Typeable k, GHC.Internal.Data.Data.Data (f a), GHC.Internal.Data.Data.Data (g a)) => GHC.Internal.Data.Data.Data (Data.Functor.Sum.Sum f g a) -- Defined in ‘Data.Functor.Sum’ instance forall a b. (GHC.Internal.Data.Data.Data a, GHC.Internal.Data.Data.Data b) => GHC.Internal.Data.Data.Data (Data.Semigroup.Arg a b) -- Defined in ‘Data.Semigroup’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Semigroup.First a) -- Defined in ‘Data.Semigroup’ instance forall a. GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Semigroup.Last a) -- Defined in ‘Data.Semigroup’ @@ -11784,7 +11797,7 @@ instance GHC.Internal.Data.Type.Equality.TestEquality GHC.Internal.TypeLits.SCha instance GHC.Internal.Data.Type.Equality.TestEquality GHC.Internal.TypeLits.SSymbol -- Defined in ‘GHC.Internal.TypeLits’ instance forall k (a :: k). GHC.Internal.Data.Type.Equality.TestEquality ((GHC.Internal.Data.Type.Equality.:~:) a) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k1 k (a :: k1). GHC.Internal.Data.Type.Equality.TestEquality ((GHC.Internal.Data.Type.Equality.:~~:) a) -- Defined in ‘GHC.Internal.Data.Type.Equality’ -instance forall k. GHC.Internal.Data.Type.Equality.TestEquality ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k. GHC.Internal.Data.Type.Equality.TestEquality ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1). GHC.Internal.Data.Type.Equality.TestEquality f => GHC.Internal.Data.Type.Equality.TestEquality (Data.Functor.Compose.Compose f g) -- Defined in ‘Data.Functor.Compose’ instance forall a k (b :: k). GHC.Internal.Enum.Bounded a => GHC.Internal.Enum.Bounded (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall a. GHC.Internal.Enum.Bounded a => GHC.Internal.Enum.Bounded (GHC.Internal.Data.Bits.And a) -- Defined in ‘GHC.Internal.Data.Bits’ @@ -11864,6 +11877,7 @@ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CULong -- Define instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Bounded GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.SourceStrictness -- Defined in ‘GHC.Internal.Generics’ @@ -11940,6 +11954,7 @@ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUShort -- Defined instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Internal.Enum.Enum GHC.Internal.Event.Windows.ConsoleEvent.ConsoleEvent -- Defined in ‘GHC.Internal.Event.Windows.ConsoleEvent’ +instance GHC.Internal.Enum.Enum GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Enum GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ @@ -11982,7 +11997,7 @@ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Ba instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Base.RecUpdError -- Defined in ‘GHC.Internal.Control.Exception.Base’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Control.Exception.Base.TypeError -- Defined in ‘GHC.Internal.Control.Exception.Base’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’ -instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common’ +instance [safe] GHC.Internal.Exception.Type.Exception ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common’ instance GHC.Internal.Exception.Type.Exception GHC.Internal.IOPort.IOPortException -- Defined in ‘GHC.Internal.IOPort’ instance [safe] GHC.Internal.Exception.Type.Exception System.Timeout.Timeout -- Defined in ‘System.Timeout’ instance forall a k (b :: k). GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ @@ -12336,6 +12351,7 @@ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CULong -- Defined in instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Num.Num GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Num.Num GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Int -- Defined in ‘GHC.Internal.Num’ @@ -12448,6 +12464,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Internal.Read.Read GHC.Internal.Event.Windows.ConsoleEvent.ConsoleEvent -- Defined in ‘GHC.Internal.Event.Windows.ConsoleEvent’ +instance GHC.Internal.Read.Read GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k2 (f :: k2 -> *) k1 (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -12521,6 +12538,7 @@ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULLong -- Defi instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULong -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Integral GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall a k (b :: k). GHC.Internal.Real.Real a => GHC.Internal.Real.Real (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Real (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Real.Real (f (g a)) => GHC.Internal.Real.Real (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -12567,6 +12585,7 @@ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CULong -- Defined i instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Real GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Real.Real GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Real.Real GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance forall a k (b :: k). GHC.Internal.Real.RealFrac a => GHC.Internal.Real.RealFrac (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ @@ -12666,8 +12685,8 @@ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.DataRep -- Defined in ‘ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.DataType -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Internal.Show.Show GHC.Internal.Data.Data.Fixity -- Defined in ‘GHC.Internal.Data.Data’ instance forall k (s :: k). GHC.Internal.Show.Show (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Internal.Show.Show ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Internal.Show.Show (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Internal.Show.Show (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance GHC.Internal.Show.Show GHC.Internal.Data.Dynamic.Dynamic -- Defined in ‘GHC.Internal.Data.Dynamic’ instance forall a b. (GHC.Internal.Show.Show a, GHC.Internal.Show.Show b) => GHC.Internal.Show.Show (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Show.Show (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ @@ -12742,6 +12761,7 @@ instance GHC.Internal.Show.Show GHC.Internal.Event.Windows.ConsoleEvent.ConsoleE instance forall a. GHC.Internal.Show.Show a => GHC.Internal.Show.Show (GHC.Internal.Event.Windows.CbResult a) -- Defined in ‘GHC.Internal.Event.Windows’ instance GHC.Internal.Show.Show GHC.Internal.Event.Windows.HandleKey -- Defined in ‘GHC.Internal.Event.Windows’ instance GHC.Internal.Show.Show GHC.Internal.Event.Windows.FFI.IOCP -- Defined in ‘GHC.Internal.Event.Windows.FFI’ +instance GHC.Internal.Show.Show GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Show.Show GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance GHC.Internal.Show.Show GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Show.Show GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ @@ -12774,7 +12794,7 @@ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.Handle -- Defined i instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.HandleType -- Defined in ‘GHC.Internal.IO.Handle.Types’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’ -instance [safe] GHC.Internal.Show.Show ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.IO.Handle.Lock.Common’ +instance [safe] GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common.FileLockingNotSupported -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.IO.Handle.Lock.Common’ instance GHC.Internal.Show.Show GHC.Internal.IO.Handle.HandlePosn -- Defined in ‘GHC.Internal.IO.Handle’ instance GHC.Internal.Show.Show GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’ instance GHC.Internal.Show.Show GHC.Internal.IO.Windows.Handle.CONSOLE_READCONSOLE_CONTROL -- Defined in ‘GHC.Internal.IO.Windows.Handle’ @@ -12872,8 +12892,8 @@ instance GHC.Classes.Eq GHC.Internal.Data.Data.ConstrRep -- Defined in ‘GHC.In instance GHC.Classes.Eq GHC.Internal.Data.Data.DataRep -- Defined in ‘GHC.Internal.Data.Data’ instance GHC.Classes.Eq GHC.Internal.Data.Data.Fixity -- Defined in ‘GHC.Internal.Data.Data’ instance forall k (s :: k). GHC.Classes.Eq (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Classes.Eq ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Classes.Eq (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Classes.Eq ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Classes.Eq (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall a b. (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). GHC.Classes.Eq (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Classes.Eq (f (g a)) => GHC.Classes.Eq (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -12954,6 +12974,7 @@ instance GHC.Classes.Eq GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘G instance GHC.Classes.Eq GHC.Internal.Event.Windows.HandleKey -- Defined in ‘GHC.Internal.Event.Windows’ instance GHC.Classes.Eq GHC.Internal.Event.Windows.FFI.IOCP -- Defined in ‘GHC.Internal.Event.Windows.FFI’ instance GHC.Classes.Eq GHC.Internal.Stack.Types.SrcLoc -- Defined in ‘GHC.Internal.Stack.Types’ +instance GHC.Classes.Eq GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Eq GHC.Internal.Exts.SpecConstrAnnotation -- Defined in ‘GHC.Internal.Exts’ instance GHC.Classes.Eq GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -13049,8 +13070,8 @@ instance GHC.Classes.Ord GHC.Internal.Unicode.GeneralCategory -- Defined in ‘G instance forall k (a :: k) (b :: k). GHC.Classes.Ord (a GHC.Internal.Data.Type.Equality.:~: b) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k1 k2 (a :: k1) (b :: k2). GHC.Classes.Ord (a GHC.Internal.Data.Type.Equality.:~~: b) -- Defined in ‘GHC.Internal.Data.Type.Equality’ instance forall k (s :: k). GHC.Classes.Ord (GHC.Internal.Data.Proxy.Proxy s) -- Defined in ‘GHC.Internal.Data.Proxy’ -instance GHC.Classes.Ord ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ -instance forall k (a :: k). GHC.Classes.Ord (ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-0.1.0.0:GHC.Internal.Data.Typeable.Internal’ +instance GHC.Classes.Ord ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.SomeTypeRep -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ +instance forall k (a :: k). GHC.Classes.Ord (ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal.TypeRep a) -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Data.Typeable.Internal’ instance forall a b. (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (GHC.Internal.Data.Either.Either a b) -- Defined in ‘GHC.Internal.Data.Either’ instance forall k (a :: k). GHC.Classes.Ord (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Classes.Ord (f (g a)) => GHC.Classes.Ord (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -13123,6 +13144,7 @@ instance GHC.Classes.Ord GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.I instance GHC.Classes.Ord GHC.Internal.Event.Windows.ConsoleEvent.ConsoleEvent -- Defined in ‘GHC.Internal.Event.Windows.ConsoleEvent’ instance GHC.Classes.Ord GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ instance GHC.Classes.Ord GHC.Internal.Event.Windows.FFI.IOCP -- Defined in ‘GHC.Internal.Event.Windows.FFI’ +instance GHC.Classes.Ord GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Ord GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -5412,6 +5412,8 @@ module GHC.Exts where data Compact# type Constraint :: * type Constraint = CONSTRAINT LiftedRep + type CostCentreId :: * + newtype CostCentreId = ... type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint class DataToTag a where dataToTag# :: a -> Int# @@ -5797,6 +5799,7 @@ module GHC.Exts where ctz64# :: Word64# -> Word# ctz8# :: Word# -> Word# currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] deRefStablePtr# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) deRefWeak# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) decodeDouble_2Int# :: Double# -> (# Int#, Word#, Word#, Int# #) @@ -9343,6 +9346,8 @@ module GHC.Stack where data CallStack = ... type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack type HasCallStack :: Constraint @@ -9350,14 +9355,17 @@ module GHC.Stack where type SrcLoc :: * data SrcLoc = SrcLoc {srcLocPackage :: [GHC.Types.Char], srcLocModule :: [GHC.Types.Char], srcLocFile :: [GHC.Types.Char], srcLocStartLine :: GHC.Types.Int, srcLocStartCol :: GHC.Types.Int, srcLocEndLine :: GHC.Types.Int, srcLocEndCol :: GHC.Types.Int} callStack :: HasCallStack => CallStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] emptyCallStack :: CallStack errorWithStackTrace :: forall a. GHC.Internal.Base.String -> a freezeCallStack :: CallStack -> CallStack @@ -9377,16 +9385,21 @@ module GHC.Stack.CCS where -- Safety: Safe type CostCentre :: * data CostCentre + type CostCentreId :: * + newtype CostCentreId = ... type CostCentreStack :: * data CostCentreStack + ccId :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO CostCentreId ccLabel :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccModule :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccSrcSpan :: GHC.Internal.Ptr.Ptr CostCentre -> GHC.Types.IO GHC.Internal.Foreign.C.String.Encoding.CString ccsCC :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentre) ccsParent :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) + ccsToIds :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [CostCentreId] ccsToStrings :: GHC.Internal.Ptr.Ptr CostCentreStack -> GHC.Types.IO [GHC.Internal.Base.String] clearCCS :: forall a. GHC.Types.IO a -> GHC.Types.IO a currentCallStack :: GHC.Types.IO [GHC.Internal.Base.String] + currentCallStackIds :: GHC.Types.IO [CostCentreId] getCCSOf :: forall a. a -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) getCurrentCCS :: forall dummy. dummy -> GHC.Types.IO (GHC.Internal.Ptr.Ptr CostCentreStack) renderStack :: [GHC.Internal.Base.String] -> GHC.Internal.Base.String @@ -11600,6 +11613,7 @@ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CULong -- Define instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Bounded GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Bounded GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.DecidedStrictness -- Defined in ‘GHC.Internal.Generics’ instance GHC.Internal.Enum.Bounded GHC.Internal.Generics.SourceStrictness -- Defined in ‘GHC.Internal.Generics’ @@ -11675,6 +11689,7 @@ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Enum.Enum GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Enum.Enum GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Enum.Enum GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Enum.Enum GHC.Internal.Generics.Associativity -- Defined in ‘GHC.Internal.Generics’ @@ -12059,6 +12074,7 @@ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CULong -- Defined in instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Num.Num GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Num.Num GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Num.Num GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Num.Num GHC.Types.Int -- Defined in ‘GHC.Internal.Num’ @@ -12170,6 +12186,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Define instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ +instance GHC.Internal.Read.Read GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k2 (f :: k2 -> *) k1 (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -12243,6 +12260,7 @@ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULLong -- Defi instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CULong -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Integral GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Integral GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance forall a k (b :: k). GHC.Internal.Real.Real a => GHC.Internal.Real.Real (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Real (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’ instance forall k1 k2 (f :: k1 -> *) (g :: k2 -> k1) (a :: k2). GHC.Internal.Real.Real (f (g a)) => GHC.Internal.Real.Real (Data.Functor.Compose.Compose f g a) -- Defined in ‘Data.Functor.Compose’ @@ -12289,6 +12307,7 @@ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CULong -- Defined i instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’ instance GHC.Internal.Real.Real GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’ +instance GHC.Internal.Real.Real GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Real.Real GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Real.Real GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ instance forall a k (b :: k). GHC.Internal.Real.RealFrac a => GHC.Internal.Real.RealFrac (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’ @@ -12467,6 +12486,7 @@ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Interna instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Manager.FdKey -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.Manager’ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.Manager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.Manager’ instance GHC.Internal.Show.Show ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager’ +instance GHC.Internal.Show.Show GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Internal.Show.Show GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance GHC.Internal.Show.Show GHC.Types.Double -- Defined in ‘GHC.Internal.Float’ instance GHC.Internal.Show.Show GHC.Types.Float -- Defined in ‘GHC.Internal.Float’ @@ -12680,6 +12700,7 @@ instance GHC.Classes.Eq GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘G instance GHC.Classes.Eq ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager.State -- Defined in ‘ghc-internal-9.1001.0:GHC.Internal.Event.TimerManager’ instance GHC.Classes.Eq GHC.Internal.Stack.Types.SrcLoc -- Defined in ‘GHC.Internal.Stack.Types’ instance GHC.Classes.Eq GHC.Internal.Exts.SpecConstrAnnotation -- Defined in ‘GHC.Internal.Exts’ +instance GHC.Classes.Eq GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Eq GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ @@ -12845,6 +12866,7 @@ instance forall a. GHC.Classes.Ord (GHC.Internal.Foreign.C.ConstPtr.ConstPtr a) instance forall i e. (GHC.Internal.Ix.Ix i, GHC.Classes.Ord e) => GHC.Classes.Ord (GHC.Internal.Arr.Array i e) -- Defined in ‘GHC.Internal.Arr’ instance GHC.Classes.Ord GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.ByteOrder’ instance GHC.Classes.Ord GHC.Internal.Event.TimeOut.TimeoutKey -- Defined in ‘GHC.Internal.Event.TimeOut’ +instance GHC.Classes.Ord GHC.Internal.Stack.CCS.CostCentreId -- Defined in ‘GHC.Internal.Stack.CCS’ instance GHC.Classes.Ord GHC.Internal.Fingerprint.Type.Fingerprint -- Defined in ‘GHC.Internal.Fingerprint.Type’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’ instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0206cc7cb47bb82d9d83e849047ae23c1f3a4ad0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0206cc7cb47bb82d9d83e849047ae23c1f3a4ad0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 19:07:37 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 09 Apr 2024 15:07:37 -0400 Subject: [Git][ghc/ghc][wip/multiline-strings] 71 commits: rts: Fix TSAN_ENABLED CPP guard Message-ID: <661591f989661_1002b4228706014529f@gitlab.mail> Ben Gamari pushed to branch wip/multiline-strings at Glasgow Haskell Compiler / GHC Commits: c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 9d482cdd by Brandon Chinn at 2024-04-09T12:35:25-04:00 Add MultilineStrings extension - - - - - e74f63a5 by Brandon Chinn at 2024-04-09T15:06:51-04:00 Add test cases for MultilineStrings - - - - - 03e6fa73 by Brandon Chinn at 2024-04-09T15:06:51-04:00 Break out common lex_magic_hash logic for strings and chars - - - - - 60b5adce by Brandon Chinn at 2024-04-09T15:06:51-04:00 Factor out string processing functions - - - - - f826ad9a by Brandon Chinn at 2024-04-09T15:06:51-04:00 Implement MultilineStrings (#24390) Updates haddock submodule for new ITmultiline constructor - - - - - f0540383 by Brandon Chinn at 2024-04-09T15:06:51-04:00 Add docs for MultilineStrings - - - - - 19 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3aa8bea0e1da042d78522ca9ebd738cfa3226131...f05403832e8781122e275cc3b01bbe1190b9656b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3aa8bea0e1da042d78522ca9ebd738cfa3226131...f05403832e8781122e275cc3b01bbe1190b9656b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 9 22:05:41 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 18:05:41 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Validate -main-is flag using parseIdentifier Message-ID: <6615bbb5ca42b_1002b438ae71c1688d7@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 82da59cc by Jade at 2024-04-09T18:05:24-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - 313d3539 by Rodrigo Mesquita at 2024-04-09T18:05:24-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 627e92f5 by Alexis King at 2024-04-09T18:05:24-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - a47165f8 by Rodrigo Mesquita at 2024-04-09T18:05:24-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 6969a71e by Rodrigo Mesquita at 2024-04-09T18:05:24-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - c4b79e52 by Ben Gamari at 2024-04-09T18:05:24-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 3fb014ec by Zejun Wu at 2024-04-09T18:05:26-04:00 Make renamer to be more flexible with parens in the LHS of the rules We used to reject LHS like `(f a) b` in RULES and requires it to be written as `f a b`. It will be handy to allow both as the expression may be more readable with extra parens in some cases when infix operator is involved. Espceially when TemplateHaskell is used, extra parens may be added out of user's control and result in "valid" rules being rejected and there are not always ways to workaround it. Fixes #24621 - - - - - 227861c1 by Alan Zimmerman at 2024-04-09T18:05:27-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7867e9c33e842466230461c47ed6a634194bf80e...227861c177262d6cf37ce1bbbd546db8a0f4f44a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7867e9c33e842466230461c47ed6a634194bf80e...227861c177262d6cf37ce1bbbd546db8a0f4f44a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 01:16:28 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 09 Apr 2024 21:16:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Validate -main-is flag using parseIdentifier Message-ID: <6615e86be094e_1002b44f913a8192637@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 96975c21 by Jade at 2024-04-09T21:16:04-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - ba347b8c by Rodrigo Mesquita at 2024-04-09T21:16:05-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 9f68bf7c by Alexis King at 2024-04-09T21:16:05-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 7a7a4d99 by Rodrigo Mesquita at 2024-04-09T21:16:05-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 64231ae3 by Rodrigo Mesquita at 2024-04-09T21:16:05-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 3399444b by Ben Gamari at 2024-04-09T21:16:05-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - a4641617 by Zejun Wu at 2024-04-09T21:16:07-04:00 Make renamer to be more flexible with parens in the LHS of the rules We used to reject LHS like `(f a) b` in RULES and requires it to be written as `f a b`. It will be handy to allow both as the expression may be more readable with extra parens in some cases when infix operator is involved. Espceially when TemplateHaskell is used, extra parens may be added out of user's control and result in "valid" rules being rejected and there are not always ways to workaround it. Fixes #24621 - - - - - b60f360a by Alan Zimmerman at 2024-04-09T21:16:08-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/227861c177262d6cf37ce1bbbd546db8a0f4f44a...b60f360a9fefd562d636f25413dd89161b3f3a9c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/227861c177262d6cf37ce1bbbd546db8a0f4f44a...b60f360a9fefd562d636f25413dd89161b3f3a9c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 04:57:31 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 10 Apr 2024 00:57:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Validate -main-is flag using parseIdentifier Message-ID: <66161c3b38740_82c2a15d326025461@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bf18a62d by Jade at 2024-04-10T00:56:58-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - 4bd2f403 by Rodrigo Mesquita at 2024-04-10T00:56:58-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 1d948462 by Alexis King at 2024-04-10T00:56:58-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 6449b741 by Rodrigo Mesquita at 2024-04-10T00:56:58-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 79745090 by Rodrigo Mesquita at 2024-04-10T00:56:58-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 1eaeba34 by Ben Gamari at 2024-04-10T00:56:58-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 31b38d94 by Zejun Wu at 2024-04-10T00:57:00-04:00 Make renamer to be more flexible with parens in the LHS of the rules We used to reject LHS like `(f a) b` in RULES and requires it to be written as `f a b`. It will be handy to allow both as the expression may be more readable with extra parens in some cases when infix operator is involved. Espceially when TemplateHaskell is used, extra parens may be added out of user's control and result in "valid" rules being rejected and there are not always ways to workaround it. Fixes #24621 - - - - - f8164b3d by Alan Zimmerman at 2024-04-10T00:57:01-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b60f360a9fefd562d636f25413dd89161b3f3a9c...f8164b3d0ef876ba95868bff73c9789ffdc72f65 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b60f360a9fefd562d636f25413dd89161b3f3a9c...f8164b3d0ef876ba95868bff73c9789ffdc72f65 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 06:39:51 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 10 Apr 2024 02:39:51 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Validate -main-is flag using parseIdentifier Message-ID: <66163437c7269_82c2a217873c3785@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5b4c8842 by Jade at 2024-04-10T02:39:45-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - d61858d3 by Rodrigo Mesquita at 2024-04-10T02:39:46-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - 9aaaa44d by Alexis King at 2024-04-10T02:39:46-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - 20bf9203 by Rodrigo Mesquita at 2024-04-10T02:39:46-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - e5572eea by Rodrigo Mesquita at 2024-04-10T02:39:46-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - 5799efae by Ben Gamari at 2024-04-10T02:39:46-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - c2f122cd by Alan Zimmerman at 2024-04-10T02:39:46-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8164b3d0ef876ba95868bff73c9789ffdc72f65...c2f122cd5ace356dd6a68bbc74db51ecc7c49459 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8164b3d0ef876ba95868bff73c9789ffdc72f65...c2f122cd5ace356dd6a68bbc74db51ecc7c49459 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 07:24:03 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 10 Apr 2024 03:24:03 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] WIP: TrieMap for IfaceType Message-ID: <66163e9387848_c98b0556ce8306eb@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 600b157a by Matthew Pickering at 2024-04-10T09:23:43+02:00 WIP: TrieMap for IfaceType - - - - - 8 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -58,6 +58,7 @@ import Data.IORef import Control.Monad import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) import System.IO.Unsafe +import GHC.Iface.Type.Map (IfaceTypeMap) -- --------------------------------------------------------------------------- @@ -369,7 +370,7 @@ initReadIfaceTypeTable ud = do initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) initWriteIfaceType = do - sym_tab <- initGenericSymbolTable + sym_tab <- initGenericSymbolTable @IfaceTypeMap pure ( WriterTable { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -112,6 +112,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -2,6 +2,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE AllowAmbiguousTypes #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} {-# LANGUAGE TypeFamilies #-} @@ -136,7 +137,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (sortOn, unfoldr) +import Data.List (unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -150,6 +151,9 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import Data.Coerce +import GHC.Data.TrieMap + + type BinArray = ForeignPtr Word8 @@ -1348,44 +1352,47 @@ data WriterTable = WriterTable -- binary serialisation and deserialisation. -- ---------------------------------------------------------------------------- -data GenericSymbolTable a = GenericSymbolTable +data GenericSymbolTable m = GenericSymbolTable { gen_symtab_next :: !FastMutInt -- ^ The next index to use - , gen_symtab_map :: !(IORef (Map.Map a Int)) + , gen_symtab_map :: !(IORef (m Int)) -- ^ Given a symbol, find the symbol + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer } -initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) initGenericSymbolTable = do symtab_next <- newFastMutInt 0 - symtab_map <- newIORef Map.empty + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] pure $ GenericSymbolTable { gen_symtab_next = symtab_next , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo } -putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int putGenericSymbolTable gen_sym_tab serialiser bh = do putGenericSymbolTable bh where - symtab_map = gen_symtab_map gen_sym_tab symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int putGenericSymbolTable bh = do - let loop bound = do - d <- readIORef symtab_map - table_count <- readFastMutInt symtab_next - let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) case vs of - [] -> return table_count + [] -> readFastMutInt symtab_next todo -> do - mapM_ (\n -> serialiser bh n) (map snd todo) - loop table_count + mapM_ (\n -> serialiser bh n) (reverse todo) + loop snd <$> (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ - loop 0) + loop) -getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do sz <- forwardGet bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) @@ -1397,19 +1404,22 @@ getGenericSymbolTable deserialiser bh = do writeArray mut_arr i f unsafeFreeze mut_arr -putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +{-# INLINE putGenericSymTab #-} +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () putGenericSymTab GenericSymbolTable{ gen_symtab_map = symtab_map_ref, - gen_symtab_next = symtab_next } + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } bh val = do symtab_map <- readIORef symtab_map_ref - case Map.lookup val symtab_map of + case lookupTM val symtab_map of Just off -> put_ bh (fromIntegral off :: Word32) Nothing -> do off <- readFastMutInt symtab_next writeFastMutInt symtab_next (off+1) writeIORef symtab_map_ref - $! Map.insert val off symtab_map + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) put_ bh (fromIntegral off :: Word32) getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/600b157a0bc6f9063fbed88fe3b65ed2d04a55cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/600b157a0bc6f9063fbed88fe3b65ed2d04a55cf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 08:24:52 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 10 Apr 2024 04:24:52 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] WIP: TrieMap for IfaceType Message-ID: <66164cd42cb53_c98b0d5163c339dc@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: bd21cc37 by Matthew Pickering at 2024-04-10T10:24:34+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 9 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -58,6 +58,7 @@ import Data.IORef import Control.Monad import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) import System.IO.Unsafe +import GHC.Iface.Type.Map (IfaceTypeMap) -- --------------------------------------------------------------------------- @@ -369,7 +370,7 @@ initReadIfaceTypeTable ud = do initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) initWriteIfaceType = do - sym_tab <- initGenericSymbolTable + sym_tab <- initGenericSymbolTable @IfaceTypeMap pure ( WriterTable { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -112,6 +112,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -2,6 +2,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE AllowAmbiguousTypes #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} {-# LANGUAGE TypeFamilies #-} @@ -136,7 +137,7 @@ import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time -import Data.List (sortOn, unfoldr) +import Data.List (unfoldr) import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) @@ -150,6 +151,9 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import Data.Coerce +import GHC.Data.TrieMap + + type BinArray = ForeignPtr Word8 @@ -1348,44 +1352,47 @@ data WriterTable = WriterTable -- binary serialisation and deserialisation. -- ---------------------------------------------------------------------------- -data GenericSymbolTable a = GenericSymbolTable +data GenericSymbolTable m = GenericSymbolTable { gen_symtab_next :: !FastMutInt -- ^ The next index to use - , gen_symtab_map :: !(IORef (Map.Map a Int)) + , gen_symtab_map :: !(IORef (m Int)) -- ^ Given a symbol, find the symbol + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer } -initGenericSymbolTable :: IO (GenericSymbolTable a) +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) initGenericSymbolTable = do symtab_next <- newFastMutInt 0 - symtab_map <- newIORef Map.empty + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] pure $ GenericSymbolTable { gen_symtab_next = symtab_next , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo } -putGenericSymbolTable :: forall a. GenericSymbolTable a -> (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> IO Int +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int putGenericSymbolTable gen_sym_tab serialiser bh = do putGenericSymbolTable bh where - symtab_map = gen_symtab_map gen_sym_tab symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int putGenericSymbolTable bh = do - let loop bound = do - d <- readIORef symtab_map - table_count <- readFastMutInt symtab_next - let vs = sortOn fst [(b, a) | (a,b) <- Map.toList d, b >= bound] + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) case vs of - [] -> return table_count + [] -> readFastMutInt symtab_next todo -> do - mapM_ (\n -> serialiser bh n) (map snd todo) - loop table_count + mapM_ (\n -> serialiser bh n) (reverse todo) + loop snd <$> (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ - loop 0) + loop) -getGenericSymbolTable :: forall a. (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do sz <- forwardGet bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) @@ -1397,19 +1404,22 @@ getGenericSymbolTable deserialiser bh = do writeArray mut_arr i f unsafeFreeze mut_arr -putGenericSymTab :: (Ord a, Binary a) => GenericSymbolTable a -> WriteBinHandle -> a -> IO () +{-# INLINE putGenericSymTab #-} +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () putGenericSymTab GenericSymbolTable{ gen_symtab_map = symtab_map_ref, - gen_symtab_next = symtab_next } + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } bh val = do symtab_map <- readIORef symtab_map_ref - case Map.lookup val symtab_map of + case lookupTM val symtab_map of Just off -> put_ bh (fromIntegral off :: Word32) Nothing -> do off <- readFastMutInt symtab_next writeFastMutInt symtab_next (off+1) writeIORef symtab_map_ref - $! Map.insert val off symtab_map + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) put_ bh (fromIntegral off :: Word32) getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit e095ca841b89b5958376768d18ae156b7a413da0 +Subproject commit 0b64da5b51dac5124b6516af1c402a83ca9d0a0d View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd21cc372e4a7d3783607896a66736019b9bcb21 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd21cc372e4a7d3783607896a66736019b9bcb21 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 08:30:49 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 10 Apr 2024 04:30:49 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <66164e399aa06_c98b0eab4883676b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 68d406f8 by Fendor at 2024-04-10T10:11:27+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: T21839c ------------------------- - - - - - 026372f7 by Fendor at 2024-04-10T10:11:27+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +233,35 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +-- See Note [Iface Binary Serialiser Order] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +273,150 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: + +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser instead of + directly serialising itself. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + +* Whenever a value of 'IfaceTyCon' is serialised, the real serialisation function needs to + be configured in the User Data. + + For example, for 'IfaceTyCon': + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + Now, here we can introduce the deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a 'Map' and remembers the offset + of each value we have already seen. + Instead of serialising the full 'IfaceTyCon', we only write the index of the value to disk. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +425,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +446,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +470,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +495,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +514,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,12 +103,14 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +122,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +139,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1366,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1400,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1447,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e79b463691f12528ca6e4bf7b1744388c248d183...026372f78d3a762a46e7135d869092062e7c3b20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e79b463691f12528ca6e4bf7b1744388c248d183...026372f78d3a762a46e7135d869092062e7c3b20 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 08:46:38 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 10 Apr 2024 04:46:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/iface-sharing Message-ID: <661651ee54fe7_c98b01134d5840971@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/iface-sharing at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/iface-sharing You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:30:00 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 10 Apr 2024 05:30:00 -0400 Subject: [Git][ghc/ghc][wip/t24631] driver: Use correct DynFlags when emitting unecessary source pragma warning Message-ID: <66165c181c806_c98b016286fc46043@gitlab.mail> Matthew Pickering pushed to branch wip/t24631 at Glasgow Haskell Compiler / GHC Commits: 256dabce by Matthew Pickering at 2024-04-10T10:29:31+01:00 driver: Use correct DynFlags when emitting unecessary source pragma warning We were using the global DynFlags in order to determine whether to emit the unecessary source imports warning, instead we should use the per-module DynFlags so that local GHC_OPTIONS are honoured. Fixes #24631 - - - - - 5 changed files: - compiler/GHC/Driver/Make.hs - + testsuite/tests/driver/T24631.hs - + testsuite/tests/driver/T24631A.hs - + testsuite/tests/driver/T24631A.hs-boot - testsuite/tests/driver/all.T Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1516,17 +1516,15 @@ modNodeMapUnionWith f (ModNodeMap m) (ModNodeMap n) = ModNodeMap (M.unionWith f -- were necessary, then the edge would be part of a cycle. warnUnnecessarySourceImports :: GhcMonad m => [SCC ModSummary] -> m () warnUnnecessarySourceImports sccs = do - diag_opts <- initDiagOpts <$> getDynFlags - when (diag_wopt Opt_WarnUnusedImports diag_opts) $ do - let check ms = - let mods_in_this_cycle = map ms_mod_name ms in - [ warn i | m <- ms, i <- ms_home_srcimps m, - unLoc i `notElem` mods_in_this_cycle ] - - warn :: Located ModuleName -> MsgEnvelope GhcMessage - warn (L loc mod) = GhcDriverMessage <$> mkPlainMsgEnvelope diag_opts + let check ms = + let mods_in_this_cycle = map ms_mod_name ms in + [ warn i (ms_hspp_opts m) | m <- ms, i <- ms_home_srcimps m, + unLoc i `notElem` mods_in_this_cycle ] + + warn :: Located ModuleName -> DynFlags -> MsgEnvelope GhcMessage + warn (L loc mod) dflags = GhcDriverMessage <$> mkPlainMsgEnvelope (initDiagOpts dflags) loc (DriverUnnecessarySourceImports mod) - logDiagnostics (mkMessages $ listToBag (concatMap (check . flattenSCC) sccs)) + logDiagnostics (mkMessages $ listToBag (concatMap (check . flattenSCC) sccs)) -- This caches the answer to the question, if we are in this unit, what does ===================================== testsuite/tests/driver/T24631.hs ===================================== @@ -0,0 +1,4 @@ +{-# OPTIONS_GHC -Wno-unused-imports #-} +module T24361 where + +import {-# SOURCE #-} T24631A ===================================== testsuite/tests/driver/T24631A.hs ===================================== @@ -0,0 +1 @@ +module T24631A where ===================================== testsuite/tests/driver/T24631A.hs-boot ===================================== @@ -0,0 +1 @@ +module T24631A where ===================================== testsuite/tests/driver/all.T ===================================== @@ -327,3 +327,4 @@ test('T23339B', [extra_files(['T23339.hs']), req_c], makefile_test, []) test('T23613', normal, compile_and_run, ['-this-unit-id=foo']) test('T23944', [unless(have_dynamic(), skip), extra_files(['T23944A.hs'])], multimod_compile, ['T23944 T23944A', '-fprefer-byte-code -fbyte-code -fno-code -dynamic-too -fwrite-interface']) test('T24286', [cxx_src, unless(have_profiling(), skip), extra_files(['T24286.cpp'])], compile, ['-prof -no-hs-main']) +test('T24631', [extra_files(['T24631A.hs', 'T24631A.hs-boot'])], multimod_compile, ['T24631', '-v0 -Wall -Werror']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/256dabce741db7b3c458b1a740bc868429c06cec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/256dabce741db7b3c458b1a740bc868429c06cec You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:34:02 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 05:34:02 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] 2 commits: fixup! Make template-haskell a stage1 package Message-ID: <66165d0a270d1_c98b0171b9104668a@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 11b974fe by Teo Camarasu at 2024-04-10T10:11:17+01:00 fixup! Make template-haskell a stage1 package - - - - - 01b8ad82 by Teo Camarasu at 2024-04-10T10:15:46+01:00 try not always re-exporting template-haskell in ghc-boot - - - - - 5 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2919,105 +2919,125 @@ tcGetInterp = do -- Note [Bootstrapping Template Haskell] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Template Haskell requires special attention when bootstrapping GHC. +-- The boot compiler (stage0) comes bundled with one version of +-- `template-haskell`. The bootstrap (stage1) compiler transitions to +-- using the in-tree version, which we distribute with our final compiler +-- (stage2). This is tricky because implementing Template Haskell requires cross +-- stage dependencies. We can divide Template Haskell into 3 capabilitie: +-- implementing running splices either using the internal interpreter, or the +-- external interpreter, and desugaring quote syntax. A splice (next stage) depends on the +-- interface of the `template-haskell` library (built in previous stage), which +-- must match the version built into the compiler, in order for that splice to +-- be runnable. The exposed interface includes the `Q` monad, the `Quasi` and +-- `Quote` typeclasses, and the TH AST. To desugar quote syntax, we use a sort +-- of late binding where we emit references to known-key definitions in +-- `GHC.Builtin.Names.TH` pointing to identifiers matching the in-tree library. -- --- Template Haskell requires special attention when compiling GHC. --- The implementation of the Template Haskell set of features requires tight --- coupling between the compiler and the `template-haskell` library. --- This complicates the bootstrapping story as compatibility constraints are --- placed on the version of `template-haskell` used to compile GHC during a --- particular stage and the version bundled with it. +-- In our current implementation we resolve these constraints by vendoring the +-- in-tree `template-haskell` library into the `ghc-boot` package while +-- compiling the stage1 compiler. This allows the stage1 compiler to depend on +-- the in-tree version of the interface without requiring the `template-haskell` +-- library to be built in stage0. -- --- These constraints can be divided by the features they are used to implement, --- namely running splices either directly or via the external interpreter, and --- desugaring bracket syntax. +-- Let's illustrate how Template Haskell works through an example. +-- Take the following code, which uses both quotes and splices. +-- > main = print $([|unwords ["hello", "world"]|]) -- --- (C1) Executing splices within the compiler: In order to execute a splice --- within the compiler, we must be able to compile and load code built against --- the same version of the `template-haskell` library as the compiler. This --- is an ABI compatibility constraint between the `template-haskell` version of --- the compiler and the splice. --- (C2) Executing splices through the external interpreter: In order to execute --- a splice via the external interpreter, we serialise bytecode, run it with the --- external interpreter, and communicate back the result through a binary --- serialised interface. This is a binary serialisation compatibilty constraint --- between the `template-haskell` version of the compiler and the splice. --- (C3) Desugaring bracket syntax: Bracket syntax is desugared by referring to a --- special wired-in package whose package id is `template-haskell`. So for --- instance an expression `'Just` gets desugared to something of type --- `template-haskell:Language.Haskell.TH.Syntax.Name`. Importantly, while this --- identifier is wired-in, the identity of the `template-haskell` package is --- not. So for instance we can successfully use an expression like --- `'Just :: Name` while compiling the `template-haskell` package as long as its --- package id is set to `template-haskell` as `Name` will resolve the the local --- identifier in the package (and the LHS and RHS will align). On the other --- hand, if we don't set the special package id, the type of the expression will --- be `template-haskell:...Name` while the `Name` on the RHS will resolve to the --- local identifier and we will get a type error. So, bracket syntax assumes the --- presence of a particular API in the `template-haskell` package, but it allows --- --- These constraints are ranked from strongest to weakest. They only apply if we --- want to support the particular feature associated with them. +-- The splice is run during renaming. This consists of the following steps. +-- 1. The quote is desugared becoming something equivalent to +-- `varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")]` +-- Notice we are introducing references to identifiers from the +-- `template-haskell` library. +-- This desguaring is implemented in `GHC.HsToCore.Quote.dsBracket`. +-- 2. The core expression of the quote is turned into bytecode. +-- 3. The bytecode is run in the interpreter. If we are using the internal +-- interpreter this is the `ghc` executable. If we are using the external +-- interpreter this is the `ghc-iserv` executable. +-- 4. Optionally the interpreter must load object code for packages mentioned in +-- the bytecode. In this instance that is just `template-haskell`. +-- 5. The bytecode is run. +-- 6. The result is a TH AST, which we convert back to a GHC AST using the +-- functions from `GHC.ThToHs`. -- --- The tricky case is what do to when building the bootstrapping (stage1) GHC. --- The stage2 GHC is simpler as it can use the in-tree `template-haskell` --- package built by the stage1 GHC. +-- At several points in the process different features required depending on the +-- `template-haskell` library. These constraints conditionally apply to any version of the +-- compiler that enables the relevant feature. -- --- We should note that we cannot feasibly use the internal interpreter with a --- stage1 GHC. This is because the stage1 GHC was compiled with the stage0 GHC, --- which we assume is a different version. In order to run a splice that too --- would need to be compiled with the stage0 GHC, and so would all its --- dependencies. --- This allows us to disregard (C1) for the stage1 case. +-- (C1) running a splice using the internal interpreter: if we run a splice by +-- loading the bytecode into the internal interpreter, then our compiler must be +-- linked against the same version of the `template-haskell` library as the +-- splice. For the stage2 compiler, this means a user splice (stage3) is linked +-- against the in-tree `template-haskell` library (stage1), which is the same +-- as what the stage2 compiler is linked against. +-- This constraint is introduced by step 4 and step 6. Usages of `reify` +-- functions from `Quasi` would also entail this constraint. If there were a +-- discrepancy between these two versions of `template-haskell`, for instance if +-- the splice's AST laccked the `StringE` constructor, then we would run into a +-- runtime or linker error. This constraint doesn't apply to the stage1 compiler +-- because we currently don't support using the internal interpreter at that +-- stage at all. -- --- In the past, we used to build the stage1 GHC and all its dependencies against --- the in-tree `template-haskell` library. This meant that we sacrificed (C2) --- because they are likely not serialisation compatible. We could not sacrifice --- (C3) because dependencies of GHC (such as `containers` and --- `template-haskell`) used bracket syntax to define `Lift` instances. This --- meant that the interface assumed by the boot compiler to implement bracket --- desugaring could not be modified (not even through CPP as (C1) would --- constrain us in future stages where we do support the internal interpreter). --- Yet, bracket syntax did work and gave us splices that desugared to code that --- referenced the in-tree version of `template-haskell` not the one the boot --- compiler required. So they could never be run. +-- (C2) running a splice using the external interpreter: if we run a splice by +-- loading the bytecode into the external interpreter, then our `iserv` +-- executable must be linked against the same version of the `template-haskell` +-- library as the splice. The compiler on the other hand only needs to be depend +-- on a binary serialisation that is compatible with `template-haskell` library. +-- This is a similar but weaker constraint on the compiler than the previous +-- one. It is possible to use this with the stage1 compiler by using an `iserv` +-- executable that is compiled against the stage1 `template-haskell` in-tree +-- library. If there is a discrepancy in the binary interface then we will run +-- into a runtime error if we fail to parse a message. -- --- Our current strategy is to not build `template-haskell` as a stage0 package. --- All of GHCs dependencies depend on the boot compilers version, and produce --- runnable splices. How do we deal with the stage1 compiler's dependency on --- `template-haskell`? There are two options. (D1) depend on the boot --- compiler's version for stage1 and then depend on the in-tree one in stage2. --- This violates (C1) and (C2), so we wouldn't be able to run splices at all --- with the stage1 compiler. Additionally this would introduce quite a bit of --- CPP into the compiler and mean we would have to stub out much of the --- template-haskell machinery or have an unrunable compatibilty shim. Or (D2) --- depend on the in-tree version. +-- (C3) desugaring quote syntax: the desugaring of quote syntax is hard coded +-- into each version of the compiler. `GHC.Builtin.Names.TH` declares many names +-- as known-key, inducing a coupling relationship quite to that of `ghc-internal`. +-- This is so that quotes can be desugared to calls to TH AST (smart) +-- constructors and uses of the Lift type class. +-- Furthermore, name quotes such as `'Just` are resolved relative to the module +-- under compilation and then desugar to a +-- `template-haskell:Language.Haskell.TH.Syntax.Name`, where the exact location +-- is determined by `GHC.Builtin.Names.TH`. This location must match the +-- `template-haskell` library against which the quote is linked. +-- This implements a sort of late binding, where identifiers will be mapped to +-- whatever package called `template-haskell` is in scope. +-- The late binding makes it possible to use quotes while compiling the +-- `template-haskell` library itself as identifiers will correctly be mapped to +-- the current package, rather than the one from the previous stage. +-- If we attempt to use quotes, but don't have a `template-haskell` package in +-- the package db with the appropriate interface we will run into type errors. +-- For instance if it lacked the `varE` function or had a function with the +-- wrong arity, then we would encounter an error when a module using the quote +-- is compiled. -- --- (D2) is what we implement, but it is complicated by the fact that it means we --- practically have two versions of `template-haskell` in the dependency graph --- of the stage1 compiler. To avoid this, we recall that we only need --- serliasation compatibility (as per (C2)), so we can avoid a direct dependency --- on the in-tree version by vendoring it. We choose to vendor it into the --- `ghc-boot` package as both `lib:ghc` and `ghci` require a dependency on the --- `template-haskell` interface as they define the two ends of the protocol. --- This allows us to still run splices through the external interpreter. +-- These 3 constraints inform our implementation strategy when building the +-- stage1 compiler. We are making use of the stage0 compiler, so if we want to +-- keep the possibility of using Template Haskell in the bootstrapping process +-- open (#22069), then our package DB must contain the `template-haskell` +-- library that our stage0 compiler is linked against (C1-3). +-- Yet, for the stage1 compiler, (C1) doesn't apply as we cannot use the +-- internal interpreter. We do not need to link the stage1 compiler against +-- the exact same `template-haskell` library that user splices compiled using +-- the stage1 compiler will need to use. Therefore, we vendor the modules from +-- the in-tree `template-haskell` library into the `ghc-boot` package. As a +-- common dependency of both, this allows the `ghc` and `ghci` libraries to +-- depend on the interface and serialisation from the in-tree `template-haskell` +-- library. This comes with a trade-off: we cannot make use of quotes while +-- compiling these modules as the identifiers would resolve to reflect the +-- stage0 compiler's expected structure (C3). -- --- We should note a futher edge-case with this approach. When compiling our --- vendored `template-haskell` library, we run afoul of (C3). The library --- defines several `Name`s using bracket syntax. As this package doesn't claim --- to be the wired-in package but it defines its own `Name` type, we get a type --- discrepancy with the `Name` type from the boot compiler's `template-haskell` --- library. Most of these are only used to define `Lift` instances, so in the --- vendored case we simply hide them behind CPP. Yet, there is one distinct use --- of a `Name`. We have a `Name` for the constructors of the `Multiplicity` --- type, which are also used in the pretty-printing module. We construct these --- manulally instead. This allows us to completely avoid using bracket syntax --- for compiling the vendored `template-haskell` package. +-- Then the stage1 compiler is used to compile the in-tree `template-haskell` +-- library, which is linked into the stage2 compiler and distributed alongside +-- it. -- --- To summarise, our current approach allows us to use the external interpreter --- to run splices and allows bracket syntax to be desugared correctly. In order --- to implement this we vendor the `template-haskell` library into `ghc-boot` --- and take special care to not use bracket syntax in those modules as that --- would incorrectly produce code that uses identifiers from the boot compiler's --- `template-haskell` library. +-- Historically, we used to build the in-tree `template-haskell` library in +-- stage0. This meant that qoutes would resolve to splices that couldn't be run +-- by the stage0 compiler (C1-2), eg, the in-tree library might contain a new +-- constructor the stage0 compiler wasn't aware of. It also made it difficult to +-- refactor the `template-haskell` library as it needed to be conservative with +-- regard to the identifiers the stage0 compiler was expecting in order to +-- desugar quotes (C3). See #23536. -- --- See #23536. +-- The current setup allows both stage0 and stage2 to use the full gamut of +-- Template Haskell functionality, while stage1 can use all but the internal +-- interpreter to run splices. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -124,6 +133,10 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if !flag(bootstrap-th) + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -155,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -115,17 +115,13 @@ Library hs-source-dirs: . build-depends: ghc-boot-th == @ProjectVersionMunged@ - , template-haskell == 2.22.0.0 - -- reexport modules from ghc-boot-th and template-haskell so that packages - -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. - -- It makes the dependency graph easier to understand and to refactor - -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + -- reexport modules from ghc-boot-th that packages + -- don't have to import all of ghc-boot, and ghc-boot-th. + -- It makes the dependency graph easier to understand. reexported-modules: GHC.LanguageExtensions.Type , GHC.ForeignSrcLang.Type , GHC.Lexeme - , Language.Haskell.TH - , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -86,5 +95,10 @@ library ghc-heap == @ProjectVersionMunged@, transformers >= 0.5 && < 0.7 + if !flag(bootstrap-th) + Build-Depends: + template-haskell == 2.22.0.0 + + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f9392adfba41999c47bc632379f101bef7d9eed...01b8ad82b641ecb1b6859774e342548049a3bd32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f9392adfba41999c47bc632379f101bef7d9eed...01b8ad82b641ecb1b6859774e342548049a3bd32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:41:08 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 10 Apr 2024 05:41:08 -0400 Subject: [Git][ghc/ghc][master] Validate -main-is flag using parseIdentifier Message-ID: <66165eb4e6ee7_c98b01ad831459379@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - 4 changed files: - compiler/GHC/Driver/Session.hs - testsuite/tests/driver/should_fail/all.T - + testsuite/tests/driver/should_fail/main-is.hs - + testsuite/tests/driver/should_fail/main-is.stderr Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -249,7 +249,10 @@ import GHC.Utils.Constants (debugIsOn) import GHC.Utils.GlobalVars import GHC.Data.Maybe import GHC.Data.Bool +import GHC.Data.StringBuffer (stringToStringBuffer) import GHC.Types.Error +import GHC.Types.Name.Reader (RdrName(..)) +import GHC.Types.Name.Occurrence (isVarOcc, occNameString) import GHC.Utils.Monad import GHC.Types.SrcLoc import GHC.Types.SafeHaskell @@ -258,9 +261,12 @@ import GHC.Data.FastString import GHC.Utils.TmpFs import GHC.Utils.Fingerprint import GHC.Utils.Outputable +import GHC.Utils.Error (emptyDiagOpts) import GHC.Settings import GHC.CmmToAsm.CFG.Weight import GHC.Core.Opt.CallerCC +import GHC.Parser (parseIdentifier) +import GHC.Parser.Lexer (mkParserOpts, initParserState, P(..), ParseResult(..)) import GHC.SysTools.BaseDir ( expandToolDir, expandTopDir ) @@ -285,6 +291,7 @@ import qualified GHC.Data.EnumSet as EnumSet import qualified GHC.LanguageExtensions as LangExt + -- Note [Updating flag description in the User's Guide] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- @@ -3342,18 +3349,32 @@ setCallerCcFilters arg = Left err -> addErr err setMainIs :: String -> DynP () -setMainIs arg - | x:_ <- main_fn, isLower x -- The arg looked like "Foo.Bar.baz" - = upd $ \d -> d { mainFunIs = Just main_fn, - mainModuleNameIs = mkModuleName main_mod } - - | x:_ <- arg, isUpper x -- The arg looked like "Foo" or "Foo.Bar" - = upd $ \d -> d { mainModuleNameIs = mkModuleName arg } - - | otherwise -- The arg looked like "baz" - = upd $ \d -> d { mainFunIs = Just arg } +setMainIs arg = parse parse_main_f arg where - (main_mod, main_fn) = splitLongestPrefix arg (== '.') + parse callback str = case unP parseIdentifier (p_state str) of + PFailed _ -> addErr $ "Can't parse -main-is \"" ++ arg ++ "\" as an identifier or module." + POk _ (L _ re) -> callback re + + -- dummy parser state. + p_state str = initParserState + (mkParserOpts mempty emptyDiagOpts [] False False False True) + (stringToStringBuffer str) + (mkRealSrcLoc (mkFastString []) 1 1) + + parse_main_f (Unqual occ) + | isVarOcc occ = upd $ \d -> d { mainFunIs = main_f occ } + parse_main_f (Qual (ModuleName mod) occ) + | isVarOcc occ = upd $ \d -> d { mainModuleNameIs = mkModuleNameFS mod + , mainFunIs = main_f occ } + -- append dummy "function" to parse A.B as the module A.B + -- and not the Data constructor B from the module A + parse_main_f _ = parse parse_mod (arg ++ ".main") + + main_f = Just . occNameString + + parse_mod (Qual (ModuleName mod) _) = upd $ \d -> d { mainModuleNameIs = mkModuleNameFS mod } + -- we appended ".m" and any parse error was caught. We are Qual or something went very wrong + parse_mod _ = error "unreachable" addLdInputs :: Option -> DynFlags -> DynFlags addLdInputs p dflags = dflags{ldInputs = ldInputs dflags ++ [p]} ===================================== testsuite/tests/driver/should_fail/all.T ===================================== @@ -5,3 +5,5 @@ test('T12752', expect_fail, compile, ['-Wcpp-undef -Werror']) test('T11789a', normal, compile_fail, ['-fppr-cols=1000']) test('T11789b', normal, compile_fail, ['-rtsopts=somw']) + +test('main-is', normal, compile_fail, ['-main-is \"This could never fail, could it?\"']) ===================================== testsuite/tests/driver/should_fail/main-is.hs ===================================== @@ -0,0 +1 @@ +module Foo where ===================================== testsuite/tests/driver/should_fail/main-is.stderr ===================================== @@ -0,0 +1,2 @@ +ghc: on the commandline: Can't parse -main-is "This could never fail, could it?" as an identifier or module. +Usage: For basic information, try the `--help' option. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d0806fc2cc592256c8b38758f13b614a46122fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d0806fc2cc592256c8b38758f13b614a46122fd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:41:46 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 10 Apr 2024 05:41:46 -0400 Subject: [Git][ghc/ghc][master] 5 commits: rts: free error message before returning Message-ID: <66165eda50deb_c98b01ad8314648bc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/include/rts/Linker.h - rts/linker/Elf.c - rts/linker/Elf.h - + rts/linker/LoadNativeObjPosix.c - + rts/linker/LoadNativeObjPosix.h - rts/linker/PEi386.c - rts/linker/PEi386.h - rts/rts.cabal - testsuite/tests/ghci/linking/dyn/T3372.hs - testsuite/tests/rts/linker/T2615.hs - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c - + testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d0806fc2cc592256c8b38758f13b614a46122fd...dccd3ea159b03cc1972cf47ee3cf8bda73ec0c5a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d0806fc2cc592256c8b38758f13b614a46122fd...dccd3ea159b03cc1972cf47ee3cf8bda73ec0c5a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:42:20 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 10 Apr 2024 05:42:20 -0400 Subject: [Git][ghc/ghc][master] EPA: Remove unnecessary XRec in CompleteMatchSig Message-ID: <66165efc92ca3_c98b01d192a4664cf@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 8 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -853,7 +853,7 @@ ppr_sig (SCCFunSig (_, src) fn mlabel) GhcTc -> ppr fn ppr_sig (CompleteMatchSig (_, src) cs mty) = pragSrcBrackets src "{-# COMPLETE" - ((hsep (punctuate comma (map ppr_n (unLoc cs)))) + ((hsep (punctuate comma (map ppr_n cs))) <+> opt_sig) where opt_sig = maybe empty ((\t -> dcolon <+> ppr t) . unLoc) mty @@ -946,14 +946,6 @@ type instance Anno (HsBindLR (GhcPass idL) (GhcPass idR)) = SrcSpanAnnA type instance Anno (IPBind (GhcPass p)) = SrcSpanAnnA type instance Anno (Sig (GhcPass p)) = SrcSpanAnnA --- For CompleteMatchSig -type instance Anno [LocatedN RdrName] = SrcSpan -type instance Anno [LocatedN Name] = SrcSpan -type instance Anno [LocatedN Id] = SrcSpan - type instance Anno (FixitySig (GhcPass p)) = SrcSpanAnnA type instance Anno StringLiteral = EpAnnCO -type instance Anno (LocatedN RdrName) = SrcSpan -type instance Anno (LocatedN Name) = SrcSpan -type instance Anno (LocatedN Id) = SrcSpan ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1159,11 +1159,11 @@ repPhases (ActiveAfter _ i) = do { MkC arg <- coreIntLit i ; dataCon' fromPhaseDataConName [arg] } repPhases _ = dataCon allPhasesDataConName -rep_complete_sig :: Located [LocatedN Name] +rep_complete_sig :: [LocatedN Name] -> Maybe (LocatedN Name) -> SrcSpan -> MetaM [(SrcSpan, Core (M TH.Dec))] -rep_complete_sig (L _ cls) mty loc +rep_complete_sig cls mty loc = do { mty' <- repMaybe nameTyConName lookupLOcc mty ; cls' <- repList nameTyConName lookupLOcc cls ; sig <- repPragComplete cls' mty' ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1812,9 +1812,8 @@ instance HiePass p => ToHie (SigContext (LocatedA (Sig (GhcPass p)))) where [ toHie $ (C Use) name , maybe (pure []) (locOnly . getLocA) mtxt ] - CompleteMatchSig _ (L ispan names) typ -> - [ locOnly ispan - , toHie $ map (C Use) names + CompleteMatchSig _ names typ -> + [ toHie $ map (C Use) names , toHie $ fmap (C Use) typ ] XSig _ -> [] ===================================== compiler/GHC/Parser.y ===================================== @@ -3630,10 +3630,10 @@ con_list :: { Located (NonEmpty (LocatedN RdrName)) } con_list : con { sL1 $1 (pure $1) } | con ',' con_list {% sLL $1 $> . (:| toList (unLoc $3)) <\$> addTrailingCommaN $1 (gl $2) } -qcon_list :: { Located [LocatedN RdrName] } -qcon_list : qcon { sL1 $1 [$1] } +qcon_list :: { [LocatedN RdrName] } +qcon_list : qcon { [$1] } | qcon ',' qcon_list {% do { h <- addTrailingCommaN $1 (gl $2) - ; return (sLL $1 $> (h : unLoc $3)) }} + ; return (h : $3) }} -- See Note [ExplicitTuple] in GHC.Hs.Expr sysdcon_nolist :: { LocatedN DataCon } -- Wired in data constructors ===================================== compiler/GHC/Rename/Bind.hs ===================================== @@ -1138,7 +1138,7 @@ renameSig ctxt sig@(SCCFunSig (_, st) v s) -- COMPLETE Sigs can refer to imported IDs which is why we use -- lookupLocatedOccRn rather than lookupSigOccRn -renameSig _ctxt sig@(CompleteMatchSig (_, s) (L l bf) mty) +renameSig _ctxt sig@(CompleteMatchSig (_, s) bf mty) = do new_bf <- traverse lookupLocatedOccRn bf new_mty <- traverse lookupLocatedOccRn mty @@ -1147,7 +1147,7 @@ renameSig _ctxt sig@(CompleteMatchSig (_, s) (L l bf) mty) -- Why 'any'? See Note [Orphan COMPLETE pragmas] addErrCtxt (text "In" <+> ppr sig) $ failWithTc TcRnOrphanCompletePragma - return (CompleteMatchSig (noAnn, s) (L l new_bf) new_mty, emptyFVs) + return (CompleteMatchSig (noAnn, s) new_bf new_mty, emptyFVs) {- ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -227,7 +227,7 @@ tcCompleteSigs sigs = -- combinations are invalid it will be found so at match sites. -- There it is also where we consider if the type of the pattern match is -- compatible with the result type constructor 'mb_tc'. - doOne (L loc c@(CompleteMatchSig (_ext, _src_txt) (L _ ns) mb_tc_nm)) + doOne (L loc c@(CompleteMatchSig (_ext, _src_txt) ns mb_tc_nm)) = fmap Just $ setSrcSpanA loc $ addErrCtxt (text "In" <+> ppr c) $ do cls <- mkUniqDSet <$> mapM (addLocM tcLookupConLike) ns mb_tc <- traverse @Maybe tcLookupLocatedTyCon mb_tc_nm ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -952,7 +952,7 @@ cvtPragmaD (LineP line file) ; return Nothing } cvtPragmaD (CompleteP cls mty) - = do { cls' <- wrapL $ mapM cNameN cls + = do { cls' <- mapM cNameN cls ; mty' <- traverse tconNameN mty ; returnJustLA $ Hs.SigD noExtField $ CompleteMatchSig (noAnn, NoSourceText) cls' mty' } ===================================== compiler/Language/Haskell/Syntax/Binds.hs ===================================== @@ -487,7 +487,7 @@ data Sig pass -- complete matchings which, for example, arise from pattern -- synonym definitions. | CompleteMatchSig (XCompleteMatchSig pass) - (XRec pass [LIdP pass]) + [LIdP pass] (Maybe (LIdP pass)) | XSig !(XXSig pass) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b1a92bd25c3f7249cf922c5dbf4415d2de44a36 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b1a92bd25c3f7249cf922c5dbf4415d2de44a36 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 09:58:58 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 10 Apr 2024 05:58:58 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 6 commits: Refactor the Binary serialisation interface Message-ID: <661662e27fb0_c98b020602a0687c6@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 68d406f8 by Fendor at 2024-04-10T10:11:27+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: T21839c ------------------------- - - - - - 026372f7 by Fendor at 2024-04-10T10:11:27+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12a3a5d5 by Matthew Pickering at 2024-04-10T10:44:28+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 4ed1ed63 by Fendor at 2024-04-10T10:44:30+02:00 Add IfaceType deduplication table to .hie serialisation Refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - c4a518b4 by Matthew Pickering at 2024-04-10T10:44:30+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 829f88c9 by Fendor at 2024-04-10T11:58:08+02:00 WIP: CI results for Data.Map deduplication - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - utils/haddock Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -952,13 +952,13 @@ data CoSel -- See Note [SelCo] | SelForAll -- Decomposes (forall a. co) - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) data FunSel -- See Note [SelCo] = SelMult -- Multiplicity | SelArg -- Argument of function | SelRes -- Result of function - deriving( Eq, Data.Data ) + deriving( Eq, Data.Data, Ord ) type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -121,7 +121,7 @@ toIfaceTvBndr :: TyVar -> IfaceTvBndr toIfaceTvBndr = toIfaceTvBndrX emptyVarSet toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr -toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar) +toIfaceTvBndrX fr tyvar = ( mkIfLclName (occNameFS (getOccName tyvar)) , toIfaceTypeX fr (tyVarKind tyvar) ) @@ -133,7 +133,7 @@ toIfaceIdBndr = toIfaceIdBndrX emptyVarSet toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr toIfaceIdBndrX fr covar = ( toIfaceType (idMult covar) - , occNameFS (getOccName covar) + , mkIfLclName (occNameFS (getOccName covar)) , toIfaceTypeX fr (varType covar) ) @@ -218,11 +218,11 @@ toIfaceTypeX fr (TyConApp tc tys) arity = tyConArity tc n_tys = length tys -toIfaceTyVar :: TyVar -> FastString -toIfaceTyVar = occNameFS . getOccName +toIfaceTyVar :: TyVar -> IfLclName +toIfaceTyVar = mkIfLclName . occNameFS . getOccName -toIfaceCoVar :: CoVar -> FastString -toIfaceCoVar = occNameFS . getOccName +toIfaceCoVar :: CoVar -> IfLclName +toIfaceCoVar = mkIfLclName . occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon @@ -264,7 +264,7 @@ toIfaceTyCon_name n = IfaceTyCon n info toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x -toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x +toIfaceTyLit (StrTyLit x) = IfaceStrTyLit (LexicalFastString x) toIfaceTyLit (CharTyLit x) = IfaceCharTyLit x ---------------- @@ -296,7 +296,7 @@ toIfaceCoercionX fr co go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c) go (SubCo co) = IfaceSubCo (go co) - go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs) + go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (mkIfLclName (coaxrName co)) (map go cs) go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs) go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) @@ -433,7 +433,7 @@ toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang toIfaceLetBndr :: Id -> IfaceLetBndr -toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) +toIfaceLetBndr id = IfLetBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (idJoinPointHood id) @@ -444,7 +444,7 @@ toIfaceTopBndr :: Id -> IfaceTopBndrInfo toIfaceTopBndr id = if isExternalName name then IfGblTopBndr name - else IfLclTopBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) + else IfLclTopBndr (mkIfLclName (occNameFS (getOccName id))) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) (toIfaceIdDetails (idDetails id)) where name = getName id @@ -555,7 +555,7 @@ toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfac toIfaceExpr (App f a) = toIfaceApp f [a] toIfaceExpr (Case s x ty as) | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty) - | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as) + | otherwise = IfaceCase (toIfaceExpr s) (mkIfLclName (getOccFS x)) (map toIfaceAlt as) toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e) toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co) toIfaceExpr (Tick t e) = IfaceTick (toIfaceTickish t) (toIfaceExpr e) @@ -610,7 +610,7 @@ toIfaceTopBind b = --------------------- toIfaceAlt :: CoreAlt -> IfaceAlt -toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map getOccFS bs) (toIfaceExpr r) +toIfaceAlt (Alt c bs r) = IfaceAlt (toIfaceCon c) (map (mkIfLclName . getOccFS) bs) (toIfaceExpr r) --------------------- toIfaceCon :: AltCon -> IfaceConAlt @@ -655,7 +655,7 @@ toIfaceVar v -- Foreign calls have special syntax | isExternalName name = IfaceExt name - | otherwise = IfaceLcl (occNameFS $ nameOccName name) + | otherwise = IfaceLcl (mkIfLclName (occNameFS $ nameOccName name)) where name = idName v ty = idType v ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -283,13 +283,16 @@ instance Ord NonDetFastString where -- `lexicalCompareFS` (i.e. which compares FastStrings on their String -- representation). Hence it is deterministic from one run to the other. newtype LexicalFastString - = LexicalFastString FastString + = LexicalFastString { getLexicalFastString :: FastString } deriving newtype (Eq, Show) deriving stock Data instance Ord LexicalFastString where compare (LexicalFastString fs1) (LexicalFastString fs2) = lexicalCompareFS fs1 fs2 +instance NFData LexicalFastString where + rnf (LexicalFastString f) = rnf f + -- ----------------------------------------------------------------------------- -- Construction ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -25,11 +25,12 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +40,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -54,6 +56,10 @@ import Data.Char import Data.Word import Data.IORef import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe +import Data.Map.Strict (Map) + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -75,7 +81,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +127,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +143,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +154,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +162,41 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + + -- The order of these deserialisation matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData fsReader bh + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData nameReader bhFs - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + ifaceTypeTable <- Binary.forwardGet bh (getTable ifaceTypeReaderTable bhName) + let + ifaceTypeReader = mkReaderFromTable ifaceTypeReaderTable ifaceTypeTable + bhIfaceType = addReaderToUserData ifaceTypeReader bhName - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + writeIORef bhRef (getReaderUserData bhIfaceType) + pure bhIfaceType --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Iface Binary Serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +209,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +226,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +250,43 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +-- See Note [Iface Binary Serialiser Order] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType + + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Iface Binary Serialiser Order] for details. + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +298,168 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Iface Binary Serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: + +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser instead of + directly serialising itself. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + +* Whenever a value of 'IfaceTyCon' is serialised, the real serialisation function needs to + be configured in the User Data. + + For example, for 'IfaceTyCon': + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + Now, here we can introduce the deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a 'Map' and remembers the offset + of each value we have already seen. + Instead of serialising the full 'IfaceTyCon', we only write the index of the value to disk. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + +Note [Iface Binary Serialiser Order] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. + +Here, a visualisation of the table structure we currently have: + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType = do + sym_tab <- initGenericSymbolTable @(Map IfaceType) + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ putGenericSymTab sym_tab + ) + + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +468,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +489,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +513,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +538,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +557,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Decl.hs ===================================== @@ -45,7 +45,6 @@ import GHC.Types.SrcLoc import GHC.Utils.Panic.Plain import GHC.Utils.Misc -import GHC.Data.FastString import GHC.Data.Maybe import GHC.Data.BooleanFormula @@ -147,7 +146,7 @@ tyConToIfaceDecl env tycon | Just fam_flav <- famTyConFlav_maybe tycon = ( tc_env1 , IfaceFamily { ifName = getName tycon, - ifResVar = if_res_var, + ifResVar = mkIfLclName <$> if_res_var, ifFamFlav = to_if_fam_flav fam_flav, ifBinders = if_binders, ifResKind = if_res_kind, @@ -288,7 +287,7 @@ classToIfaceDecl env clas ifClassCtxt = tidyToIfaceContext env1 sc_theta, ifATs = map toIfaceAT clas_ats, ifSigs = map toIfaceClassOp op_stuff, - ifMinDef = toIfaceBooleanFormula $ fmap getOccFS (classMinimalDef clas) + ifMinDef = toIfaceBooleanFormula $ fmap (mkIfLclName . getOccFS) (classMinimalDef clas) } (env1, tc_binders) = tidyTyConBinders env (tyConBinders tycon) @@ -334,7 +333,7 @@ tidyTyConBinder env@(_, subst) tvb@(Bndr tv vis) tidyTyConBinders :: TidyEnv -> [TyConBinder] -> (TidyEnv, [TyConBinder]) tidyTyConBinders = mapAccumL tidyTyConBinder -tidyTyVar :: TidyEnv -> TyVar -> FastString +tidyTyVar :: TidyEnv -> TyVar -> IfLclName tidyTyVar (_, subst) tv = toIfaceTyVar (lookupVarEnv subst tv `orElse` tv) toIfaceBooleanFormula :: BooleanFormula IfLclName -> IfaceBooleanFormula ===================================== compiler/GHC/Iface/Env.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Runtime.Context import GHC.Unit.Module import GHC.Unit.Module.ModIface -import GHC.Data.FastString import GHC.Data.FastString.Env import GHC.Types.Var @@ -190,10 +189,10 @@ setNameModule (Just m) n = ************************************************************************ -} -tcIfaceLclId :: FastString -> IfL Id +tcIfaceLclId :: IfLclName -> IfL Id tcIfaceLclId occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_id_env lcl) occ of + ; case lookupFsEnv (if_id_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM $ vcat @@ -209,10 +208,10 @@ extendIfaceIdEnv ids in env { if_id_env = id_env' } -tcIfaceTyVar :: FastString -> IfL TyVar +tcIfaceTyVar :: IfLclName -> IfL TyVar tcIfaceTyVar occ = do { lcl <- getLclEnv - ; case lookupFsEnv (if_tv_env lcl) occ of + ; case lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ) of Just ty_var -> return ty_var Nothing -> failIfM (text "Iface type variable out of scope: " <+> ppr occ) } @@ -220,15 +219,15 @@ tcIfaceTyVar occ lookupIfaceTyVar :: IfaceTvBndr -> IfL (Maybe TyVar) lookupIfaceTyVar (occ, _) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar) lookupIfaceVar (IfaceIdBndr (_, occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_id_env lcl) occ) } + ; return (lookupFsEnv (if_id_env lcl) (ifLclNameFS occ)) } lookupIfaceVar (IfaceTvBndr (occ, _)) = do { lcl <- getLclEnv - ; return (lookupFsEnv (if_tv_env lcl) occ) } + ; return (lookupFsEnv (if_tv_env lcl) (ifLclNameFS occ)) } extendIfaceTyVarEnv :: [TyVar] -> IfL a -> IfL a extendIfaceTyVarEnv tyvars ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -67,7 +66,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -84,57 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType - -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh - putAt bh symtab_p_p symtab_p - seekBin bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh - putAt bh dict_p_p dict_p - seekBin bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Iface Binary Serialiser Order] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -181,7 +181,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +190,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,59 +213,42 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p - dict <- getDictionary bin_handle - seekBin bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' - return symtab - -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) - -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +258,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +316,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +327,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -162,15 +162,15 @@ getEvidenceTree refmap var = go emptyNameSet var hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where - go (HTyVarTy n) = IfaceTyVar $ occNameFS $ getOccName n + go (HTyVarTy n) = IfaceTyVar $ (mkIfLclName (occNameFS $ getOccName n)) go (HAppTy a b) = IfaceAppTy a (hieToIfaceArgs b) go (HLitTy l) = IfaceLitTy l - go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k) + go (HForAllTy ((n,k),af) t) = let b = (mkIfLclName (occNameFS $ getOccName n), k) in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t go (HFunTy w a b) = IfaceFunTy visArgTypeLike w a b go (HQualTy pred b) = IfaceFunTy invisArgTypeLike many_ty pred b go (HCastTy a) = a - go HCoercionTy = IfaceTyVar "" + go HCoercionTy = IfaceTyVar (mkIfLclName "") go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs) -- This isn't fully faithful - we can't produce the 'Inferred' case ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints @@ -1216,8 +1216,8 @@ addFingerprints hsc_env iface0 getOcc (IfLclTopBndr fs _ _ details) = case details of IfRecSelId { ifRecSelFirstCon = first_con } - -> mkRecFieldOccFS (getOccFS first_con) fs - _ -> mkVarOccFS fs + -> mkRecFieldOccFS (getOccFS first_con) (ifLclNameFS fs) + _ -> mkVarOccFS (ifLclNameFS fs) binding_key (IfaceNonRec b _) = IfaceNonRec (getOcc b) () binding_key (IfaceRec bs) = IfaceRec (map (\(b, _) -> (getOcc b, ())) bs) ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,8 +14,9 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +27,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -34,12 +35,16 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -631,6 +632,7 @@ data IfaceExpr | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E + data IfaceTickish = IfaceHpcTick Module Int -- from HpcTick x | IfaceSCC CostCentre Bool Bool -- from ProfNote @@ -1025,7 +1027,7 @@ pprIfaceDecl ss (IfaceClass { ifName = clas pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions text "{-# MINIMAL" <+> pprBooleanFormula - (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+> + (\_ def -> cparen (isLexSym def) (ppr def)) 0 (fmap ifLclNameFS minDef) <+> text "#-}" -- See Note [Suppressing binder signatures] in GHC.Iface.Type @@ -2444,13 +2446,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,9 +9,9 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( - IfExtName, IfLclName, + IfExtName, + IfLclName(..), mkIfLclName, ifLclNameFS, IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), @@ -33,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, -- Equality testing isIfaceLiftedTypeKind, @@ -90,10 +92,12 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq +import Data.Proxy import Control.Monad ((<$!>)) +import Control.Arrow (first) +import qualified Data.Semigroup as Semi +import Data.Maybe (isJust) {- ************************************************************************ @@ -103,7 +107,20 @@ import Control.Monad ((<$!>)) ************************************************************************ -} -type IfLclName = FastString -- A local name in iface syntax +-- | A local name in iface syntax +newtype IfLclName = IfLclName + { getIfLclName :: LexicalFastString + } deriving (Eq, Ord, Show) + +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + +ifLclNameFS :: IfLclName -> FastString +ifLclNameFS = getLexicalFastString . getIfLclName + +mkIfLclName :: FastString -> IfLclName +mkIfLclName = IfLclName . LexicalFastString type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax -- (However Internal or System Names never should) @@ -111,6 +128,8 @@ type IfExtName = Name -- An External or WiredIn Name can appear in Iface synta data IfaceBndr -- Local (non-top-level) binders = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr + deriving (Eq, Ord) + type IfaceIdBndr = (IfaceType, IfLclName, IfaceType) type IfaceTvBndr = (IfLclName, IfaceKind) @@ -179,6 +198,7 @@ data IfaceType -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression -- in interface file size (in GHC's boot libraries). -- See !3987. + deriving (Eq, Ord) type IfaceMult = IfaceType @@ -187,9 +207,9 @@ type IfaceContext = [IfacePredType] data IfaceTyLit = IfaceNumTyLit Integer - | IfaceStrTyLit FastString + | IfaceStrTyLit LexicalFastString | IfaceCharTyLit Char - deriving (Eq) + deriving (Eq, Ord) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag @@ -231,6 +251,7 @@ data IfaceAppArgs -- arguments in @{...}. IfaceAppArgs -- The rest of the arguments + deriving (Eq, Ord) instance Semi.Semigroup IfaceAppArgs where IA_Nil <> xs = xs @@ -257,7 +278,7 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName -- See Note [Sharing IfaceTyConInfo] for why -- sharing is so important for 'IfaceTyConInfo'. } - deriving (Eq) + deriving (Eq, Ord) -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -277,7 +298,7 @@ data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon -- that is actually being applied to two types -- of the same kind. This affects pretty-printing -- only: see Note [Equality predicates in IfaceType] - deriving (Eq) + deriving (Eq, Ord) instance Outputable IfaceTyConSort where ppr IfaceNormalTyCon = text "normal" @@ -371,7 +392,7 @@ data IfaceTyConInfo -- Used only to guide pretty-printing -- should be printed as 'D to distinguish it from -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } - deriving (Eq) + deriving (Eq, Ord) -- | This smart constructor allows sharing of the two most common -- cases. See Note [Sharing IfaceTyConInfo] @@ -421,7 +442,7 @@ This one change leads to an 15% reduction in residency for GHC when embedding data IfaceMCoercion = IfaceMRefl - | IfaceMCo IfaceCoercion + | IfaceMCo IfaceCoercion deriving (Eq, Ord) data IfaceCoercion = IfaceReflCo IfaceType @@ -446,11 +467,13 @@ data IfaceCoercion | IfaceSubCo IfaceCoercion | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] + deriving (Eq, Ord) data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String + deriving (Eq, Ord) {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -622,11 +645,11 @@ type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType] mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst -- See Note [Substitution on IfaceType] -mkIfaceTySubst eq_spec = mkFsEnv eq_spec +mkIfaceTySubst eq_spec = mkFsEnv (map (first ifLclNameFS) eq_spec) inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool -- See Note [Substitution on IfaceType] -inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs) +inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst (ifLclNameFS fs)) substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType -- See Note [Substitution on IfaceType] @@ -682,7 +705,7 @@ substIfaceAppArgs env args substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType substIfaceTyVar env tv - | Just ty <- lookupFsEnv env tv = ty + | Just ty <- lookupFsEnv env (ifLclNameFS tv) = ty | otherwise = IfaceTyVar tv @@ -1191,7 +1214,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind - = let subs' = extendFsEnv subs var substituted_ty + = let subs' = extendFsEnv subs (ifLclNameFS var) substituted_ty -- Record that we should replace it with LiftedRep/Lifted/Many, -- and recurse, discarding the forall in go subs' True ty @@ -1199,7 +1222,7 @@ defaultIfaceTyVarsOfKind def_rep def_mult ty = go emptyFsEnv True ty go subs rank1 (IfaceForAllTy bndr ty) = IfaceForAllTy (go_ifacebndr subs bndr) (go subs rank1 ty) - go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of + go subs _ ty@(IfaceTyVar tv) = case lookupFsEnv subs (ifLclNameFS tv) of Just s -> s Nothing -> ty @@ -1627,7 +1650,7 @@ pprTyTcApp ctxt_prec tc tys = , IA_Arg (IfaceLitTy (IfaceStrTyLit n)) Required (IA_Arg ty Required IA_Nil) <- tys -> maybeParen ctxt_prec funPrec - $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty + $ char '?' <> ftext (getLexicalFastString n) <> text "::" <> ppr_ty topPrec ty | IfaceTupleTyCon arity sort <- ifaceTyConSort info , not debug @@ -2015,6 +2038,9 @@ pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) ------------------- +instance Outputable IfLclName where + ppr = ppr . ifLclNameFS + instance Outputable IfaceTyCon where ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc) @@ -2045,11 +2071,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 @@ -2171,38 +2198,47 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) - - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } - - get bh = do + put_ bh tyCon = case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh tyCon + + get bh = case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2230,6 +2266,13 @@ instance Binary IfaceType where _ -> do n <- get bh return (IfaceLitTy n) +instance Binary IfLclName where + put_ bh = put_ bh . ifLclNameFS + + get bh = do + fs <- get bh + pure $ IfLclName $ LexicalFastString fs + instance Binary IfaceMCoercion where put_ bh IfaceMRefl = putByte bh 1 @@ -2475,6 +2518,9 @@ instance NFData IfaceTyConSort where IfaceSumTyCon arity -> rnf arity IfaceEqualityTyCon -> () +instance NFData IfLclName where + rnf (IfLclName lfs) = rnf lfs + instance NFData IfaceTyConInfo where rnf (IfaceTyConInfo f s) = f `seq` rnf s ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -733,7 +733,7 @@ tc_iface_decl parent _ (IfaceFamily {ifName = tc_name, { res_kind' <- tcIfaceType res_kind -- Note [Synonym kind loop] ; rhs <- forkM (mk_doc tc_name) $ tc_fam_flav tc_name fam_flav - ; res_name <- traverse (newIfaceName . mkTyVarOccFS) res + ; res_name <- traverse (newIfaceName . mkTyVarOccFS . ifLclNameFS) res ; let tycon = mkFamilyTyCon tc_name binders' res_kind' res_name rhs parent inj ; return (ATyCon tycon) } where @@ -782,7 +782,7 @@ tc_iface_decl _parent ignore_prags ; fds <- mapM tc_fd rdr_fds ; traceIf (text "tc-iface-class3" <+> ppr tc_name) ; let mindef_occ = fromIfaceBooleanFormula if_mindef - ; mindef <- traverse (lookupIfaceTop . mkVarOccFS) mindef_occ + ; mindef <- traverse (lookupIfaceTop . mkVarOccFS . ifLclNameFS) mindef_occ ; cls <- fixM $ \ cls -> do { ats <- mapM (tc_at cls) rdr_ats ; traceIf (text "tc-iface-class4" <+> ppr tc_name) @@ -936,8 +936,8 @@ mk_top_id (IfLclTopBndr raw_name iface_type info details) = do ; let occ = case details' of RecSelId { sel_tycon = parent } -> let con_fs = getOccFS $ recSelFirstConName parent - in mkRecFieldOccFS con_fs raw_name - _ -> mkVarOccFS raw_name + in mkRecFieldOccFS con_fs (ifLclNameFS raw_name) + _ -> mkVarOccFS (ifLclNameFS raw_name) ; name <- newIfaceName occ } info' <- tcIdInfo False TopLevel name ty info let new_id = mkGlobalId details' name ty info' @@ -1441,7 +1441,7 @@ tcIfaceCtxt sts = mapM tcIfaceType sts ----------------------------------------- tcIfaceTyLit :: IfaceTyLit -> IfL TyLit tcIfaceTyLit (IfaceNumTyLit n) = return (NumTyLit n) -tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) +tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit (getLexicalFastString n)) tcIfaceTyLit (IfaceCharTyLit n) = return (CharTyLit n) {- @@ -1485,7 +1485,7 @@ tcIfaceCo = go go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) - go_var :: FastString -> IfL CoVar + go_var :: IfLclName -> IfL CoVar go_var = tcIfaceLclId tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance @@ -1561,7 +1561,7 @@ tcIfaceExpr (IfaceECase scrut ty) tcIfaceExpr (IfaceCase scrut case_bndr alts) = do scrut' <- tcIfaceExpr scrut - case_bndr_name <- newIfaceName (mkVarOccFS case_bndr) + case_bndr_name <- newIfaceName (mkVarOccFS (ifLclNameFS case_bndr)) let scrut_ty = exprType scrut' case_mult = ManyTy @@ -1580,7 +1580,7 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do return (Case scrut' case_bndr' (coreAltsType alts') alts') tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} NotTopLevel name ty' info @@ -1598,7 +1598,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; return (Let (Rec pairs') body') } } where tc_rec_bndr (IfLetBndr fs ty _ ji) - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; return (mkLocalId name ManyTy ty' `asJoinId_maybe` ji) } tc_pair (IfLetBndr _ _ info _, rhs) id @@ -1655,12 +1655,12 @@ tcIfaceAlt scrut mult (tycon, inst_tys) (IfaceAlt (IfaceDataAlt data_occ) arg_st (failIfM (ppr scrut $$ ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon))) ; tcIfaceDataAlt mult con inst_tys arg_strs rhs } -tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [FastString] -> IfaceExpr +tcIfaceDataAlt :: Mult -> DataCon -> [Type] -> [IfLclName] -> IfaceExpr -> IfL CoreAlt tcIfaceDataAlt mult con inst_tys arg_strs rhs = do { uniqs <- getUniquesM ; let (ex_tvs, arg_ids) - = dataConRepFSInstPat arg_strs uniqs mult con inst_tys + = dataConRepFSInstPat (map ifLclNameFS arg_strs) uniqs mult con inst_tys ; rhs' <- extendIfaceEnvs ex_tvs $ extendIfaceIdEnv arg_ids $ @@ -2031,7 +2031,7 @@ tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule -- - axioms for type-level literals (Nat and Symbol), -- enumerated in typeNatCoAxiomRules tcIfaceCoAxiomRule n - | Just ax <- lookupUFM typeNatCoAxiomRules n + | Just ax <- lookupUFM typeNatCoAxiomRules (ifLclNameFS n) = return ax | otherwise = pprPanic "tcIfaceCoAxiomRule" (ppr n) @@ -2075,7 +2075,7 @@ tcIfaceImplicit n = do bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a bindIfaceId (w, fs, ty) thing_inside - = do { name <- newIfaceName (mkVarOccFS fs) + = do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs)) ; ty' <- tcIfaceType ty ; w' <- tcIfaceType w ; let id = mkLocalIdOrCoVar name w' ty' @@ -2118,7 +2118,7 @@ bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside - = do { name <- newIfaceName (mkTyVarOccFS occ) + = do { name <- newIfaceName (mkTyVarOccFS (ifLclNameFS occ)) ; tyvar <- mk_iface_tyvar name kind ; extendIfaceTyVarEnv [tyvar] (thing_inside tyvar) } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData fs_writer bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -148,7 +148,7 @@ import qualified Data.Semigroup as Semi ********************************************************************* -} data LeftOrRight = CLeft | CRight - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) pickLR :: LeftOrRight -> (a,a) -> a pickLR CLeft (l,_) = l @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -720,7 +720,7 @@ Currently there are nine different uses of 'VarBndr': data VarBndr var argf = Bndr var argf -- See Note [The VarBndr type and its uses] - deriving( Data ) + deriving( Data, Eq, Ord) -- | Variable Binder -- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -2,8 +2,10 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE AllowAmbiguousTypes #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +23,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +32,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -62,19 +66,41 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -91,8 +117,10 @@ import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +132,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +149,12 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce +import GHC.Data.TrieMap + + + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +186,95 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +293,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +317,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +379,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +416,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +432,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +453,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +475,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +513,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +526,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +538,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +559,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +585,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +610,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +634,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +662,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1081,74 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () -lazyPut bh a = do +lazyPut :: Binary a => WriteBinHandle -> a -> IO () +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + f bh a -- dump the object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + let bh' = inner_bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f p bh' + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1156,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1174,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1195,283 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +data BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +data BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } + +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +data GenericSymbolTable m = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use + , gen_symtab_map :: !(IORef (m Int)) + -- ^ Given a symbol, find the symbol + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer + } + +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo + } + +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab + putGenericSymbolTable :: HasCallStack => WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) + case vs of + [] -> readFastMutInt symtab_next + todo -> do + mapM_ (\n -> serialiser bh n) (reverse todo) + loop + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop) + +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +{-# INLINE putGenericSymTab #-} +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } + bh val = do + symtab_map <- readIORef symtab_map_ref + case lookupTM val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) + put_ bh (fromIntegral off :: Word32) + +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count + + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1480,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1514,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1561,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -78,6 +78,7 @@ import Data.Eq import Data.Bool import Data.Char import Prelude (Integer, length) +import Data.Ord (Ord) {- ************************************************************************ @@ -91,7 +92,7 @@ import Prelude (Integer, length) data PromotionFlag = NotPromoted | IsPromoted - deriving ( Eq, Data ) + deriving ( Eq, Data, Ord ) isPromoted :: PromotionFlag -> Bool isPromoted IsPromoted = True ===================================== compiler/Language/Haskell/Syntax/Type.hs-boot ===================================== @@ -2,6 +2,7 @@ module Language.Haskell.Syntax.Type where import Data.Bool import Data.Eq +import Data.Ord {- ************************************************************************ @@ -17,5 +18,6 @@ data PromotionFlag | IsPromoted instance Eq PromotionFlag +instance Ord PromotionFlag isPromoted :: PromotionFlag -> Bool ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 0b64da5b51dac5124b6516af1c402a83ca9d0a0d View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bd21cc372e4a7d3783607896a66736019b9bcb21...829f88c9c22a96d48e121b4769924c7a6ef63e28 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bd21cc372e4a7d3783607896a66736019b9bcb21...829f88c9c22a96d48e121b4769924c7a6ef63e28 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 10:09:34 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 10 Apr 2024 06:09:34 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/iface-sharing-tyconapp Message-ID: <6616655e86e50_c98b02268ae872996@gitlab.mail> Matthew Pickering pushed new branch wip/iface-sharing-tyconapp at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/iface-sharing-tyconapp You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 10:12:30 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 10 Apr 2024 06:12:30 -0400 Subject: [Git][ghc/ghc][wip/iface-sharing-tyconapp] 8 commits: Refactor the Binary serialisation interface Message-ID: <6616660ed3216_c98b02346c1c743bc@gitlab.mail> Matthew Pickering pushed to branch wip/iface-sharing-tyconapp at Glasgow Haskell Compiler / GHC Commits: 68d406f8 by Fendor at 2024-04-10T10:11:27+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: T21839c ------------------------- - - - - - 026372f7 by Fendor at 2024-04-10T10:11:27+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12a3a5d5 by Matthew Pickering at 2024-04-10T10:44:28+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - 4ed1ed63 by Fendor at 2024-04-10T10:44:30+02:00 Add IfaceType deduplication table to .hie serialisation Refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - c4a518b4 by Matthew Pickering at 2024-04-10T10:44:30+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 829f88c9 by Fendor at 2024-04-10T11:58:08+02:00 WIP: CI results for Data.Map deduplication - - - - - 21c66902 by Matthew Pickering at 2024-04-10T11:12:09+01:00 Add some tests to check for size of interface files when serialising various types - - - - - aa5cd630 by Matthew Pickering at 2024-04-10T11:12:09+01:00 Only share IfaceTyConApp - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingFastString.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3080267851a9cb69641cf43b2d3c68da8267d3b...aa5cd6305545e33fc255a8f669aad72907cdec41 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3080267851a9cb69641cf43b2d3c68da8267d3b...aa5cd6305545e33fc255a8f669aad72907cdec41 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 11:26:22 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 07:26:22 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Deleted 1 commit: try not always re-exporting template-haskell in ghc-boot Message-ID: <6616775e9739a_272d9a39f7ec2706f@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: 01b8ad82 by Teo Camarasu at 2024-04-10T10:15:46+01:00 try not always re-exporting template-haskell in ghc-boot - - - - - 4 changed files: - compiler/ghc.cabal.in - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -124,6 +133,10 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if !flag(bootstrap-th) + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -155,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -115,17 +115,13 @@ Library hs-source-dirs: . build-depends: ghc-boot-th == @ProjectVersionMunged@ - , template-haskell == 2.22.0.0 - -- reexport modules from ghc-boot-th and template-haskell so that packages - -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. - -- It makes the dependency graph easier to understand and to refactor - -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + -- reexport modules from ghc-boot-th that packages + -- don't have to import all of ghc-boot, and ghc-boot-th. + -- It makes the dependency graph easier to understand. reexported-modules: GHC.LanguageExtensions.Type , GHC.ForeignSrcLang.Type , GHC.Lexeme - , Language.Haskell.TH - , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -86,5 +95,10 @@ library ghc-heap == @ProjectVersionMunged@, transformers >= 0.5 && < 0.7 + if !flag(bootstrap-th) + Build-Depends: + template-haskell == 2.22.0.0 + + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01b8ad82b641ecb1b6859774e342548049a3bd32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01b8ad82b641ecb1b6859774e342548049a3bd32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 12:04:14 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 08:04:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24624 Message-ID: <6616803eed508_272d9a8815a8368c2@gitlab.mail> Teo Camarasu pushed new branch wip/T24624 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24624 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 12:06:35 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 08:06:35 -0400 Subject: [Git][ghc/ghc][wip/T24624] wip Message-ID: <661680cbbe332_272d9a958fe43881e@gitlab.mail> Teo Camarasu pushed to branch wip/T24624 at Glasgow Haskell Compiler / GHC Commits: ad03706b by Teo Camarasu at 2024-04-10T13:06:29+01:00 wip - - - - - 3 changed files: - hadrian/src/Rules/Compile.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/src/Settings/Packages.hs Changes: ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -13,6 +13,7 @@ import Rules.Generate import Settings import Target import Utilities +import Packages import qualified Text.Parsec as Parsec @@ -219,6 +220,9 @@ compileHsObjectAndHi rs objpath = do (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + when (stage == Stage1 && C.package ctx == ghc) $ do + need [root -/- stageString stage -/- "bin" -/- "ghc-iserv"] + -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). -- Allow such reads (see https://gitlab.haskell.org/ghc/ghc/wikis/Developing-Hadrian#haskell-object-files-and-hi-inputs) ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -48,6 +48,7 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do arg "-dynamic-too" , commonGhcArgs , ghcLinkArgs + , stage1 ? package ghc ? builder (Ghc CompileHs) ? mconcat [arg "-fexternal-interpreter", arg "-pgmi ../../stage1/bin/ghc-iserv"] , defaultGhcWarningsArgs , builder (Ghc CompileHs) ? arg "-c" , getInputs ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -155,10 +155,9 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") - + , builder (Cabal Flags) ? mconcat + [ arg "internal-interpreter" + ] ] , package unix ? builder (Cabal Flags) ? arg "+os-string" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ad03706bbac5111d818e6f039d749a94755259c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ad03706bbac5111d818e6f039d749a94755259c0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 12:25:29 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Wed, 10 Apr 2024 08:25:29 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/24462-quickfix Message-ID: <6616853912b2d_272d9ac97f98446a0@gitlab.mail> Zubin pushed new branch wip/24462-quickfix at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/24462-quickfix You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 12:47:25 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Wed, 10 Apr 2024 08:47:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/9.6.5-backports Message-ID: <66168a5ddb343_272d9a116d5cc556a5@gitlab.mail> Zubin pushed new branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/9.6.5-backports You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 12:51:55 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 08:51:55 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <66168b6bb4d12_272d9a122d9945753c@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 0c00d5b6 by Teo Camarasu at 2024-04-10T13:46:03+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by vendoring the in-tree `template-haskell` into `ghc-boot` thus allowing `stage1:ghc` to depend on the new interface of the library including the `Binary` instances. This is controlled by a `bootstrap-th` cabal flag on `ghc-boot`. When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 - - - - - 11 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,98 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `ghc-boot:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance, which does +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- (SG: at least I think that is the case. Can someone verify? Otherwise +-- it would be conceivable to build just ghc against in-tree TH and +-- keep the boot libraries built against boot TH.) +-- (TC: this might be unblocked in the future if we have a separate +-- package DB for splices.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 2b. Instead of vendoring, build a CPP'd version of in-tree TH by the boot +-- compiler under a changed package-id, e.g., `template-haskell-next`, and +-- build stage1 GHC against that. +-- SG: Why not? + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c00d5b6a506aa6273435ce1127a712d5b1e7b3f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c00d5b6a506aa6273435ce1127a712d5b1e7b3f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:16:09 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 09:16:09 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 5 commits: Bump Cabal submodule to current state of 3.12 branch Message-ID: <6616911911c1e_272d9a176d1846651b@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 5a85e5b1 by Ben Gamari at 2024-04-04T14:24:55-04:00 Bump Cabal submodule to current state of 3.12 branch - - - - - 0fb5c97d by Ben Gamari at 2024-04-08T13:36:25-04:00 base: Deprecate GHC.Pack See #21461. - - - - - 834fe22d by Apoorv Ingle at 2024-04-09T21:17:38-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. (cherry picked from commit 0c48f2b952ad4ee995e4eafa458b7a8d3c442415) - - - - - 93a375be by Ben Gamari at 2024-04-10T09:14:29-04:00 Bump process submodule to 1.6.19.0 Addresses Windows command-line injection vulnerability. - - - - - 66b01dbd by Ben Gamari at 2024-04-10T09:15:27-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 10 changed files: - compiler/GHC/HsToCore/Match.hs - compiler/GHC/Tc/Gen/Do.hs - libraries/Cabal - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs - libraries/process - libraries/unix - + testsuite/tests/patsyn/should_run/T24552.hs - + testsuite/tests/patsyn/should_run/T24552.stdout - testsuite/tests/patsyn/should_run/all.T Changes: ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -29,7 +29,7 @@ import Language.Haskell.Syntax.Basic (Boxity(..)) import {-#SOURCE#-} GHC.HsToCore.Expr (dsExpr) -import GHC.Types.Basic ( Origin(..), requiresPMC, isDoExpansionGenerated ) +import GHC.Types.Basic ( Origin(..), requiresPMC ) import GHC.Types.SourceText ( FractionalLit, @@ -765,20 +765,11 @@ one pattern, and match simply only accepts one pattern. JJQC 30-Nov-1997 -} -matchWrapper ctxt scrs (MG { mg_alts = L _ matches' +matchWrapper ctxt scrs (MG { mg_alts = L _ matches , mg_ext = MatchGroupTc arg_tys rhs_ty origin }) = do { dflags <- getDynFlags ; locn <- getSrcSpanDs - ; let matches - = if any (is_pat_syn_match origin) matches' - then filter (non_gen_wc origin) matches' - -- filter out the wild pattern fail alternatives - -- which have a do expansion origin - -- They generate spurious overlapping warnings - -- Due to pattern synonyms treated as refutable patterns - -- See Part 1's Wrinkle 1 in Note [Expanding HsDo with XXExprGhcRn] in GHC.Tc.Gen.Do - else matches' ; new_vars <- case matches of [] -> newSysLocalsDs arg_tys (m:_) -> @@ -797,6 +788,8 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches' , text "matchPmChecked" <+> ppr (isMatchContextPmChecked dflags origin ctxt)]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt + -- See Note [Expanding HsDo with XXExprGhcRn] Part 1. Wrinkle 1 for + -- pmc for pattern synonyms -- See Note [Long-distance information] in GHC.HsToCore.Pmc then addHsScrutTmCs (concat scrs) new_vars $ @@ -843,16 +836,6 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches' $ NEL.nonEmpty $ replicate (length (grhssGRHSs m)) ldi_nablas - is_pat_syn_match :: Origin -> LMatch GhcTc (LHsExpr GhcTc) -> Bool - is_pat_syn_match origin (L _ (Match _ _ [L _ (VisPat _ l_pat)] _)) | isDoExpansionGenerated origin - = isPatSyn l_pat - is_pat_syn_match _ _ = False - -- generated match pattern that is not a wildcard - non_gen_wc :: Origin -> LMatch GhcTc (LHsExpr GhcTc) -> Bool - non_gen_wc origin (L _ (Match _ _ ([L _ (VisPat _ (L _ (WildPat _)))]) _)) - = not . isDoExpansionGenerated $ origin - non_gen_wc _ _ = True - {- Note [Long-distance information in matchWrapper] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The pattern match checking in matchWrapper is done conditionally, depending ===================================== compiler/GHC/Tc/Gen/Do.hs ===================================== @@ -212,7 +212,7 @@ mk_failable_expr doFlav pat@(L loc _) expr fail_op = mk_fail_block :: HsDoFlavour -> LPat GhcRn -> LHsExpr GhcRn -> FailOperator GhcRn -> TcM (HsExpr GhcRn) mk_fail_block doFlav pat@(L ploc _) e (Just (SyntaxExprRn fail_op)) = do dflags <- getDynFlags - return $ HsLam noAnn LamSingle $ mkMatchGroup (doExpansionOrigin doFlav) -- \ + return $ HsLam noAnn LamCases $ mkMatchGroup (doExpansionOrigin doFlav) -- \ (wrapGenSpan [ genHsCaseAltDoExp doFlav (mkVisPat pat) e -- pat -> expr , fail_alt_case dflags pat fail_op -- _ -> fail "fail pattern" ]) @@ -356,25 +356,42 @@ The `fail`-block wrapping is done by `GHC.Tc.Gen.Do.mk_failable_expr`. of do-notation is that if the pattern match fails, we fail in the monad, *not* just crash at runtime. -* That call of `fail` will (rightly) automatically generate a `MonadFail` constraint. So if the - pattern is irrefuable, we don't want to generate that `fail` alternative, else we'll generate - a `MonadFail` constraint that isn't needed. +* According to the language specification, when the pattern is irrefutable, + we should not add the `fail` alternative. This is important because + the occurrence of `fail` means that the typechecker will generate a `MonadFail` constraint, + and irrefutable patterns shouldn't need a fail alternative. -* _Wrinkle 1_: For pattern synonyms, we always wrap it with a `fail`-block. - When the pattern is irrefutable, we do not add the fail block. - This is important because the occurrence of `fail` means that the typechecker - will generate a `MonadFail` constraint, and the language spec says that - we should not do that for irrefutable patterns. +* _Wrinkel 1_: Note that pattern synonyms count as refutable during type checking, + (see `GHC.Tc.Gen.Pat.isIrrefutableHsPatRnTcM`). They will hence generate a + `MonadFail` constraint and they will always be wrapped in a `fail`able-block. - Note that pattern synonyms count as refutable (see `isIrrefutableHsPat`), and hence will generate - a `MonadFail` constraint, also, we would get a pattern match checker's redundant pattern warnings. - because after desugaring, it is marked as irrefutable! To avoid such - spurious warnings and type checker errors, we filter out those patterns that appear - in a do expansion generated match in `HsToCore.Match.matchWrapper`. (see testcase Typeable1.hs) + Consider a patten synonym declaration (testcase T24552): + + pattern MyJust :: a -> Maybe a + pattern MyJust x <- Just x where MyJust = Just + + and a `do`-block with the following bind and return statement + + do { MyJust x <- [MyNothing, MyJust ()] + ; return x } + + The `do`-expansion will generate the expansion + + (>>=) ([MyNothing, MyJust ()]) + (\case MyJust x -> return x -- (1) + _ -> fail "failable pattern .. " -- (2) + ) + + This code (specifically the `match` spanning lines (1) and (2)) is a compiler generated code; + the associated `Origin` in tagged `Generated` + The alternative statements will thus be ignored by the pattern match check (c.f. `isMatchContextPmChecked`). + This ensures we do not generate spurious redundant-pattern-match warnings due to the line (2) above. + See Note [Generated code and pattern-match checking] + See Note [Long-distance information in matchWrapper] * _Wrinkle 2_: The call to `fail` will give rise to a `MonadFail` constraint. What `CtOrigin` do we - attach to that constraint? It should be a good one, because it'll show up in error - messages when the `MonadFail` constraint can't be solved. Ideally, it should identify the + attach to that constraint? When the `MonadFail` constraint can't be solved, it'll show up in error + messages and it needs to be a good location. Ideally, it should identify the pattern `p`. Hence, we wrap the `fail` alternative expression with a `ExpandedPat` that tags the fail expression with the failable pattern. (See testcase MonadFailErrors.hs) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit fb3f4d47d261f7401e4ea717ffab31af5d5470fb +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/base/changelog.md ===================================== @@ -1,6 +1,7 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit a53f925e3ee246e2429418b7a088ecaa0976007b +Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 ===================================== testsuite/tests/patsyn/should_run/T24552.hs ===================================== @@ -0,0 +1,14 @@ +{-# language PatternSynonyms #-} + +module Main where + +import Prelude +import qualified Prelude as P + +pattern MyNothing :: Maybe a +pattern MyNothing <- Nothing where MyNothing = Nothing + +pattern MyJust :: a -> Maybe a +pattern MyJust x <- Just x where MyJust = Just + +main = print $ do MyJust x <- [MyNothing, MyJust ()] ; return x ===================================== testsuite/tests/patsyn/should_run/T24552.stdout ===================================== @@ -0,0 +1 @@ +[()] ===================================== testsuite/tests/patsyn/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('T11224', normal, compile_and_run, ['-Wincomplete-patterns -Woverlapping-pa test('T13688', req_th, multimod_compile_and_run, ['T13688', '-v0']) test('T14228', normal, compile_and_run, ['']) test('records-poly-update', normal, compile_and_run, ['']) +test('T24552', normal, compile_and_run, ['']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76a0e7f6a197606f950316bd48ae8da04fb9298a...66b01dbd4c4fa7992c1bd99e160e26bba8ed4bff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76a0e7f6a197606f950316bd48ae8da04fb9298a...66b01dbd4c4fa7992c1bd99e160e26bba8ed4bff You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:21:51 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 10 Apr 2024 09:21:51 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6616926f252c1_272d9a1917d54729af@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: d2a7ca25 by Teo Camarasu at 2024-04-10T14:21:32+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by vendoring the in-tree `template-haskell` into `ghc-boot` thus allowing `stage1:ghc` to depend on the new interface of the library including the `Binary` instances. This is controlled by a `bootstrap-th` cabal flag on `ghc-boot`. When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 11 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs - libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,98 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `ghc-boot:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance, which does +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- (SG: at least I think that is the case. Can someone verify? Otherwise +-- it would be conceivable to build just ghc against in-tree TH and +-- keep the boot libraries built against boot TH.) +-- (TC: this might be unblocked in the future if we have a separate +-- package DB for splices.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 2b. Instead of vendoring, build a CPP'd version of in-tree TH by the boot +-- compiler under a changed package-id, e.g., `template-haskell-next`, and +-- build stage1 GHC against that. +-- SG: Why not? + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -115,7 +115,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,6 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +107,6 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text , transformers , unlit @@ -143,6 +141,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +155,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -121,6 +121,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,49 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + build-depends: + ghc-prim + , pretty + -- we vendor ghc-boot-th and template-haskell while bootstrapping TH. + -- This is to avoid having two copies of ghc-boot-th and template-haskell + -- in the build graph: one from the boot compiler and the in-tree one. + hs-source-dirs: . ../ghc-boot-th ../template-haskell ../template-haskell/vendored-filepath + exposed-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Lib + , Language.Haskell.TH.Ppr + , Language.Haskell.TH.PprLib + , Language.Haskell.TH.Quote + , Language.Haskell.TH.Syntax + , Language.Haskell.TH.LanguageExtensions + , Language.Haskell.TH.CodeDo + , Language.Haskell.TH.Lib.Internal + + other-modules: + Language.Haskell.TH.Lib.Map + , System.FilePath + , System.FilePath.Posix + , System.FilePath.Windows + else + hs-source-dirs: . + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + , template-haskell == 2.22.0.0 + -- reexport modules from ghc-boot-th and template-haskell so that packages + -- don't have to import all of ghc-boot, ghc-boot-th and template-haskell. + -- It makes the dependency graph easier to understand and to refactor + -- and reduces the amount of cabal flags we need to use for bootstrapping TH. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + , Language.Haskell.TH + , Language.Haskell.TH.Syntax if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -84,7 +84,6 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 if !os(windows) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Posix ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) ===================================== libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs ===================================== @@ -102,6 +102,7 @@ module System.FilePath.Windows ) where +import Prelude import Data.Char(toLower, toUpper, isAsciiLower, isAsciiUpper) import Data.Maybe(isJust) import Data.List(stripPrefix, isSuffixOf) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2a7ca25b24b1963e33a55a6e00cbd886815de21 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2a7ca25b24b1963e33a55a6e00cbd886815de21 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:26:11 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 09:26:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24646 Message-ID: <661693733b1c4_272d9a1a6f79c772a9@gitlab.mail> Ben Gamari pushed new branch wip/T24646 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24646 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:27:47 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 09:27:47 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Message-ID: <661693d319a4_272d9a1b83ca083367@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: d5e97c23 by Ben Gamari at 2024-04-10T09:22:33-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 1 changed file: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d5e97c234513d283c7b1ea2b90ab32ebcf59b3c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d5e97c234513d283c7b1ea2b90ab32ebcf59b3c8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:31:44 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 09:31:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24640 Message-ID: <661694c093011_272d9a1cd52ac839d2@gitlab.mail> Ben Gamari pushed new branch wip/T24640 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24640 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 13:32:27 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 09:32:27 -0400 Subject: [Git][ghc/ghc][wip/T24640] Bump unix submodule to 2.8.5.1 Message-ID: <661694eb51618_272d9a1d48270857a2@gitlab.mail> Ben Gamari pushed to branch wip/T24640 at Glasgow Haskell Compiler / GHC Commits: 0a6b7ece by Ben Gamari at 2024-04-10T09:32:21-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 1 changed file: - libraries/unix Changes: ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a6b7ece38cea0baf5ac950dcf1b73cca4a75f8a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a6b7ece38cea0baf5ac950dcf1b73cca4a75f8a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 14:46:03 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 10 Apr 2024 10:46:03 -0400 Subject: [Git][ghc/ghc][wip/T23109] Wibble Message-ID: <6616a62b6dc4e_272d9a276ac6c940ad@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 6696873e by Simon Peyton Jones at 2024-04-10T15:45:49+01:00 Wibble - - - - - 2 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2162,9 +2162,10 @@ isEnumerationTyCon :: TyCon -> Bool isEnumerationTyCon (TyCon { tyConArity = arity, tyConDetails = details }) | AlgTyCon { algTcRhs = rhs } <- details = case rhs of - DataTyCon { is_enum = res } -> res - TupleTyCon {} -> arity == 0 - _ -> False + DataTyCon { is_enum = res } -> res + TupleTyCon { tup_sort = tsort } + | arity == 0 -> isBoxed (tupleSortBoxity tsort) + _ -> False | otherwise = False -- | Is this a 'TyCon', synonym or otherwise, that defines a family? ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -587,9 +587,15 @@ dictSelRule val_index n_ty_args _ id_unf _ args mkDataConWorkId :: Name -> DataCon -> Id mkDataConWorkId wkr_name data_con - | isNewTyCon tycon - = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty nt_work_info - -- See Note [Newtype workers] + | isNewTyCon tycon -- See Note [Newtype workers] + = if isClassTyCon tycon then + mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty + (nt_info `setInlinePragInfo` neverInlinePragma { inl_rule = ConLike } + `setUnfoldingInfo` mkDataConUnfolding newtype_rhs) + else + mkGlobalId (DataConWrapId data_con) wkr_name wkr_ty + (nt_info `setInlinePragInfo` dataConWrapperInlinePragma + `setUnfoldingInfo` mkCompulsoryUnfolding newtype_rhs) | otherwise = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty alg_wkr_info @@ -620,18 +626,12 @@ mkDataConWorkId wkr_name data_con univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys - nt_inl_prag | isClassTyCon tycon = neverInlinePragma { inl_rule = ConLike } - | otherwise = dataConWrapperInlinePragma - newtype_unf | isClassTyCon tycon = mkDataConUnfolding newtype_rhs - | otherwise = mkCompulsoryUnfolding newtype_rhs - nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo - `setArityInfo` 1 -- Arity 1 - `setInlinePragInfo` nt_inl_prag - `setUnfoldingInfo` newtype_unf - -- See W1 in Note [LFInfo of DataCon workers and wrappers] + nt_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo + `setArityInfo` 1 -- Arity 1 `setLFInfo` (panic "mkDataConWorkId: we shouldn't look at LFInfo for newtype worker ids") - id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) - res_ty_args = mkTyCoVarTys univ_tvs + -- See W1 in Note [LFInfo of DataCon workers and wrappers] + id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) + res_ty_args = mkTyCoVarTys univ_tvs newtype_rhs = assertPpr (null ex_tcvs && isSingleton arg_tys) (ppr data_con) $ -- Note [Newtype datacons] mkLams univ_tvs $ Lam id_arg1 $ @@ -656,18 +656,18 @@ How do we construct a /correct/ LFInfo for workers and wrappers? (Remember: `LFCon` means "a saturated constructor application") (1) Data constructor workers and wrappers with arity > 0 are unambiguously -functions and should be given `LFReEntrant`, regardless of the runtime -relevance of the arguments. - - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, - and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + functions and should be given `LFReEntrant`, regardless of the runtime + relevance of the arguments. For example: + `Just :: a -> Maybe a` is given `LFReEntrant`, + `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. (2) A datacon /worker/ with zero arity is trivially fully saturated -- it takes -no arguments whatsoever (not even zero-width args), so it is given `LFCon`. + no arguments whatsoever (not even zero-width args), so it is given `LFCon`. (3) Perhaps surprisingly, a datacon /wrapper/ can be an `LFCon`. See Wrinkle (W1) below. -A datacon /wrapper/ with zero arity must be a fully saturated application of -the worker to zero-width arguments only (which are dropped after unarisation), -and therefore is also given `LFCon`. + A datacon /wrapper/ with zero arity must be a fully saturated application of + the worker to zero-width arguments only (which are dropped after unarisation), + and therefore is also given `LFCon`. For example, consider the following data constructors: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6696873e91d463ef522019968169a0e195ab0662 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6696873e91d463ef522019968169a0e195ab0662 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 15:38:26 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 11:38:26 -0400 Subject: [Git][ghc/ghc][wip/or-pats] 132 commits: Remove duplicate code normalising slashes Message-ID: <6616b272c3bfd_272d9a2fa07ec101660@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 145e7efc by Sebastian Graf at 2024-04-10T17:36:05+02:00 Parser: Remove unused `apats` rule - - - - - 99c60f2f by David Knothe at 2024-04-10T17:38:02+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 29 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2bfed745a67e4b461db8ccb241bc734996972e3f...99c60f2f8b4f39a13bc2ca551482cd611886e70b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2bfed745a67e4b461db8ccb241bc734996972e3f...99c60f2f8b4f39a13bc2ca551482cd611886e70b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 15:55:28 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 11:55:28 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616b6701a0ea_165ea6bf2c0936b@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 654e00e1 by David Knothe at 2024-04-10T17:55:18+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/deSugar/should_run/Or5.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/654e00e13dcc47a55b0ab69ad99cde8e805239bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/654e00e13dcc47a55b0ab69ad99cde8e805239bd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 15:56:51 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 11:56:51 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616b6c3cf8c7_165ea619a0c810327@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 5ddc0f3b by David Knothe at 2024-04-10T17:56:46+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/deSugar/should_run/Or5.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ddc0f3ba7500c2dd9beda19d80c057c54495fbc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ddc0f3ba7500c2dd9beda19d80c057c54495fbc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 17:59:55 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 13:59:55 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] Bump stm submodule Message-ID: <6616d39b7df46_165ea6ecf57c17479@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 872427df by Ben Gamari at 2024-04-10T13:59:13-04:00 Bump stm submodule Fixing #24643 - - - - - 1 changed file: - libraries/stm Changes: ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit 4e7aa7885b3f9724b19e68d12cbd2774b11b9bd0 +Subproject commit b77afda28b60f526ebb4be436240afd6ca956673 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/872427dfdb62e6f0482c2dfd63b2d212ef3f68f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/872427dfdb62e6f0482c2dfd63b2d212ef3f68f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 18:11:29 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 14:11:29 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616d651d017_165ea610b31cc18076@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: ed766a7c by David Knothe at 2024-04-10T20:11:20+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed766a7c35fc1b43ee3a67dddaf1b12f03827551 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed766a7c35fc1b43ee3a67dddaf1b12f03827551 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 19:17:28 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 10 Apr 2024 15:17:28 -0400 Subject: [Git][ghc/ghc][wip/T20201] 10 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <6616e5c8b6d74_165ea6183ca38215f1@gitlab.mail> Ben Gamari pushed to branch wip/T20201 at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - c73dc703 by Ben Gamari at 2024-04-10T15:17:10-04:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - e6d181bd by Ben Gamari at 2024-04-10T15:17:10-04:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - 28 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Module/Warnings.hs - ghc/GHCi/UI.hs - libraries/ghci/GHCi/CreateBCO.hs - libraries/ghci/GHCi/ResolvedBCO.hs - rts/RtsFlags.c - − test.hs - testsuite/tests/ghci/should_run/BinaryArray.hs - + testsuite/tests/rts/T20201a.hs - + testsuite/tests/rts/T20201a.stderr - + testsuite/tests/rts/T20201b.hs - + testsuite/tests/rts/T20201b.stderr - testsuite/tests/rts/all.T - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -213,8 +213,8 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm (text "bytecode instruction count mismatch") let asm_insns = ssElts final_insns - insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns - bitmap_arr = mkBitmapArray bsize bitmap + !insns_arr = mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns + !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs) -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive @@ -224,7 +224,7 @@ assembleBCO platform (ProtoBCO { protoBCOName = nm return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64 +mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -60,10 +60,13 @@ linkBCO interp le bco_ix (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do -- fromIntegral Word -> Word64 should be a no op if Word is Word64 -- otherwise it will result in a cast to longlong on 32bit systems. - lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) + (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp le) (elemsFlatBag lits0) ptrs <- mapM (resolvePtr interp le bco_ix) (elemsFlatBag ptrs0) - return (ResolvedBCO isLittleEndian arity insns bitmap - (listArray (0, fromIntegral (sizeFlatBag lits0)-1) lits) + let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits + return (ResolvedBCO isLittleEndian arity + insns + bitmap + (mkBCOByteArray lits') (addListToSS emptySS ptrs)) lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnliftedNewtypes #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types ( CompiledByteCode(..), seqCompiledByteCode + , BCOByteArray(..), mkBCOByteArray , FFIInfo(..) , RegBitmap(..) , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo @@ -34,10 +37,10 @@ import GHCi.BreakArray import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq +import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray ) import Foreign import Data.Array -import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -153,8 +156,8 @@ data UnlinkedBCO = UnlinkedBCO { unlinkedBCOName :: !Name, unlinkedBCOArity :: {-# UNPACK #-} !Int, - unlinkedBCOInstrs :: !(UArray Int Word16), -- insns - unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap + unlinkedBCOInstrs :: !(BCOByteArray Word16), -- insns + unlinkedBCOBitmap :: !(BCOByteArray Word), -- bitmap unlinkedBCOLits :: !(FlatBag BCONPtr), -- non-ptrs unlinkedBCOPtrs :: !(FlatBag BCOPtr) -- ptrs } ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -304,9 +304,18 @@ and updates to multiple buckets with low synchronization overhead. See Note [Updating the FastString table] on how it's updated. -} data FastStringTable = FastStringTable - {-# UNPACK #-} !FastMutInt -- the unique ID counter shared with all buckets - {-# UNPACK #-} !FastMutInt -- number of computed z-encodings for all buckets - (Array# (IORef FastStringTableSegment)) -- concurrent segments + {-# UNPACK #-} !FastMutInt + -- ^ The unique ID counter shared with all buckets + -- + -- We unpack the 'FastMutInt' counter as it is always consumed strictly. + {-# NOUNPACK #-} !FastMutInt + -- ^ Number of computed z-encodings for all buckets. + -- + -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk + -- in 'mkFastStringWith' and needs to be boxed any way. + -- If this is unpacked, then we box this single 'FastMutInt' once for each + -- allocated FastString. + (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments data FastStringTableSegment = FastStringTableSegment {-# UNPACK #-} !(MVar ()) -- the lock for write in each segment ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -350,7 +350,7 @@ hsRecUpdFieldOcc = fmap unambiguousFieldOcc . hfbLHS instance Outputable (HsTyPat p) => Outputable (HsConPatTyArg p) where ppr (HsConPatTyArg _ ty) = char '@' <> ppr ty -instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ Located RecFieldsDotDot) +instance (Outputable arg, Outputable (XRec p (HsRecField p arg)), XRec p RecFieldsDotDot ~ LocatedE RecFieldsDotDot) => Outputable (HsRecFields p arg) where ppr (HsRecFields { rec_flds = flds, rec_dotdot = Nothing }) = braces (fsep (punctuate comma (map ppr flds))) @@ -976,4 +976,4 @@ type instance Anno (Pat (GhcPass p)) = SrcSpanAnnA type instance Anno (HsOverLit (GhcPass p)) = EpAnnCO type instance Anno ConLike = SrcSpanAnnN type instance Anno (HsFieldBind lhs rhs) = SrcSpanAnnA -type instance Anno RecFieldsDotDot = SrcSpan +type instance Anno RecFieldsDotDot = EpaLocation ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1830,7 +1830,7 @@ lPatImplicits = hs_lpat details (RecCon (HsRecFields { rec_dotdot = Nothing, rec_flds })) = hs_lpats $ map (hfbRHS . unLoc) rec_flds details (RecCon (HsRecFields { rec_dotdot = Just (L err_loc rec_dotdot), rec_flds })) - = [(err_loc, implicit_field_binders)] + = [(l2l err_loc, implicit_field_binders)] ++ hs_lpats explicit_pats where (explicit_pats, implicit_field_binders) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -595,8 +595,8 @@ fromIfaceWarnings = \case fromIfaceWarningTxt :: IfaceWarningTxt -> WarningTxt GhcRn fromIfaceWarningTxt = \case - IfWarningTxt mb_cat src strs -> WarningTxt (noLoc . fromWarningCategory <$> mb_cat) src (noLoc <$> map fromIfaceStringLiteralWithNames strs) - IfDeprecatedTxt src strs -> DeprecatedTxt src (noLoc <$> map fromIfaceStringLiteralWithNames strs) + IfWarningTxt mb_cat src strs -> WarningTxt (noLocA . fromWarningCategory <$> mb_cat) src (noLocA <$> map fromIfaceStringLiteralWithNames strs) + IfDeprecatedTxt src strs -> DeprecatedTxt src (noLocA <$> map fromIfaceStringLiteralWithNames strs) fromIfaceStringLiteralWithNames :: (IfaceStringLiteral, [IfExtName]) -> WithHsDocIdentifiers StringLiteral GhcRn fromIfaceStringLiteralWithNames (str, names) = WithHsDocIdentifiers (fromIfaceStringLiteral str) (map noLoc names) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -956,7 +956,9 @@ tc_iface_decl_fingerprint :: Bool -- Don't load pragmas into tc_iface_decl_fingerprint ignore_prags (_version, decl) = do { -- Populate the name cache with final versions of all -- the names associated with the decl - let main_name = ifName decl + let !main_name = ifName decl + -- Force this field access, as `main_name` thunk will otherwise + -- be retained in the thunk created by `forkM`. -- Typecheck the thing, lazily -- NB. Firstly, the laziness is there in case we never need the ===================================== compiler/GHC/Parser.y ===================================== @@ -1964,9 +1964,9 @@ maybe_warning_pragma :: { Maybe (LWarningTxt GhcPs) } (AnnPragma (mo $1) (mc $4) (fst $ unLoc $3))} | {- empty -} { Nothing } -warning_category :: { Maybe (Located InWarningCategory) } - : 'in' STRING { Just (sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) - (sL1 $2 $ mkWarningCategory (getSTRING $2))) } +warning_category :: { Maybe (LocatedE InWarningCategory) } + : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2) + (reLoc $ sL1 $2 $ mkWarningCategory (getSTRING $2))) } | {- empty -} { Nothing } warnings :: { OrdList (LWarnDecl GhcPs) } @@ -4131,8 +4131,8 @@ getSCC lt = do let s = getSTRING lt then addFatalError $ mkPlainErrorMsgEnvelope (getLoc lt) $ PsErrSpaceInSCC else return s -stringLiteralToHsDocWst :: Located StringLiteral -> Located (WithHsDocIdentifiers StringLiteral GhcPs) -stringLiteralToHsDocWst = lexStringLiteral parseIdentifier +stringLiteralToHsDocWst :: Located StringLiteral -> LocatedE (WithHsDocIdentifiers StringLiteral GhcPs) +stringLiteralToHsDocWst sl = reLoc $ lexStringLiteral parseIdentifier sl -- Utilities for combining source spans comb2 :: (HasLoc a, HasLoc b) => a -> b -> SrcSpan @@ -4560,7 +4560,7 @@ addTrailingCommaN (L anns a) span = do addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral addTrailingCommaS (L l sl) span - = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaLocationRealSrcSpan span) }) + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaToNoCommentsLocation span) }) -- ------------------------------------- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -454,27 +454,8 @@ instance Outputable EpaComment where -- annotation. data AddEpAnn = AddEpAnn AnnKeywordId EpaLocation deriving (Data,Eq) --- | The anchor for an @'AnnKeywordId'@. The Parser inserts the --- @'EpaSpan'@ variant, giving the exact location of the original item --- in the parsed source. This can be replaced by the @'EpaDelta'@ --- version, to provide a position for the item relative to the end of --- the previous item in the source. This is useful when editing an --- AST prior to exact printing the changed one. The list of comments --- in the @'EpaDelta'@ variant captures any comments between the prior --- output and the thing being marked here, since we cannot otherwise --- sort the relative order. - -data EpaLocation' a = EpaSpan !SrcSpan - | EpaDelta !DeltaPos !a - deriving (Data,Eq,Show) - type EpaLocation = EpaLocation' [LEpaComment] -type NoCommentsLocation = EpaLocation' NoComments - -data NoComments = NoComments - deriving (Data,Eq,Ord,Show) - epaToNoCommentsLocation :: EpaLocation -> NoCommentsLocation epaToNoCommentsLocation (EpaSpan ss) = EpaSpan ss epaToNoCommentsLocation (EpaDelta dp []) = EpaDelta dp NoComments @@ -492,34 +473,6 @@ data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation instance Outputable a => Outputable (GenLocated TokenLocation a) where ppr (L _ x) = ppr x --- | Spacing between output items when exact printing. It captures --- the spacing from the current print position on the page to the --- position required for the thing about to be printed. This is --- either on the same line in which case is is simply the number of --- spaces to emit, or it is some number of lines down, with a given --- column offset. The exact printing algorithm keeps track of the --- column offset pertaining to the current anchor position, so the --- `deltaColumn` is the additional spaces to add in this case. See --- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for --- details. -data DeltaPos - = SameLine { deltaColumn :: !Int } - | DifferentLine - { deltaLine :: !Int, -- ^ deltaLine should always be > 0 - deltaColumn :: !Int - } deriving (Show,Eq,Ord,Data) - --- | Smart constructor for a 'DeltaPos'. It preserves the invariant --- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. -deltaPos :: Int -> Int -> DeltaPos -deltaPos l c = case l of - 0 -> SameLine c - _ -> DifferentLine l c - -getDeltaLine :: DeltaPos -> Int -getDeltaLine (SameLine _) = 0 -getDeltaLine (DifferentLine r _) = r - -- | Used in the parser only, extract the 'RealSrcSpan' from an -- 'EpaLocation'. The parser will never insert a 'DeltaPos', so the -- partial function is safe. @@ -527,13 +480,6 @@ epaLocationRealSrcSpan :: EpaLocation -> RealSrcSpan epaLocationRealSrcSpan (EpaSpan (RealSrcSpan r _)) = r epaLocationRealSrcSpan _ = panic "epaLocationRealSrcSpan" -instance Outputable NoComments where - ppr NoComments = text "NoComments" - -instance (Outputable a) => Outputable (EpaLocation' a) where - ppr (EpaSpan r) = text "EpaSpan" <+> ppr r - ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs - instance Outputable AddEpAnn where ppr (AddEpAnn kw ss) = text "AddEpAnn" <+> ppr kw <+> ppr ss @@ -1419,10 +1365,6 @@ instance (Outputable a) => Outputable (EpAnn a) where instance Outputable NoEpAnns where ppr NoEpAnns = text "NoEpAnns" -instance Outputable DeltaPos where - ppr (SameLine c) = text "SameLine" <+> ppr c - ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c - instance Outputable (GenLocated NoCommentsLocation EpaComment) where ppr (L l c) = text "L" <+> ppr l <+> ppr c ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2679,7 +2679,7 @@ mkRdrRecordCon con flds anns mk_rec_fields :: [LocatedA (HsRecField (GhcPass p) arg)] -> Maybe SrcSpan -> HsRecFields (GhcPass p) arg mk_rec_fields fs Nothing = HsRecFields { rec_flds = fs, rec_dotdot = Nothing } mk_rec_fields fs (Just s) = HsRecFields { rec_flds = fs - , rec_dotdot = Just (L s (RecFieldsDotDot $ length fs)) } + , rec_dotdot = Just (L (l2l s) (RecFieldsDotDot $ length fs)) } mk_rec_upd_field :: HsRecField GhcPs (LHsExpr GhcPs) -> HsRecUpdField GhcPs GhcPs mk_rec_upd_field (HsFieldBind noAnn (L loc (FieldOcc _ rdr)) arg pun) ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -310,7 +310,7 @@ rnWarningTxt :: WarningTxt GhcPs -> RnM (WarningTxt GhcRn) rnWarningTxt (WarningTxt mb_cat st wst) = do forM_ mb_cat $ \(L _ (InWarningCategory _ _ (L loc cat))) -> unless (validWarningCategory cat) $ - addErrAt loc (TcRnInvalidWarningCategory cat) + addErrAt (locA loc) (TcRnInvalidWarningCategory cat) wst' <- traverse (traverse rnHsDoc) wst pure (WarningTxt mb_cat st wst') rnWarningTxt (DeprecatedTxt st wst) = do ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -775,7 +775,7 @@ rnHsRecPatsAndThen mk (L _ con) do { arg' <- rnLPatAndThen (nested_mk dd mk (RecFieldsDotDot n')) (hfbRHS fld) ; return (L l (fld { hfbRHS = arg' })) } - loc = maybe noSrcSpan getLoc dd + loc = maybe noSrcSpan getLocA dd -- Don't warn for let P{..} = ... in ... check_unused_wildcard = case mk of @@ -873,12 +873,12 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) , hfbRHS = arg' , hfbPun = pun } } - rn_dotdot :: Maybe (Located RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat + rn_dotdot :: Maybe (LocatedE RecFieldsDotDot) -- See Note [DotDot fields] in GHC.Hs.Pat -> Maybe Name -- The constructor (Nothing for an -- out of scope constructor) -> [LHsRecField GhcRn (LocatedA arg)] -- Explicit fields -> RnM ([LHsRecField GhcRn (LocatedA arg)]) -- Field Labels we need to fill in - rn_dotdot (Just (L loc (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match + rn_dotdot (Just (L loc_e (RecFieldsDotDot n))) (Just con) flds -- ".." on record construction / pat match | not (isUnboundName con) -- This test is because if the constructor -- isn't in scope the constructor lookup will add -- an error but still return an unbound name. We @@ -910,6 +910,7 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) _other -> True ] ; addUsedGREs NoDeprecationWarnings dot_dot_gres + ; let loc = locA loc_e ; let locn = noAnnSrcSpan loc ; return [ L (noAnnSrcSpan loc) (HsFieldBind { hfbAnn = noAnn ===================================== compiler/GHC/Types/SourceText.hs ===================================== @@ -305,17 +305,13 @@ data StringLiteral = StringLiteral { sl_st :: SourceText, -- literal raw source. -- See Note [Literal source text] sl_fs :: FastString, -- literal string value - sl_tc :: Maybe RealSrcSpan -- Location of + sl_tc :: Maybe NoCommentsLocation + -- Location of -- possible -- trailing comma -- AZ: if we could have a LocatedA -- StringLiteral we would not need sl_tc, but -- that would cause import loops. - - -- AZ:2: sl_tc should be an EpaAnchor, to allow - -- editing and reprinting the AST. Need a more - -- robust solution. - } deriving Data instance Eq StringLiteral where ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -109,6 +109,10 @@ module GHC.Types.SrcLoc ( mkSrcSpanPs, combineRealSrcSpans, psLocatedToLocated, + + -- * Exact print locations + EpaLocation'(..), NoCommentsLocation, NoComments(..), + DeltaPos(..), deltaPos, getDeltaLine, ) where import GHC.Prelude @@ -894,3 +898,70 @@ psSpanEnd (PsSpan r b) = PsLoc (realSrcSpanEnd r) (bufSpanEnd b) mkSrcSpanPs :: PsSpan -> SrcSpan mkSrcSpanPs (PsSpan r b) = RealSrcSpan r (Strict.Just b) + +-- --------------------------------------------------------------------- +-- The following section contains basic types related to exact printing. +-- See https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +-- This is only s subset, to prevent import loops. The balance are in +-- GHC.Parser.Annotation +-- --------------------------------------------------------------------- + + +-- | The anchor for an @'AnnKeywordId'@. The Parser inserts the +-- @'EpaSpan'@ variant, giving the exact location of the original item +-- in the parsed source. This can be replaced by the @'EpaDelta'@ +-- version, to provide a position for the item relative to the end of +-- the previous item in the source. This is useful when editing an +-- AST prior to exact printing the changed one. The list of comments +-- in the @'EpaDelta'@ variant captures any comments between the prior +-- output and the thing being marked here, since we cannot otherwise +-- sort the relative order. + +data EpaLocation' a = EpaSpan !SrcSpan + | EpaDelta !DeltaPos !a + deriving (Data,Eq,Show) + +type NoCommentsLocation = EpaLocation' NoComments + +data NoComments = NoComments + deriving (Data,Eq,Ord,Show) + +-- | Spacing between output items when exact printing. It captures +-- the spacing from the current print position on the page to the +-- position required for the thing about to be printed. This is +-- either on the same line in which case is is simply the number of +-- spaces to emit, or it is some number of lines down, with a given +-- column offset. The exact printing algorithm keeps track of the +-- column offset pertaining to the current anchor position, so the +-- `deltaColumn` is the additional spaces to add in this case. See +-- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations for +-- details. +data DeltaPos + = SameLine { deltaColumn :: !Int } + | DifferentLine + { deltaLine :: !Int, -- ^ deltaLine should always be > 0 + deltaColumn :: !Int + } deriving (Show,Eq,Ord,Data) + +-- | Smart constructor for a 'DeltaPos'. It preserves the invariant +-- that for the 'DifferentLine' constructor 'deltaLine' is always > 0. +deltaPos :: Int -> Int -> DeltaPos +deltaPos l c = case l of + 0 -> SameLine c + _ -> DifferentLine l c + +getDeltaLine :: DeltaPos -> Int +getDeltaLine (SameLine _) = 0 +getDeltaLine (DifferentLine r _) = r + +instance Outputable NoComments where + ppr NoComments = text "NoComments" + +instance (Outputable a) => Outputable (EpaLocation' a) where + ppr (EpaSpan r) = text "EpaSpan" <+> ppr r + ppr (EpaDelta d cs) = text "EpaDelta" <+> ppr d <+> ppr cs + +instance Outputable DeltaPos where + ppr (SameLine c) = text "SameLine" <+> ppr c + ppr (DifferentLine l c) = text "DifferentLine" <+> ppr l <+> ppr c ===================================== compiler/GHC/Unit/Module/Warnings.hs ===================================== @@ -121,11 +121,11 @@ data InWarningCategory = InWarningCategory { iwc_in :: !(EpToken "in"), iwc_st :: !SourceText, - iwc_wc :: (Located WarningCategory) + iwc_wc :: (LocatedE WarningCategory) } deriving Data fromWarningCategory :: WarningCategory -> InWarningCategory -fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLoc wc) +fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLocA wc) -- See Note [Warning categories] @@ -201,14 +201,14 @@ type LWarningTxt pass = XRec pass (WarningTxt pass) -- reason/explanation from a WARNING or DEPRECATED pragma data WarningTxt pass = WarningTxt - (Maybe (Located InWarningCategory)) + (Maybe (LocatedE InWarningCategory)) -- ^ Warning category attached to this WARNING pragma, if any; -- see Note [Warning categories] SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] | DeprecatedTxt SourceText - [Located (WithHsDocIdentifiers StringLiteral pass)] + [LocatedE (WithHsDocIdentifiers StringLiteral pass)] deriving Generic -- | To which warning category does this WARNING or DEPRECATED pragma belong? @@ -218,7 +218,7 @@ warningTxtCategory (WarningTxt (Just (L _ (InWarningCategory _ _ (L _ cat)))) _ warningTxtCategory _ = defaultWarningCategory -- | The message that the WarningTxt was specified to output -warningTxtMessage :: WarningTxt p -> [Located (WithHsDocIdentifiers StringLiteral p)] +warningTxtMessage :: WarningTxt p -> [LocatedE (WithHsDocIdentifiers StringLiteral p)] warningTxtMessage (WarningTxt _ _ m) = m warningTxtMessage (DeprecatedTxt _ m) = m @@ -260,7 +260,7 @@ instance Outputable (WarningTxt pass) where NoSourceText -> pp_ws ds SourceText src -> ftext src <+> pp_ws ds <+> text "#-}" -pp_ws :: [Located (WithHsDocIdentifiers StringLiteral pass)] -> SDoc +pp_ws :: [LocatedE (WithHsDocIdentifiers StringLiteral pass)] -> SDoc pp_ws [l] = ppr $ unLoc l pp_ws ws = text "[" ===================================== ghc/GHCi/UI.hs ===================================== @@ -557,7 +557,8 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, ===================================== libraries/ghci/GHCi/CreateBCO.hs ===================================== @@ -68,9 +68,6 @@ createBCO arr bco return (HValue final_bco) } -toWordArray :: UArray Int Word64 -> UArray Int Word -toWordArray = amap fromIntegral - linkBCO' :: Array Int HValue -> ResolvedBCO -> IO BCO linkBCO' arr ResolvedBCO{..} = do let @@ -80,11 +77,10 @@ linkBCO' arr ResolvedBCO{..} = do !(I# arity#) = resolvedBCOArity !(EmptyArr empty#) = emptyArr -- See Note [BCO empty array] - - barr a = case a of UArray _lo _hi n b -> if n == 0 then empty# else b - insns_barr = barr resolvedBCOInstrs - bitmap_barr = barr (toWordArray resolvedBCOBitmap) - literals_barr = barr (toWordArray resolvedBCOLits) + barr arr# = if I# (sizeofByteArray# arr#) == 0 then empty# else arr# + insns_barr = barr (getBCOByteArray resolvedBCOInstrs) + bitmap_barr = barr (getBCOByteArray resolvedBCOBitmap) + literals_barr = barr (getBCOByteArray resolvedBCOLits) PtrsArr marr <- mkPtrsArray arr n_ptrs ptrs IO $ \s -> ===================================== libraries/ghci/GHCi/ResolvedBCO.hs ===================================== @@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving, - BangPatterns, CPP #-} + BangPatterns, CPP, MagicHash, FlexibleInstances, FlexibleContexts, + TypeApplications, ScopedTypeVariables, UnboxedTuples #-} module GHCi.ResolvedBCO ( ResolvedBCO(..) , ResolvedBCOPtr(..) , isLittleEndian + , BCOByteArray(..) + , mkBCOByteArray ) where import Prelude -- See note [Why do we import Prelude here?] @@ -11,11 +14,19 @@ import GHC.Data.SizedSeq import GHCi.RemoteTypes import GHCi.BreakArray -import Data.Array.Unboxed import Data.Binary +import Data.Binary.Put (putBuilder) import GHC.Generics -import GHCi.BinaryArray +import Foreign.Ptr +import Data.Array.Byte +import qualified Data.Binary.Get.Internal as Binary +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Builder.Internal as BB +import GHC.Exts +import Data.Array.Base (UArray(..)) + +import GHC.IO #include "MachDeps.h" @@ -32,19 +43,35 @@ isLittleEndian = True -- | A 'ResolvedBCO' is one in which all the 'Name' references have been -- resolved to actual addresses or 'RemoteHValues'. -- --- Note, all arrays are zero-indexed (we assume this when --- serializing/deserializing) data ResolvedBCO = ResolvedBCO { resolvedBCOIsLE :: Bool, resolvedBCOArity :: {-# UNPACK #-} !Int, - resolvedBCOInstrs :: UArray Int Word16, -- insns - resolvedBCOBitmap :: UArray Int Word64, -- bitmap - resolvedBCOLits :: UArray Int Word64, -- non-ptrs + resolvedBCOInstrs :: BCOByteArray Word16, -- insns + resolvedBCOBitmap :: BCOByteArray Word, -- bitmap + resolvedBCOLits :: BCOByteArray Word, -- non-ptrs resolvedBCOPtrs :: (SizedSeq ResolvedBCOPtr) -- ptrs } deriving (Generic, Show) +-- | Wrapper for a 'ByteArray#'. +-- The phantom type tells what elements are stored in the 'ByteArray#'. +-- Creating a 'ByteArray#' can be achieved using 'UArray''s API, +-- where the underlying 'ByteArray#' can be unpacked. +data BCOByteArray a + = BCOByteArray { + getBCOByteArray :: !ByteArray# + } + +mkBCOByteArray :: UArray Int a -> BCOByteArray a +mkBCOByteArray (UArray _ _ _ arr) = BCOByteArray arr + +instance Show (BCOByteArray Word16) where + showsPrec _ _ = showString "BCOByteArray Word16" + +instance Show (BCOByteArray Word) where + showsPrec _ _ = showString "BCOByteArray Word" + -- | The Binary instance for ResolvedBCOs. -- -- Note, that we do encode the endianness, however there is no support for mixed @@ -54,12 +81,16 @@ instance Binary ResolvedBCO where put ResolvedBCO{..} = do put resolvedBCOIsLE put resolvedBCOArity - putArray resolvedBCOInstrs - putArray resolvedBCOBitmap - putArray resolvedBCOLits + put resolvedBCOInstrs + put resolvedBCOBitmap + put resolvedBCOLits put resolvedBCOPtrs - get = ResolvedBCO - <$> get <*> get <*> getArray <*> getArray <*> getArray <*> get + get = ResolvedBCO <$> get <*> get <*> get <*> get <*> get <*> get + +instance Binary (BCOByteArray a) where + put = putBCOByteArray + get = decodeBCOByteArray + data ResolvedBCOPtr = ResolvedBCORef {-# UNPACK #-} !Int @@ -75,3 +106,65 @@ data ResolvedBCOPtr deriving (Generic, Show) instance Binary ResolvedBCOPtr + +-- -------------------------------------------------------- +-- Serialisers for 'BCOByteArray' +-- -------------------------------------------------------- + +putBCOByteArray :: BCOByteArray a -> Put +putBCOByteArray (BCOByteArray bar) = do + put (I# (sizeofByteArray# bar)) + putBuilder $ byteArrayBuilder bar + +decodeBCOByteArray :: Get (BCOByteArray a) +decodeBCOByteArray = do + n <- get + getByteArray n + +byteArrayBuilder :: ByteArray# -> BB.Builder +byteArrayBuilder arr# = BB.builder $ go 0 (I# (sizeofByteArray# arr#)) + where + go :: Int -> Int -> BB.BuildStep a -> BB.BuildStep a + go !inStart !inEnd k (BB.BufferRange outStart outEnd) + -- There is enough room in this output buffer to write all remaining array + -- contents + | inRemaining <= outRemaining = do + copyByteArrayToAddr arr# inStart outStart inRemaining + k (BB.BufferRange (outStart `plusPtr` inRemaining) outEnd) + -- There is only enough space for a fraction of the remaining contents + | otherwise = do + copyByteArrayToAddr arr# inStart outStart outRemaining + let !inStart' = inStart + outRemaining + return $! BB.bufferFull 1 outEnd (go inStart' inEnd k) + where + inRemaining = inEnd - inStart + outRemaining = outEnd `minusPtr` outStart + + copyByteArrayToAddr :: ByteArray# -> Int -> Ptr a -> Int -> IO () + copyByteArrayToAddr src# (I# src_off#) (Ptr dst#) (I# len#) = + IO $ \s -> case copyByteArrayToAddr# src# src_off# dst# len# s of + s' -> (# s', () #) + +getByteArray :: Int -> Get (BCOByteArray a) +getByteArray nbytes@(I# nbytes#) = do + let !(MutableByteArray arr#) = unsafeDupablePerformIO $ + IO $ \s -> case newByteArray# nbytes# s of + (# s', mbar #) -> (# s', MutableByteArray mbar #) + let go 0 _ = return () + go !remaining !off = do + Binary.readNWith n $ \ptr -> + copyAddrToByteArray ptr arr# off n + go (remaining - n) (off + n) + where n = min chunkSize remaining + go nbytes 0 + return $! unsafeDupablePerformIO $ + IO $ \s -> case unsafeFreezeByteArray# arr# s of + (# s', bar #) -> (# s', BCOByteArray bar #) + where + chunkSize = 10*1024 + + copyAddrToByteArray :: Ptr a -> MutableByteArray# RealWorld + -> Int -> Int -> IO () + copyAddrToByteArray (Ptr src#) dst# (I# dst_off#) (I# len#) = + IO $ \s -> case copyAddrToByteArray# src# dst# dst_off# len# s of + s' -> (# s', () #) ===================================== rts/RtsFlags.c ===================================== @@ -2124,7 +2124,6 @@ static void initStatsFile (FILE *f) static StgWord64 decodeSize(const char *flag, uint32_t offset, StgWord64 min, StgWord64 max) { - char c; const char *s; StgDouble m; StgWord64 val; @@ -2137,19 +2136,45 @@ decodeSize(const char *flag, uint32_t offset, StgWord64 min, StgWord64 max) } else { - m = atof(s); - c = s[strlen(s)-1]; - - if (c == 't' || c == 'T') - m *= (StgWord64)1024*1024*1024*1024; - else if (c == 'g' || c == 'G') - m *= 1024*1024*1024; - else if (c == 'm' || c == 'M') - m *= 1024*1024; - else if (c == 'k' || c == 'K') - m *= 1024; - else if (c == 'w' || c == 'W') - m *= sizeof(W_); + char *end; + m = strtod(s, &end); + + if (end == s) { + errorBelch("error in RTS option %s: unable to parse number '%s'", flag, s); + stg_exit(EXIT_FAILURE); + } + + StgWord64 unit; + switch (*end) { + case 't': + case 'T': + unit = (StgWord64)1024*1024*1024*1024; + break; + case 'g': + case 'G': + unit = 1024*1024*1024; + break; + case 'm': + case 'M': + unit = 1024*1024; + break; + case 'k': + case 'K': + unit = 1024; + break; + case 'w': + case 'W': + unit = sizeof(W_); + break; + case '\0': + unit = 1; + break; + default: + errorBelch("error in RTS option %s: unknown unit suffix '%c'", flag, *end); + stg_exit(EXIT_FAILURE); + } + + m *= unit; } val = (StgWord64)m; ===================================== test.hs deleted ===================================== @@ -1,14 +0,0 @@ -import Data.Char -import Data.Foldable --- | Just like 'GHC.ResponseFile.escapeArg', but it is not exposed from base. -escapeArg :: String -> String -escapeArg = reverse . foldl' escape [] - -escape :: String -> Char -> String -escape cs c - | isSpace c - || '\\' == c - || '\'' == c - || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result - | otherwise = c:cs - ===================================== testsuite/tests/ghci/should_run/BinaryArray.hs ===================================== @@ -1,11 +1,15 @@ -{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleContexts, MagicHash, ScopedTypeVariables #-} import Data.Binary.Get import Data.Binary.Put +import Data.Binary (get, put) +import Data.Array.Byte import Data.Array.Unboxed as AU import Data.Array.IO (IOUArray) import Data.Array.MArray (MArray) import Data.Array as A +import Data.Array.Base as A import GHCi.BinaryArray +import GHCi.ResolvedBCO import GHC.Word roundtripTest :: (IArray UArray a, MArray IOUArray a IO, Eq a) @@ -18,6 +22,17 @@ roundtripTest arr = | otherwise -> putStrLn "failed to round-trip" Left _ -> putStrLn "deserialization failed" +roundtripTestByteArray :: forall a . (IArray UArray a, MArray IOUArray a IO, Eq a) + => UArray Int a -> IO () +roundtripTestByteArray (UArray _ _ _ arr#) = + let val = BCOByteArray arr# :: BCOByteArray a + ser = Data.Binary.Put.runPut $ put val + in case Data.Binary.Get.runGetOrFail (get :: Get (BCOByteArray a)) ser of + Right (_, _, BCOByteArray arr'# ) + | ByteArray arr# == ByteArray arr'# -> return () + | otherwise -> putStrLn "failed to round-trip" + Left _ -> putStrLn "deserialization failed" + main :: IO () main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Int) @@ -27,3 +42,10 @@ main = do roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word32) roundtripTest (AU.listArray (1,500) [1..] :: UArray Int Word64) roundtripTest (AU.listArray (1,500) ['a'..] :: UArray Int Char) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Int) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word8) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word16) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word32) + roundtripTestByteArray (AU.listArray (1,500) [1..] :: UArray Int Word64) + roundtripTestByteArray (AU.listArray (1,500) ['a'..] :: UArray Int Char) ===================================== testsuite/tests/rts/T20201a.hs ===================================== @@ -0,0 +1 @@ +main = putStrLn "hi" ===================================== testsuite/tests/rts/T20201a.stderr ===================================== @@ -0,0 +1 @@ +T20201a: error in RTS option -AturtlesM: unable to parse number 'turtlesM' ===================================== testsuite/tests/rts/T20201b.hs ===================================== @@ -0,0 +1,2 @@ +main = putStrLn "hi" + ===================================== testsuite/tests/rts/T20201b.stderr ===================================== @@ -0,0 +1 @@ +T20201b: error in RTS option -A64z: unknown unit suffix 'z' ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,6 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T20201a', exit_code(1), compile_and_run, ['-with-rtsopts -AturtlesM']) +test('T20201b', exit_code(1), compile_and_run, ['-with-rtsopts -A64z']) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -711,6 +711,11 @@ printStringAtMLocL (EpAnn anc an cs) l s = do printStringAtAA :: (Monad m, Monoid w) => EpaLocation -> String -> EP w m EpaLocation printStringAtAA el str = printStringAtAAC CaptureComments el str +printStringAtNC :: (Monad m, Monoid w) => NoCommentsLocation -> String -> EP w m NoCommentsLocation +printStringAtNC el str = do + el' <- printStringAtAAC NoCaptureComments (noCommentsToEpaLocation el) str + return (epaToNoCommentsLocation el') + printStringAtAAL :: (Monad m, Monoid w) => a -> Lens a EpaLocation -> String -> EP w m a printStringAtAAL an l str = do @@ -2117,10 +2122,10 @@ instance ExactPrint StringLiteral where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact l@(StringLiteral src fs mcomma) = do + exact (StringLiteral src fs mcomma) = do printSourceTextAA src (show (unpackFS fs)) - mapM_ (\r -> printStringAtRs r ",") mcomma - return l + mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma + return (StringLiteral src fs mcomma') -- --------------------------------------------------------------------- @@ -3328,12 +3333,13 @@ instance (ExactPrint body) => ExactPrint (HsRecFields GhcPs body) where setAnnotationAnchor a _ _ _ = a exact (HsRecFields fields mdot) = do fields' <- markAnnotated fields - case mdot of - Nothing -> return () - Just (L ss _) -> - printStringAtSs ss ".." >> return () + mdot' <- case mdot of + Nothing -> return Nothing + Just (L ss d) -> do + ss' <- printStringAtAA ss ".." + return $ Just (L ss' d) -- Note: mdot contains the SrcSpan where the ".." appears, if present - return (HsRecFields fields' mdot) + return (HsRecFields fields' mdot') -- --------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63773182b0d55a3d1954c0dfaf5158c595680243...e6d181bd90baa751b80ddc77490e1bbb3bf29a82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63773182b0d55a3d1954c0dfaf5158c595680243...e6d181bd90baa751b80ddc77490e1bbb3bf29a82 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 19:36:58 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 15:36:58 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616ea5a3dc92_165ea61b411fc217b4@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 20e3d922 by David Knothe at 2024-04-10T21:36:52+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/20e3d92268f0613cba4d76ba58f05fa889375704 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/20e3d92268f0613cba4d76ba58f05fa889375704 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 19:40:32 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 15:40:32 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616eb308cb3b_165ea61c75d84227c0@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 87bb7dd9 by David Knothe at 2024-04-10T21:40:21+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst - docs/users_guide/exts/patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87bb7dd930892eec7c2eb83b8f2eaa07d98fcafc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87bb7dd930892eec7c2eb83b8f2eaa07d98fcafc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 10 20:21:41 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 10 Apr 2024 16:21:41 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6616f4d5ee8bd_165ea62256ab43014a@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 7121a485 by David Knothe at 2024-04-10T22:21:36+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7121a48593e4bbac85d729f905c4a643b33a910f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7121a48593e4bbac85d729f905c4a643b33a910f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 04:07:36 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 00:07:36 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 4 commits: Bump process submodule to 1.6.19.0 Message-ID: <66176208b885c_327663952d24772ad@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 76a0f8f2 by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump process submodule to 1.6.19.0 Addresses Windows command-line injection vulnerability. - - - - - 086698ba by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 21c9c1bc by Ben Gamari at 2024-04-11T00:07:21-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - aa5b34e1 by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump stm submodule Fixing #24643 - - - - - 5 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - libraries/process - libraries/stm - libraries/unix - testsuite/tests/process/process004.stdout Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit a53f925e3ee246e2429418b7a088ecaa0976007b +Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit 4e7aa7885b3f9724b19e68d12cbd2774b11b9bd0 +Subproject commit b77afda28b60f526ebb4be436240afd6ca956673 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 ===================================== testsuite/tests/process/process004.stdout ===================================== @@ -1,2 +1,2 @@ -Exc: true: runInteractiveProcess: chdir: invalid argument (Bad file descriptor) +Exc: true: runInteractiveProcess: chdir: does not exist (No such file or directory) Exc: true: runProcess: chdir: does not exist (No such file or directory) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/872427dfdb62e6f0482c2dfd63b2d212ef3f68f5...aa5b34e1643df9c44eaebea38cb58dafaf60cb4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/872427dfdb62e6f0482c2dfd63b2d212ef3f68f5...aa5b34e1643df9c44eaebea38cb58dafaf60cb4b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 07:51:35 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 11 Apr 2024 03:51:35 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ifacetype-delay-serialisation Message-ID: <66179687cd077_3276632369410874c8@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ifacetype-delay-serialisation at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ifacetype-delay-serialisation You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 08:03:28 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 11 Apr 2024 04:03:28 -0400 Subject: [Git][ghc/ghc][wip/24462-quickfix] Disable `-fasm-shortcutting` on -O2 and warn about its usage. Message-ID: <661799507938d_32766324f7714893ed@gitlab.mail> Zubin pushed to branch wip/24462-quickfix at Glasgow Haskell Compiler / GHC Commits: 55a82c3c by Zubin Duggal at 2024-04-11T13:33:15+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24462). - - - - - 5 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/bugs.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -67,7 +67,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1263,7 +1263,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2356,7 +2356,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, ===================================== docs/users_guide/bugs.rst ===================================== @@ -694,6 +694,9 @@ Bugs in GHC - Because of a toolchain limitation we are unable to support full Unicode paths on Windows. On Windows we support up to Latin-1. See :ghc-ticket:`12971` for more. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ as such you shouldn't need to set any of them explicitly. A flag generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ as such you shouldn't need to set any of them explicitly. A flag these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. Implied by :ghc-flag:`-O`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55a82c3c80ab41d2cfbbe859a25c07219f501922 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55a82c3c80ab41d2cfbbe859a25c07219f501922 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 08:14:16 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 11 Apr 2024 04:14:16 -0400 Subject: [Git][ghc/ghc][wip/24462-quickfix] Disable `-fasm-shortcutting` on -O2 and warn about its usage. Message-ID: <66179bd8d3c7c_32766326ed48891317@gitlab.mail> Zubin pushed to branch wip/24462-quickfix at Glasgow Haskell Compiler / GHC Commits: 4ae8d89e by Zubin Duggal at 2024-04-11T13:43:53+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). - - - - - 5 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/bugs.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -67,7 +67,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1263,7 +1263,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2356,7 +2356,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, ===================================== docs/users_guide/bugs.rst ===================================== @@ -694,6 +694,9 @@ Bugs in GHC - Because of a toolchain limitation we are unable to support full Unicode paths on Windows. On Windows we support up to Latin-1. See :ghc-ticket:`12971` for more. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ as such you shouldn't need to set any of them explicitly. A flag generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ as such you shouldn't need to set any of them explicitly. A flag these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. Implied by :ghc-flag:`-O`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ae8d89e376d79b4188c61e6469c7f01d8445768 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ae8d89e376d79b4188c61e6469c7f01d8445768 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 08:16:10 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 11 Apr 2024 04:16:10 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] 3 commits: Bump process submodule to 1.6.19.0 Message-ID: <66179c4a5072f_32766327bf4b09187@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: a2897a32 by Zubin Duggal at 2024-04-11T13:44:48+05:30 Bump process submodule to 1.6.19.0 - - - - - f4028647 by Zubin Duggal at 2024-04-11T13:44:48+05:30 Prepare release 9.6.5 - - - - - 29418a1a by Zubin Duggal at 2024-04-11T13:45:55+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - 10 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Session.hs - configure.ac - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/using-optimisation.rst - libraries/base/base.cabal - libraries/base/changelog.md - libraries/process Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -66,7 +66,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3363,7 +3363,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, @@ -4002,7 +4003,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are ===================================== docs/users_guide/9.6.5-notes.rst ===================================== @@ -0,0 +1,110 @@ +.. _release-9.6.5: + +Version 9.6.5 +============== + +The significant changes to the various parts of the compiler are listed below. +See the `migration guide +`_ on the GHC Wiki +for specific guidance on migrating programs to this release. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +11, 12, 13, 14 or 15. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Disable ``-fasm-shortcutting`` with ``-O2`` as it leads to unsound optimisations + (:ghc-ticket:`24462). +- Fix a typechecker bug resulting in ``TYPE`` and ``CONSTRAINT`` being apart + (:ghc-ticket:`24279`). +- Fix a bug resulting in incorrect runtime results due to a botched simplifier + pass (:ghc-ticket:`24295`). +- Assign correct source spans to nested documentation comments in the AST (:ghc-ticket:`24378`). +- Fix a bug causing suboptimal error messages for certain invalid cyclic + module graphs with hs-boot files (:ghc-ticket:`24196`, :ghc-ticket:`24275`). +- Fix a bug resulting in infix ``(~)`` and ``(@)`` operators not being usable in + TH quotes (:ghc-ticket:`23748`). +- Fix a bug arising from incorrect parsing of paths containing spaces in the + settings file (:ghc-ticket:`24265`). +- Allow special pragmas to desugar correctly in a few more cases (:ghc-ticket:`24370`). + +Runtime system +-------------- + +- Fix an off-by-one while writing eventlogs (:ghc-ticket:`24287`). +- Avoid segfaults with using ``-Dn`` with the non-moving collector (:ghc-ticket:`24393`). + +Build system and packaging +-------------------------- + +- Fix a bug resulting in the distributed ``hsc2hs`` wrapper using flags from the + compiler build environment (:ghc-ticket:`24050`). +- Better compatibility for newer alex versions in the configure script (:ghc-ticket:`24302`). +- Handle autotools adding the ``-std`` flag to the ``CC``/``CXX`` variables (:ghc-ticket:`24324`). +- Fix a typo in the configure script resulting in the target for the linker being set incorrectly + when configuring a cross-compiler (:ghc-ticket:`24414`). +- Do not override existing linker flags in ``FP_LD_NO_FIXUP_CHAINS``. +- Ensure the ``genapply`` program is built with the write constants when cross compiling (:ghc-ticket:`24347`). +- Ensure we take ``LDFLAGS`` into account when configuring a linker (:ghc-ticket:`24565`). +- Fix a segfault with the non-moving GC (:ghc-ticket:`24492`). + +Core libraries +-------------- + +- Bump ``base`` to 4.18.2.1 +- Bump ``filepath`` to 1.4.300.1 +- Bump ``directory`` to 1.3.8.3 +- Bump ``process`` to 1.6.19.0 +- Bump ``libffi-tarballs`` to 3.4.6 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/bugs.rst ===================================== @@ -697,6 +697,9 @@ Bugs in GHC - ``-Wincomplete-record-updates`` does not warn about record updates for records with partial record fields since GHC 9.6.1. See :ghc-ticket:`23520` for more details. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/release-notes.rst ===================================== @@ -8,3 +8,4 @@ Release notes 9.6.2-notes 9.6.3-notes 9.6.4-notes + 9.6.5-notes ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ by saying ``-fno-wombat``. generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ by saying ``-fno-wombat``. these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. :type: dynamic ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.18.2.0 +version: 4.18.2.1 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause ===================================== libraries/base/changelog.md ===================================== @@ -1,5 +1,8 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.18.2.1 *April 2024* + * Various documentation improvements + ## 4.18.2.0 *January 2024* * Update to [Unicode 15.1.0](https://www.unicode.org/versions/Unicode15.1.0/). * Improve String & IsString documentation. ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 3466b14dacddc4628427c4d787482899dd0b17cd +Subproject commit eee87f2838356431930e1fe8f8527db609e3252b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37da54eb8da1273f5cf7d74e3afe702650efbead...29418a1aae93f79ff296d8a2634070cb14cda86f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37da54eb8da1273f5cf7d74e3afe702650efbead...29418a1aae93f79ff296d8a2634070cb14cda86f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 08:45:45 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 11 Apr 2024 04:45:45 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6617a339ecaa3_3276632b9404092277@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 67829917 by David Knothe at 2024-04-11T10:45:39+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/678299177e8c90a9757106604649e044e9c8f7e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/678299177e8c90a9757106604649e044e9c8f7e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 09:38:20 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 11 Apr 2024 05:38:20 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-delay-serialisation] MP fixes Message-ID: <6617af8cca3c5_327663326998896667@gitlab.mail> Matthew Pickering pushed to branch wip/fendor/ifacetype-delay-serialisation at Glasgow Haskell Compiler / GHC Commits: 2076ed5d by Matthew Pickering at 2024-04-11T10:38:01+01:00 MP fixes - - - - - 2 changed files: - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs Changes: ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -2210,7 +2210,7 @@ instance Binary IfaceType where putIfaceType :: WriteBinHandle -> IfaceType -> IO () putIfaceType bh (IfaceSerialisedType fb) = do ity <- getIfaceType =<< thawBinHandle fb - put_ bh ity + putIfaceType bh ity putIfaceType _ (IfaceFreeTyVar tv) = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1385,8 +1385,8 @@ loop. See #19744. tcIfaceType :: IfaceType -> IfL Type tcIfaceType = go where - go (IfaceSerialisedType bs) = do - deserialised <- liftIO (get @IfaceType =<< thawBinHandle bs) + go i@(IfaceSerialisedType bs) = do + deserialised <- liftIO (getIfaceType =<< thawBinHandle bs) go deserialised View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2076ed5d2193fef27ec89fb56da506d37921bca3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2076ed5d2193fef27ec89fb56da506d37921bca3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 10:08:17 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 11 Apr 2024 06:08:17 -0400 Subject: [Git][ghc/ghc][wip/home-unit-closure-fast] driver: Make `checkHomeUnitsClosed` faster Message-ID: <6617b69132277_327663363b5d410457e@gitlab.mail> Zubin pushed to branch wip/home-unit-closure-fast at Glasgow Haskell Compiler / GHC Commits: 29bfe38e by Zubin Duggal at 2024-04-11T15:38:05+05:30 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 6 changed files: - compiler/GHC/Driver/Make.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1565,8 +1565,8 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots (root_errs, rootSummariesOk) <- partitionWithM getRootSummary roots -- #17549 let root_map = mkRootMap rootSummariesOk checkDuplicates root_map - (deps, pkg_deps, map0) <- loopSummaries rootSummariesOk (M.empty, Set.empty, root_map) - let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) (hsc_all_home_unit_ids hsc_env) (Set.toList pkg_deps) + (deps, map0) <- loopSummaries rootSummariesOk (M.empty, root_map) + let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) let unit_env = hsc_unit_env hsc_env let tmpfs = hsc_tmpfs hsc_env @@ -1660,19 +1660,19 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This loops over all the mod summaries in the dependency graph, accumulates the actual dependencies for each module/unit loopSummaries :: [ModSummary] - -> (M.Map NodeKey ModuleGraphNode, Set.Set (UnitId, UnitId), + -> (M.Map NodeKey ModuleGraphNode, DownsweepCache) - -> IO ((M.Map NodeKey ModuleGraphNode), Set.Set (UnitId, UnitId), DownsweepCache) + -> IO ((M.Map NodeKey ModuleGraphNode), DownsweepCache) loopSummaries [] done = return done - loopSummaries (ms:next) (done, pkgs, summarised) + loopSummaries (ms:next) (done, summarised) | Just {} <- M.lookup k done - = loopSummaries next (done, pkgs, summarised) + = loopSummaries next (done, summarised) -- Didn't work out what the imports mean yet, now do that. | otherwise = do - (final_deps, pkgs1, done', summarised') <- loopImports (calcDeps ms) done summarised + (final_deps, done', summarised') <- loopImports (calcDeps ms) done summarised -- This has the effect of finding a .hs file if we are looking at the .hs-boot file. - (_, _, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' - loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', pkgs1 `Set.union` pkgs, summarised'') + (_, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' + loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', summarised'') where k = NodeKey_Module (msKey ms) @@ -1692,18 +1692,17 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- Visited set; the range is a list because -- the roots can have the same module names -- if allow_dup_roots is True - -> IO ([NodeKey], Set.Set (UnitId, UnitId), - + -> IO ([NodeKey], M.Map NodeKey ModuleGraphNode, DownsweepCache) -- The result is the completed NodeMap - loopImports [] done summarised = return ([], Set.empty, done, summarised) + loopImports [] done summarised = return ([], done, summarised) loopImports ((home_uid,mb_pkg, gwib) : ss) done summarised | Just summs <- M.lookup cache_key summarised = case summs of [Right ms] -> do let nk = NodeKey_Module (msKey ms) - (rest, pkgs, summarised', done') <- loopImports ss done summarised - return (nk: rest, pkgs, summarised', done') + (rest, summarised', done') <- loopImports ss done summarised + return (nk: rest, summarised', done') [Left _err] -> loopImports ss done summarised _errs -> do @@ -1715,69 +1714,77 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots Nothing excl_mods case mb_s of NotThere -> loopImports ss done summarised - External uid -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (other_deps, Set.insert (homeUnitId home_unit, uid) pkgs, done', summarised') + External _ -> do + (other_deps, done', summarised') <- loopImports ss done summarised + return (other_deps, done', summarised') FoundInstantiation iud -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (NodeKey_Unit iud : other_deps, pkgs, done', summarised') + (other_deps, done', summarised') <- loopImports ss done summarised + return (NodeKey_Unit iud : other_deps, done', summarised') FoundHomeWithError (_uid, e) -> loopImports ss done (Map.insert cache_key [(Left e)] summarised) FoundHome s -> do - (done', pkgs1, summarised') <- - loopSummaries [s] (done, Set.empty, Map.insert cache_key [Right s] summarised) - (other_deps, pkgs2, final_done, final_summarised) <- loopImports ss done' summarised' + (done', summarised') <- + loopSummaries [s] (done, Map.insert cache_key [Right s] summarised) + (other_deps, final_done, final_summarised) <- loopImports ss done' summarised' -- MP: This assumes that we can only instantiate non home units, which is probably fair enough for now. - return (NodeKey_Module (msKey s) : other_deps, pkgs1 `Set.union` pkgs2, final_done, final_summarised) + return (NodeKey_Module (msKey s) : other_deps, final_done, final_summarised) where cache_key = (home_uid, mb_pkg, unLoc <$> gwib) home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod --- This function checks then important property that if both p and q are home units +-- | This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] --- Fast path, trivially closed. -checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] - | otherwise = - let res = foldMap loop home_imp_ids - -- Now check whether everything which transitively depends on a home_unit is actually a home_unit - -- These units are the ones which we need to load as home packages but failed to do for some reason, - -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids - then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] - +-- +-- See Note [Multiple Home Units], section 'Closure Property'. +checkHomeUnitsClosed :: UnitEnv -> [DriverMessages] +checkHomeUnitsClosed ue + | Set.null bad_unit_ids = [] + | otherwise = [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] where + home_id_set = unitEnv_keys $ ue_home_unit_graph ue + bad_unit_ids = upwards_closure Set.\\ home_id_set rootLoc = mkGeneralSrcSpan (fsLit "") - -- TODO: This could repeat quite a bit of work but I struggled to write this function. - -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit - loop (from_uid, uid) = - let us = ue_findHomeUnitEnv from_uid ue in - let um = unitInfoMap (homeUnitEnv_units us) in - case lookupUniqMap um uid of - Nothing -> pprPanic "uid not found" (ppr uid) - Just ui -> - let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set - in - -- Case 1: The unit directly depends on a home_id - if not (null home_depends) - then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res - -- Case 2: Check the rest of the dependencies, and then see if any of them depended on - else - let res = foldMap (loop . (from_uid,)) other_depends - in - if not (Set.null res) - then Set.insert uid res - else res + + graph :: Graph (Node UnitId UnitId) + graph = graphFromEdgedVerticesUniq graphNodes + + -- downwards closure of graph + downwards_closure + = graphFromEdgedVerticesUniq [ DigraphNode uid uid (Set.toList deps) + | (uid, deps) <- M.toList (allReachable graph node_key)] + + inverse_closure = transposeG downwards_closure + + upwards_closure = Set.fromList $ map node_key $ reachablesG inverse_closure [DigraphNode uid uid [] | uid <- Set.toList home_id_set] + + all_unit_direct_deps :: UniqMap UnitId (Set.Set UnitId) + all_unit_direct_deps + = unitEnv_foldWithKey go emptyUniqMap $ ue_home_unit_graph ue + where + go rest this this_uis = + plusUniqMap_C Set.union + (addToUniqMap_C Set.union external_depends this (Set.fromList $ this_deps)) + rest + where + external_depends = mapUniqMap (Set.fromList . unitDepends) (unitInfoMap this_units) + this_units = homeUnitEnv_units this_uis + this_deps = [ toUnitId unit | (unit,Just _) <- explicitUnits this_units] + + graphNodes :: [Node UnitId UnitId] + graphNodes = go Set.empty home_id_set + where + go done todo + = case Set.minView todo of + Nothing -> [] + Just (uid, todo') + | Set.member uid done -> go done todo' + | otherwise -> case lookupUniqMap all_unit_direct_deps uid of + Nothing -> pprPanic "uid not found" (ppr (uid, all_unit_direct_deps)) + Just depends -> + let todo'' = (depends Set.\\ done) `Set.union` todo' + in DigraphNode uid uid (Set.toList depends) : go (Set.insert uid done) todo'' -- | Update the every ModSummary that is depended on -- by a module that needs template haskell. We enable codegen to ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile ===================================== @@ -0,0 +1,23 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +SETUP=../Setup -v0 + +mhu-perf: clean + $(MAKE) -s --no-print-directory clean + ./genLargeHMU + '$(GHC_PKG)' init tmp.d + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make Setup + for dir in unit-p*; do \ + cd $$dir && $(SETUP) clean && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --ipid=$$dir-0.1.0.0 --with-ghc='$(TEST_HC)' --with-hc-pkg='$(GHC_PKG)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d && $(SETUP) build && $(SETUP) register --inplace && cd ..; \ + done; + + +ifeq "$(CLEANUP)" "1" + $(MAKE) -s --no-print-directory clean +endif + +clean : + $(RM) -r unitTop* unit-p* top*/ tmp*.d inst-* *.o *.hi */*.o */*.hi */Setup$(exeext) */dist Setup$(exeext) + ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs ===================================== @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -0,0 +1,10 @@ +test('mhu-perf', + [ collect_compiler_stats('bytes allocated',2), + extra_files(['genLargeHMU','Setup.hs']), + pre_cmd('$MAKE -s --no-print-directory mhu-perf'), + js_broken(22349), + when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests + compile_timeout_multiplier(5) + ], + multiunit_compile, + [['unitTop1', 'unitTop2'], '-fhide-source-paths']) ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU ===================================== @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of packages with $WIDTH modules on each layer +# Every package on layer N depends on all the packages on layer N-1 +# unitTop imports all the units from the last layer +DEPTH=8 +WIDTH=8 +for i in $(seq -w 1 $WIDTH); do + mkdir unit-p0M$i + echo "module DummyLevel0M$i where" > unit-p0M$i/DummyLevel0M$i.hs; + cat > unit-p0M$i/unit-p0M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel0M$i + build-depends: base +EOF +done +for l in $(seq 1 $DEPTH); do + for i in $(seq -w 1 $WIDTH); do + mkdir unit-p${l}M$i + cat > unit-p${l}M$i/unit-p${l}M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel${l}M$i + build-depends: base +EOF + echo "module DummyLevel${l}M$i where" > unit-p${l}M$i/DummyLevel${l}M$i.hs; + for j in $(seq -w 1 $WIDTH); do + echo " , unit-p$((l-1))M$j" >> unit-p${l}M$i/unit-p${l}M$i.cabal + echo "import DummyLevel$((l-1))M$j" >> unit-p${l}M$i/DummyLevel${l}M$i.hs; + done + done +done +mkdir top1 +echo "module Top1 where" > top1/Top1.hs +echo "-package-db ./tmp.d -i -itop1 Top1 -this-unit-id unit-top1 -package base" > unitTop1; +for j in $(seq -w 1 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop1; + echo "import DummyLevel${DEPTH}M$j" >> top1/Top1.hs; +done +mkdir top2 +echo "module Top2 where" > top2/Top2.hs +echo "-package-db ./tmp.d -i -itop2 Top2 -this-unit-id unit-top2 -package base" > unitTop2; +for j in $(seq -w 2 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop2; + echo "import DummyLevel${DEPTH}M$j" >> top2/Top2.hs; +done ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr ===================================== @@ -0,0 +1,2 @@ +[1 of 2] Compiling Top1[unit-top1] +[2 of 2] Compiling Top2[unit-top2] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29bfe38ee9193a29fae79d0006c076d835400e62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29bfe38ee9193a29fae79d0006c076d835400e62 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 10:27:03 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 06:27:03 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617baf71edfd_3276633932e68107219@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 745e9a3e by Teo Camarasu at 2024-04-11T11:25:25+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,99 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance, which does +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- (SG: at least I think that is the case. Can someone verify? Otherwise +-- it would be conceivable to build just ghc against in-tree TH and +-- keep the boot libraries built against boot TH.) +-- (TC: this might be unblocked in the future if we have a separate +-- package DB for splices.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-next == 2.22.0.0 + else + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellNext , transformers , unlit , hp2ps @@ -143,6 +143,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +157,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap-th) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745e9a3ed9704e5b44358b6cc1c038d23005238b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745e9a3ed9704e5b44358b6cc1c038d23005238b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 10:41:15 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 06:41:15 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617be4b2d7e5_3276633ba90d41135c3@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: be50b656 by Teo Camarasu at 2024-04-11T11:40:25+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,99 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance, which does +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- (SG: at least I think that is the case. Can someone verify? Otherwise +-- it would be conceivable to build just ghc against in-tree TH and +-- keep the boot libraries built against boot TH.) +-- (TC: this might be unblocked in the future if we have a separate +-- package DB for splices.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-next == 2.22.0.0 + else + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellNext , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap-th) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be50b6569b8a19eaffeb31971d97ea845efc5dd1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be50b6569b8a19eaffeb31971d97ea845efc5dd1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:02:50 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 11 Apr 2024 07:02:50 -0400 Subject: [Git][ghc/ghc][wip/or-pats] Implement Or Patterns (#22596) Message-ID: <6617c35a878ff_3276633ee2bb0116284@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 7a441c15 by David Knothe at 2024-04-11T13:02:45+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Outputable.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Pat.hs - + docs/users_guide/exts/or_patterns.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a441c15ec45b6f0a8b9837e30081b452e28b4f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a441c15ec45b6f0a8b9837e30081b452e28b4f2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:21:55 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 07:21:55 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617c7d363578_32766342628f8127315@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 61be7a75 by Teo Camarasu at 2024-04-11T12:21:27+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,114 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance, which does +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- (SG: at least I think that is the case. Can someone verify? Otherwise +-- it would be conceivable to build just ghc against in-tree TH and +-- keep the boot libraries built against boot TH.) +-- (TC: this might be unblocked in the future if we have a separate +-- package DB for splices.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap-th) + Build-Depends: + template-haskell-next == 2.22.0.0 + else + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell , text + , templateHaskellNext , transformers , unlit , hp2ps @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap-th) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap-th) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap-th + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap-th) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61be7a754398e0bf93bb41674c80b81307a2eba6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61be7a754398e0bf93bb41674c80b81307a2eba6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:33:32 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 07:33:32 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Apply 4 suggestion(s) to 3 file(s) Message-ID: <6617ca8ce97d0_3276634506be014192f@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 182f88fa by Sebastian Graf at 2024-04-11T11:33:28+00:00 Apply 4 suggestion(s) to 3 file(s) - - - - - 3 changed files: - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Settings/Default.hs Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2952,7 +2952,7 @@ tcGetInterp = do -- -- A. The vendoring in (2) means that the fully qualified name of the in-tree TH -- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. --- That is OK, because we need it just for the `Binary` instance, which does +-- That is OK, because we need it just for the `Binary` instance and to convert TH ASTs returned by splices into the Hs AST, both of which do -- not depend on the fully qualified name of the type to serialise! -- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] -- is unaffected, because the desugaring refers to names in stage1 TH, i.e., ===================================== compiler/ghc.cabal.in ===================================== @@ -85,8 +85,7 @@ Flag hadrian-stage0 Flag bootstrap-th Description: Enabled when building the stage1 compiler in order to vendor the in-tree - `template-haskell` library, while allowing dependencies to depend on the - boot `template-haskell` library. + `template-haskell` library as `template-haskell-next`. See Note [Bootstrapping Template Haskell] Default: False Manual: True @@ -135,7 +134,7 @@ Library if flag(bootstrap-th) Build-Depends: - template-haskell-next == 2.22.0.0 + template-haskell-next == * else Build-Depends: template-haskell == 2.22.0.0 ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -108,8 +108,8 @@ stage0Packages = do , parsec , semaphoreCompat , time - , text , templateHaskellNext + , text , transformers , unlit , hp2ps View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/182f88faa8502da3d4805f1a60e918875458ed79 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/182f88faa8502da3d4805f1a60e918875458ed79 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:39:05 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 07:39:05 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] 100 commits: docs: Remove mention of non-existent Ord instance for Complex Message-ID: <6617cbd921192_e495cdc6f4416cb@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 76d45e9a by Teo Camarasu at 2024-04-11T12:38:21+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 22 changed files: - .gitignore - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/182f88faa8502da3d4805f1a60e918875458ed79...76d45e9ae3a0199fa62f92b553dc583615fbcec1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/182f88faa8502da3d4805f1a60e918875458ed79...76d45e9ae3a0199fa62f92b553dc583615fbcec1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:45:27 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 07:45:27 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617cd57ac09e_e495c352f644972f@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: a6430217 by Teo Camarasu at 2024-04-11T12:45:06+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,109 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to convert TH ASTs returned by splices into the Hs AST, both of which do +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,14 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library as `template-haskell-next`. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +123,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +132,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next == * + else + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a6430217afde006df3495e5d2bd391a813decaaf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a6430217afde006df3495e5d2bd391a813decaaf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 11:52:31 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 11 Apr 2024 07:52:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Validate -main-is flag using parseIdentifier Message-ID: <6617ceff2e758_e495c55b888526fd@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - d3e3f041 by Alex Mason at 2024-04-11T07:52:23-04:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - e7f2abae by Ben Gamari at 2024-04-11T07:52:24-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2f122cd5ace356dd6a68bbc74db51ecc7c49459...e7f2abae8e15758629909ad6e8cded4aec4361bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2f122cd5ace356dd6a68bbc74db51ecc7c49459...e7f2abae8e15758629909ad6e8cded4aec4361bc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 12:04:20 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 08:04:20 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617d1c45a4d4_e495c772a5462685@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 51a04c18 by Teo Camarasu at 2024-04-11T13:04:07+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,109 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to convert TH ASTs returned by splices into the Hs AST, both of which do +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,14 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library as `template-haskell-next`. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +123,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +132,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.0.0 + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51a04c188a25245d32b2e018d4769358817f9e92 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51a04c188a25245d32b2e018d4769358817f9e92 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 12:04:59 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 08:04:59 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617d1eb619fe_e495c84c8e4635d8@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 05f917ff by Teo Camarasu at 2024-04-11T13:04:43+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,109 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to convert TH ASTs returned by splices into the Hs AST, both of which do +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,14 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library as `template-haskell-next`. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +123,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +132,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,6 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +159,6 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap-th" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap-th") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap-th" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap-th" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05f917ffa397ebc12ed410a4ef25969971a2a0cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05f917ffa397ebc12ed410a4ef25969971a2a0cc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 12:24:11 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 08:24:11 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6617d66bac3eb_e495cb750ac663a7@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: 6a2ace3d by Teo Camarasu at 2024-04-11T13:22:12+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,109 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to convert TH ASTs returned by splices into the Hs AST, both of which do +-- not depend on the fully qualified name of the type to serialise! +-- Importantly, Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- is unaffected, because the desugaring refers to names in stage1 TH, i.e., +-- the next compiler stage. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a single version +-- of template-haskell. +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,14 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library as `template-haskell-next`. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +123,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +132,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +160,7 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell + , templateHaskellNext , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.0.0 + else + build-depends: + template-haskell == 2.22.0.0 + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) +import Data.Char (ord) +import qualified Data.Fixed as Fixed +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import GHC.CString ( unpackCString# ) +import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import Data.Void ( Void, absurd ) +import Numeric.Natural import Data.Array.Byte (ByteArray(..)) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) -import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) import GHC.ST (ST(..), runST) +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by --- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by +-- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library, while allowing dependencies to depend on the + boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a2ace3de20c2f624c1d44d0eac07e78759be63d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a2ace3de20c2f624c1d44d0eac07e78759be63d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 12:27:30 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 08:27:30 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.10 Message-ID: <6617d73266104_e495cd3f59068889@gitlab.mail> Ben Gamari deleted branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 12:27:33 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 08:27:33 -0400 Subject: [Git][ghc/ghc][ghc-9.10] 8 commits: Bump parsec submodule to 3.1.17.0 Message-ID: <6617d735a6deb_e495cd313dc69098@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 76a0e7f6 by Ben Gamari at 2024-03-29T17:02:25-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 5a85e5b1 by Ben Gamari at 2024-04-04T14:24:55-04:00 Bump Cabal submodule to current state of 3.12 branch - - - - - 0fb5c97d by Ben Gamari at 2024-04-08T13:36:25-04:00 base: Deprecate GHC.Pack See #21461. - - - - - 834fe22d by Apoorv Ingle at 2024-04-09T21:17:38-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. (cherry picked from commit 0c48f2b952ad4ee995e4eafa458b7a8d3c442415) - - - - - 76a0f8f2 by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump process submodule to 1.6.19.0 Addresses Windows command-line injection vulnerability. - - - - - 086698ba by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 21c9c1bc by Ben Gamari at 2024-04-11T00:07:21-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - aa5b34e1 by Ben Gamari at 2024-04-11T00:07:21-04:00 Bump stm submodule Fixing #24643 - - - - - 14 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/HsToCore/Match.hs - compiler/GHC/Tc/Gen/Do.hs - libraries/Cabal - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs - libraries/parsec - libraries/process - libraries/stm - libraries/unix - + testsuite/tests/patsyn/should_run/T24552.hs - + testsuite/tests/patsyn/should_run/T24552.stdout - testsuite/tests/patsyn/should_run/all.T - testsuite/tests/process/process004.stdout Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -29,7 +29,7 @@ import Language.Haskell.Syntax.Basic (Boxity(..)) import {-#SOURCE#-} GHC.HsToCore.Expr (dsExpr) -import GHC.Types.Basic ( Origin(..), requiresPMC, isDoExpansionGenerated ) +import GHC.Types.Basic ( Origin(..), requiresPMC ) import GHC.Types.SourceText ( FractionalLit, @@ -765,20 +765,11 @@ one pattern, and match simply only accepts one pattern. JJQC 30-Nov-1997 -} -matchWrapper ctxt scrs (MG { mg_alts = L _ matches' +matchWrapper ctxt scrs (MG { mg_alts = L _ matches , mg_ext = MatchGroupTc arg_tys rhs_ty origin }) = do { dflags <- getDynFlags ; locn <- getSrcSpanDs - ; let matches - = if any (is_pat_syn_match origin) matches' - then filter (non_gen_wc origin) matches' - -- filter out the wild pattern fail alternatives - -- which have a do expansion origin - -- They generate spurious overlapping warnings - -- Due to pattern synonyms treated as refutable patterns - -- See Part 1's Wrinkle 1 in Note [Expanding HsDo with XXExprGhcRn] in GHC.Tc.Gen.Do - else matches' ; new_vars <- case matches of [] -> newSysLocalsDs arg_tys (m:_) -> @@ -797,6 +788,8 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches' , text "matchPmChecked" <+> ppr (isMatchContextPmChecked dflags origin ctxt)]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt + -- See Note [Expanding HsDo with XXExprGhcRn] Part 1. Wrinkle 1 for + -- pmc for pattern synonyms -- See Note [Long-distance information] in GHC.HsToCore.Pmc then addHsScrutTmCs (concat scrs) new_vars $ @@ -843,16 +836,6 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches' $ NEL.nonEmpty $ replicate (length (grhssGRHSs m)) ldi_nablas - is_pat_syn_match :: Origin -> LMatch GhcTc (LHsExpr GhcTc) -> Bool - is_pat_syn_match origin (L _ (Match _ _ [L _ (VisPat _ l_pat)] _)) | isDoExpansionGenerated origin - = isPatSyn l_pat - is_pat_syn_match _ _ = False - -- generated match pattern that is not a wildcard - non_gen_wc :: Origin -> LMatch GhcTc (LHsExpr GhcTc) -> Bool - non_gen_wc origin (L _ (Match _ _ ([L _ (VisPat _ (L _ (WildPat _)))]) _)) - = not . isDoExpansionGenerated $ origin - non_gen_wc _ _ = True - {- Note [Long-distance information in matchWrapper] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The pattern match checking in matchWrapper is done conditionally, depending ===================================== compiler/GHC/Tc/Gen/Do.hs ===================================== @@ -212,7 +212,7 @@ mk_failable_expr doFlav pat@(L loc _) expr fail_op = mk_fail_block :: HsDoFlavour -> LPat GhcRn -> LHsExpr GhcRn -> FailOperator GhcRn -> TcM (HsExpr GhcRn) mk_fail_block doFlav pat@(L ploc _) e (Just (SyntaxExprRn fail_op)) = do dflags <- getDynFlags - return $ HsLam noAnn LamSingle $ mkMatchGroup (doExpansionOrigin doFlav) -- \ + return $ HsLam noAnn LamCases $ mkMatchGroup (doExpansionOrigin doFlav) -- \ (wrapGenSpan [ genHsCaseAltDoExp doFlav (mkVisPat pat) e -- pat -> expr , fail_alt_case dflags pat fail_op -- _ -> fail "fail pattern" ]) @@ -356,25 +356,42 @@ The `fail`-block wrapping is done by `GHC.Tc.Gen.Do.mk_failable_expr`. of do-notation is that if the pattern match fails, we fail in the monad, *not* just crash at runtime. -* That call of `fail` will (rightly) automatically generate a `MonadFail` constraint. So if the - pattern is irrefuable, we don't want to generate that `fail` alternative, else we'll generate - a `MonadFail` constraint that isn't needed. +* According to the language specification, when the pattern is irrefutable, + we should not add the `fail` alternative. This is important because + the occurrence of `fail` means that the typechecker will generate a `MonadFail` constraint, + and irrefutable patterns shouldn't need a fail alternative. -* _Wrinkle 1_: For pattern synonyms, we always wrap it with a `fail`-block. - When the pattern is irrefutable, we do not add the fail block. - This is important because the occurrence of `fail` means that the typechecker - will generate a `MonadFail` constraint, and the language spec says that - we should not do that for irrefutable patterns. +* _Wrinkel 1_: Note that pattern synonyms count as refutable during type checking, + (see `GHC.Tc.Gen.Pat.isIrrefutableHsPatRnTcM`). They will hence generate a + `MonadFail` constraint and they will always be wrapped in a `fail`able-block. - Note that pattern synonyms count as refutable (see `isIrrefutableHsPat`), and hence will generate - a `MonadFail` constraint, also, we would get a pattern match checker's redundant pattern warnings. - because after desugaring, it is marked as irrefutable! To avoid such - spurious warnings and type checker errors, we filter out those patterns that appear - in a do expansion generated match in `HsToCore.Match.matchWrapper`. (see testcase Typeable1.hs) + Consider a patten synonym declaration (testcase T24552): + + pattern MyJust :: a -> Maybe a + pattern MyJust x <- Just x where MyJust = Just + + and a `do`-block with the following bind and return statement + + do { MyJust x <- [MyNothing, MyJust ()] + ; return x } + + The `do`-expansion will generate the expansion + + (>>=) ([MyNothing, MyJust ()]) + (\case MyJust x -> return x -- (1) + _ -> fail "failable pattern .. " -- (2) + ) + + This code (specifically the `match` spanning lines (1) and (2)) is a compiler generated code; + the associated `Origin` in tagged `Generated` + The alternative statements will thus be ignored by the pattern match check (c.f. `isMatchContextPmChecked`). + This ensures we do not generate spurious redundant-pattern-match warnings due to the line (2) above. + See Note [Generated code and pattern-match checking] + See Note [Long-distance information in matchWrapper] * _Wrinkle 2_: The call to `fail` will give rise to a `MonadFail` constraint. What `CtOrigin` do we - attach to that constraint? It should be a good one, because it'll show up in error - messages when the `MonadFail` constraint can't be solved. Ideally, it should identify the + attach to that constraint? When the `MonadFail` constraint can't be solved, it'll show up in error + messages and it needs to be a good location. Ideally, it should identify the pattern `p`. Hence, we wrap the `fail` alternative expression with a `ExpandedPat` that tags the fail expression with the failable pattern. (See testcase MonadFailErrors.hs) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit fb3f4d47d261f7401e4ea717ffab31af5d5470fb +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/base/changelog.md ===================================== @@ -1,6 +1,7 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 0736c51d0b39a9852cd39259af4cfaf6cafe36a3 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit a53f925e3ee246e2429418b7a088ecaa0976007b +Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit 4e7aa7885b3f9724b19e68d12cbd2774b11b9bd0 +Subproject commit b77afda28b60f526ebb4be436240afd6ca956673 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 ===================================== testsuite/tests/patsyn/should_run/T24552.hs ===================================== @@ -0,0 +1,14 @@ +{-# language PatternSynonyms #-} + +module Main where + +import Prelude +import qualified Prelude as P + +pattern MyNothing :: Maybe a +pattern MyNothing <- Nothing where MyNothing = Nothing + +pattern MyJust :: a -> Maybe a +pattern MyJust x <- Just x where MyJust = Just + +main = print $ do MyJust x <- [MyNothing, MyJust ()] ; return x ===================================== testsuite/tests/patsyn/should_run/T24552.stdout ===================================== @@ -0,0 +1 @@ +[()] ===================================== testsuite/tests/patsyn/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('T11224', normal, compile_and_run, ['-Wincomplete-patterns -Woverlapping-pa test('T13688', req_th, multimod_compile_and_run, ['T13688', '-v0']) test('T14228', normal, compile_and_run, ['']) test('records-poly-update', normal, compile_and_run, ['']) +test('T24552', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/process/process004.stdout ===================================== @@ -1,2 +1,2 @@ -Exc: true: runInteractiveProcess: chdir: invalid argument (Bad file descriptor) +Exc: true: runInteractiveProcess: chdir: does not exist (No such file or directory) Exc: true: runProcess: chdir: does not exist (No such file or directory) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/16e1fca214c4f90d9d881e44cb82bd193231204b...aa5b34e1643df9c44eaebea38cb58dafaf60cb4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/16e1fca214c4f90d9d881e44cb82bd193231204b...aa5b34e1643df9c44eaebea38cb58dafaf60cb4b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:03:26 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 11 Apr 2024 09:03:26 -0400 Subject: [Git][ghc/ghc][wip/andreask/fix_fallthrough] NCG: Fix a bug where we errounously removed a required jump instruction. Message-ID: <6617df9e86219_e495c1257cf885752@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/fix_fallthrough at Glasgow Haskell Compiler / GHC Commits: 3e79f2c3 by Andreas Klebinger at 2024-04-11T15:02:49+02:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 13 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm Changes: ===================================== compiler/GHC/CmmToAsm/AArch64.hs ===================================== @@ -47,6 +47,7 @@ instance Instruction AArch64.Instr where patchRegsOfInstr = AArch64.patchRegsOfInstr isJumpishInstr = AArch64.isJumpishInstr jumpDestsOfInstr = AArch64.jumpDestsOfInstr + canFallthroughTo = AArch64.canFallthroughTo patchJumpInstr = AArch64.patchJumpInstr mkSpillInstr = AArch64.mkSpillInstr mkLoadInstr = AArch64.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -311,6 +311,12 @@ jumpDestsOfInstr (BL t _ _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr _ = [] +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid +canFallthroughTo (J (TBlock target)) bid = bid == target +canFallthroughTo (B (TBlock target)) bid = bid == target +canFallthroughTo _ _ = False + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points. ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -771,10 +771,9 @@ dropJumps :: forall a i. Instruction i => LabelMap a -> [GenBasicBlock i] dropJumps _ [] = [] dropJumps info (BasicBlock lbl ins:todo) | Just ins <- nonEmpty ins --This can happen because of shortcutting - , [dest] <- jumpDestsOfInstr (NE.last ins) , BasicBlock nextLbl _ : _ <- todo - , not (mapMember dest info) - , nextLbl == dest + , canFallthroughTo (NE.last ins) nextLbl + , not (mapMember nextLbl info) = BasicBlock lbl (NE.init ins) : dropJumps info todo | otherwise = BasicBlock lbl ins : dropJumps info todo ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -71,11 +71,17 @@ class Instruction instr where :: instr -> Bool - -- | Give the possible destinations of this jump instruction. + -- | Give the possible *local block* destinations of this jump instruction. -- Must be defined for all jumpish instructions. jumpDestsOfInstr :: instr -> [BlockId] + -- | Check if the instr always transfers control flow + -- to the given block. Used by code layout to eliminate + -- jumps that can be replaced by fall through. + canFallthroughTo + :: instr -> BlockId -> Bool + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join ===================================== compiler/GHC/CmmToAsm/Monad.hs ===================================== @@ -78,8 +78,15 @@ data NcgImpl statics instr jumpDest = NcgImpl { cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl statics instr], generateJumpTableForInstr :: instr -> Maybe (NatCmmDecl statics instr), getJumpDestBlockId :: jumpDest -> Maybe BlockId, + -- | Does this jump always jump to a single destination and is shortcutable? + -- + -- We use this to determine shortcutable instructions - See Note [What is shortcutting] + -- Note that if we return a destination here we *most* support the relevant shortcutting in + -- shortcutStatics for jump tables and shortcutJump for the instructions itself. canShortcut :: instr -> Maybe jumpDest, + -- | Replace references to blockIds with other destinations - used to update jump tables. shortcutStatics :: (BlockId -> Maybe jumpDest) -> statics -> statics, + -- | Change the jump destination(s) of an instruction. shortcutJump :: (BlockId -> Maybe jumpDest) -> instr -> instr, -- | 'Module' is only for printing internal labels. See Note [Internal proc -- labels] in CLabel. @@ -105,6 +112,25 @@ data NcgImpl statics instr jumpDest = NcgImpl { -- when possible. } +{- Note [supporting shortcutting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For the concept of shortcutting see Note [What is shortcutting]. + +In order to support shortcutting across multiple backends uniformly we +use canShortcut, shortcutStatics and shortcutJump. + +canShortcut tells us if the backend support shortcutting of a instruction +and if so what destination we should retarget instruction to instead. + +shortcutStatics exists to allow us to update jump destinations in jump tables. + +shortcutJump updates the instructions itself. + +A backend can opt out of those by always returning Nothing for canShortcut +and implementing shortcutStatics/shortcutJump as \_ x -> x + +-} + {- Note [pprNatCmmDeclS and pprNatCmmDeclH] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each NcgImpl provides two implementations of its CmmDecl printer, pprNatCmmDeclS ===================================== compiler/GHC/CmmToAsm/PPC.hs ===================================== @@ -46,6 +46,7 @@ instance Instruction PPC.Instr where patchRegsOfInstr = PPC.patchRegsOfInstr isJumpishInstr = PPC.isJumpishInstr jumpDestsOfInstr = PPC.jumpDestsOfInstr + canFallthroughTo = PPC.canFallthroughTo patchJumpInstr = PPC.patchJumpInstr mkSpillInstr = PPC.mkSpillInstr mkLoadInstr = PPC.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/PPC/Instr.hs ===================================== @@ -22,6 +22,7 @@ module GHC.CmmToAsm.PPC.Instr , patchJumpInstr , patchRegsOfInstr , jumpDestsOfInstr + , canFallthroughTo , takeRegRegMoveInstr , takeDeltaInstr , mkRegRegMoveInstr @@ -509,6 +510,13 @@ isJumpishInstr instr JMP{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo instr bid + = case instr of + BCC _ target _ -> target == bid + BCCFAR _ target _ -> target == bid + _ -> False + -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the ===================================== compiler/GHC/CmmToAsm/Reg/Liveness.hs ===================================== @@ -126,6 +126,11 @@ instance Instruction instr => Instruction (InstrSR instr) where Instr instr -> isJumpishInstr instr _ -> False + canFallthroughTo i bid + = case i of + Instr instr -> canFallthroughTo instr bid + _ -> False + jumpDestsOfInstr i = case i of Instr instr -> jumpDestsOfInstr instr ===================================== compiler/GHC/CmmToAsm/X86.hs ===================================== @@ -51,6 +51,7 @@ instance Instruction X86.Instr where patchRegsOfInstr = X86.patchRegsOfInstr isJumpishInstr = X86.isJumpishInstr jumpDestsOfInstr = X86.jumpDestsOfInstr + canFallthroughTo = X86.canFallthroughTo patchJumpInstr = X86.patchJumpInstr mkSpillInstr = X86.mkSpillInstr mkLoadInstr = X86.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -31,6 +31,7 @@ module GHC.CmmToAsm.X86.Instr , mkSpillInstr , mkRegRegMoveInstr , jumpDestsOfInstr + , canFallthroughTo , patchRegsOfInstr , patchJumpInstr , isMetaInstr @@ -669,6 +670,17 @@ isJumpishInstr instr CALL{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo insn bid + = case insn of + JXX _ target -> bid == target + JMP_TBL _ targets _ _ -> all isTargetBid targets + _ -> False + where + isTargetBid target = case target of + Nothing -> True + Just (DestBlockId target) -> target == bid + _ -> False jumpDestsOfInstr :: Instr ===================================== testsuite/tests/codeGen/should_run/T24507.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} + +module Main where + +import GHC.Exts + +foreign import prim "foo" foo :: Int# -> Int# + +main = do + + let f x = case x of I# x' -> case foo x' of x -> print (I# x) + mapM_ f [1..7] \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/T24507.stdout ===================================== @@ -0,0 +1,7 @@ +1 +2 +2 +2 +2 +2 +2 ===================================== testsuite/tests/codeGen/should_run/T24507_cmm.cmm ===================================== @@ -0,0 +1,35 @@ +#include "Cmm.h" + +bar() { + return (2); +} + +foo(W_ x) { + + switch(x) { + case 1: goto a; + case 2: goto b; + case 3: goto c; + case 4: goto d; + case 5: goto e; + case 6: goto f; + case 7: goto g; + } + return (1); + + a: + return (1); + b: + jump bar(); + c: + jump bar(); + d: + jump bar(); + e: + jump bar(); + f: + jump bar(); + g: + jump bar(); + +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e79f2c3148cb02cbdb5e94acedfc51f1ebe6319 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e79f2c3148cb02cbdb5e94acedfc51f1ebe6319 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:13:20 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 09:13:20 -0400 Subject: [Git][ghc/ghc][wip/T24528] 79 commits: rts: fix clang compilation on aarch64 Message-ID: <6617e1f05332b_e495c1406d4c9082f@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - bae99515 by Ben Gamari at 2024-04-11T09:13:14-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 27 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b38ffc82df8b2b38439699886df7b17ece8eb534...bae9951543fa5a3aa7f338dacb257626e38e6a14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b38ffc82df8b2b38439699886df7b17ece8eb534...bae9951543fa5a3aa7f338dacb257626e38e6a14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:21:25 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 11 Apr 2024 09:21:25 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Apply 3 suggestion(s) to 3 file(s) Message-ID: <6617e3d537a41_e495c16150c010031c@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: f749da0e by Matthew Craven at 2024-04-11T13:21:16+00:00 Apply 3 suggestion(s) to 3 file(s) - - - - - 3 changed files: - compiler/GHC/Tc/Gen/Splice.hs - libraries/ghc-boot/ghc-boot.cabal.in - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2966,8 +2966,14 @@ tcGetInterp = do -- because the boot compiler expects the boot TH AST in splices, but, e.g., -- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. -- However, at the moment, we are not using TH in GHC anyway.) --- * Ultimately, we must link the stage1 compiler against a single version --- of template-haskell. +-- * Ultimately, we must link the stage1 compiler against a +-- single version of template-haskell. +-- (Beyond the fact that doing otherwise would invite even +-- more "which `template-haskell` is this" confusion, it +-- would also result in confusing linker errors: see for +-- example #21981. In principle we could likely lift this +-- restriction with more aggressive name mangling, but the +-- knock-on effects of doing so are unexplored.) -- * If the single version is the in-tree TH, we have to recompile all boot -- libraries (e.g. bytestring, containers) with this new TH version. -- * But the boot libraries must *not* be built against a non-boot TH version. ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -38,8 +38,8 @@ source-repository head Flag bootstrap Description: Enabled when building the stage1 compiler in order to vendor the in-tree - `template-haskell` library, while allowing dependencies to depend on the - boot `template-haskell` library. + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. See Note [Bootstrapping Template Haskell] Default: False Manual: True ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,5 +1,5 @@ --- WARNING: template-haskell at Suffix@.cabal is automatically generated from template-haskell at Suffix@.cabal.in by --- ../../configure. Make sure you are editing template-haskell at Suffix@.cabal.in, not +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from ../template-haskell/template-haskell.cabal.in by +-- ../../configure. Make sure you are editing template-haskell.cabal.in, not -- template-haskell at Suffix@.cabal. name: template-haskell at Suffix@ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f749da0e1be25fa97447d93c61982decf0300932 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f749da0e1be25fa97447d93c61982decf0300932 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:27:35 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 11 Apr 2024 09:27:35 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/check_clang Message-ID: <6617e547de99_e495c17fddd810323@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/check_clang at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/check_clang You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:36:19 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 11 Apr 2024 09:36:19 -0400 Subject: [Git][ghc/ghc][wip/andreask/m_warning] 182 commits: Rephrase error message to say "visible arguments" (#24318) Message-ID: <6617e753d4e2b_e495c19f19f0117175@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/m_warning at Glasgow Haskell Compiler / GHC Commits: 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 9e91744a by Andreas Klebinger at 2024-04-11T15:35:46+02:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a07a89877a23136b0cf2cd791931b9646c6c59a9...9e91744a19dcd699896341baadf98f99b1250839 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a07a89877a23136b0cf2cd791931b9646c6c59a9...9e91744a19dcd699896341baadf98f99b1250839 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:40:32 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 09:40:32 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.10 Message-ID: <6617e850f06c0_e495c1b166dc1243a0@gitlab.mail> Ben Gamari pushed new branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.10 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:40:57 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 11 Apr 2024 09:40:57 -0400 Subject: [Git][ghc/ghc][wip/andreask/expose-overloaded-unfoldings] 261 commits: Add @since annotation to Data.Data.mkConstrTag Message-ID: <6617e8697e229_e495c1b890741245e@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/expose-overloaded-unfoldings at Glasgow Haskell Compiler / GHC Commits: 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - af52c6e1 by Andreas Klebinger at 2024-04-11T15:25:07+02:00 Tidy: Add flag to expose unfoldings if they take dictionary arguments. Add the flag `-fexpose-overloaded-unfoldings` to be able to control this behaviour. For ghc's boot libraries file size grew by less than 1% when it was enabled. However I refrained from enabling it by default for now. I've also added a section on specialization more broadly to the users guide. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: T12425 T13386 hard_hole_fits ------------------------- - - - - - 19 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9405b18b8c58ce1ae96606441bd1681f521741b9...af52c6e1ce063bcd438052964c032ec46a82ca4e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9405b18b8c58ce1ae96606441bd1681f521741b9...af52c6e1ce063bcd438052964c032ec46a82ca4e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 13:50:14 2024 From: gitlab at gitlab.haskell.org (Finley McIlwaine (@FinleyMcIlwaine)) Date: Thu, 11 Apr 2024 09:50:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t24653 Message-ID: <6617ea96e0671_c6e628606061696@gitlab.mail> Finley McIlwaine pushed new branch wip/t24653 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t24653 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 14:31:50 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 10:31:50 -0400 Subject: [Git][ghc/ghc][wip/T20201] 11 commits: Prefer packed representation for CompiledByteCode Message-ID: <6617f45627b7_c6e62567818760ee@gitlab.mail> Ben Gamari pushed to branch wip/T20201 at Glasgow Haskell Compiler / GHC Commits: 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - a11cd804 by Ben Gamari at 2024-04-11T10:31:43-04:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - 3efedac6 by Ben Gamari at 2024-04-11T10:31:43-04:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/ObjLink.hs - libraries/ghci/GHCi/Run.hs - rts/Linker.c - rts/LinkerInternals.h - rts/RtsFlags.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6d181bd90baa751b80ddc77490e1bbb3bf29a82...3efedac6eba6a81f6116e2eea540d34fb17cdf3a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6d181bd90baa751b80ddc77490e1bbb3bf29a82...3efedac6eba6a81f6116e2eea540d34fb17cdf3a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 14:32:00 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 11 Apr 2024 10:32:00 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/nursery-resize-message Message-ID: <6617f460c5736_c6e625c0620764f9@gitlab.mail> Matthew Pickering pushed new branch wip/nursery-resize-message at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/nursery-resize-message You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 14:44:26 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 11 Apr 2024 10:44:26 -0400 Subject: [Git][ghc/ghc][wip/T23109] 2 commits: Get rid of newtype classes in CorePrep not CoreToStg Message-ID: <6617f74a8c135_c6e627a74d482613@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 7526aaac by Simon Peyton Jones at 2024-04-11T15:43:31+01:00 Get rid of newtype classes in CorePrep not CoreToStg - - - - - 00d4ce0a by Simon Peyton Jones at 2024-04-11T15:43:53+01:00 SetLevels Experimental: don't float constants, except to top level - - - - - 4 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -703,7 +703,7 @@ lvlMFE env strict_ctxt ann_expr -- We can save work if we can move a redex outside a value lambda -- But if float_is_new_lam is True, then the redex is wrapped in a -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam + saves_work = escapes_value_lam && not (exprIsHNF expr) && not float_is_new_lam escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) -- See Note [Escaping a value lambda] ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -531,13 +531,7 @@ coreToStgApp f args ticks = do app = case idDetails f of DataConWorkId dc | saturated - , let tc = dataConTyCon dc - -> if isClassTyCon tc && isNewTyCon tc then - case args' of - [StgVarArg id] -> StgApp id [] - [StgLitArg lit] -> StgLit lit - _ -> pprPanic "coreToStgApp" (ppr dc <+> ppr args') - else if isUnboxedSumDataCon dc then + -> if isUnboxedSumDataCon dc then StgConApp dc NoNumber args' (sumPrimReps args) else StgConApp dc NoNumber args' [] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -59,7 +59,7 @@ import GHC.Types.Var import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Id.Make ( realWorldPrimId ) +import GHC.Types.Id.Make ( realWorldPrimId, wrapNewTypeBody ) import GHC.Types.Basic import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName ) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) @@ -1084,6 +1084,10 @@ cpeApp top_env expr | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + cpe_app env (Var v) args + | Just (payload, args') <- isNewTypeClassApp v args + = cpe_app env payload args' + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1172,8 +1176,8 @@ cpeApp top_env expr rebuild_app' :: CorePrepEnv - -> [ArgInfo] -- The arguments (inner to outer) - -> CpeApp + -> [ArgInfo] -- The arguments (inner to outer); substitution not applied + -> CpeApp -- Substitution already applied -> Floats -> [Demand] -> [CoreTickish] @@ -1185,12 +1189,9 @@ cpeApp top_env expr rebuild_app' env (a : as) fun' floats ss rt_ticks req_depth = case a of -- See Note [Ticks and mandatory eta expansion] - _ - | not (null rt_ticks) - , req_depth <= 0 - -> - let tick_fun = foldr mkTick fun' rt_ticks - in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth + _ | not (null rt_ticks), req_depth <= 0 + -> let tick_fun = foldr mkTick fun' rt_ticks + in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth @@ -1204,11 +1205,12 @@ cpeApp top_env expr (_ : ss_rest, True) -> (topDmd, ss_rest) (ss1 : ss_rest, False) -> (ss1, ss_rest) ([], _) -> (topDmd, []) - (fs, arg') <- cpeArg top_env ss1 arg + (fs, arg') <- cpeArg env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth + -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -1226,6 +1228,24 @@ isLazyExpr (Tick _ e) = isLazyExpr e isLazyExpr (Var f `App` _ `App` _) = f `hasKey` lazyIdKey isLazyExpr _ = False +isNewTypeClassApp :: Id -> [ArgInfo] -> Maybe (CoreExpr, [ArgInfo]) +isNewTypeClassApp v args + | Just data_con <- isDataConWorkId_maybe v + , let tycon = dataConTyCon data_con + , isNewTyCon tycon + , let get_payload 0 rev_arg_tys (CpeApp payload : args') + = Just (wrapNewTypeBody tycon (reverse rev_arg_tys) payload, args') + get_payload n rev_arg_tys (CpeApp (Type ty) : args) + = get_payload (n-1) (ty:rev_arg_tys) args + get_payload _ _ _ + = Nothing + = assertPpr (isClassTyCon tycon) (ppr v) $ + -- Newtype data constructors are already inlined + -- /except/ for newtype classes + get_payload (tyConArity tycon) [] args + + | otherwise = Nothing + {- Note [runRW magic] ~~~~~~~~~~~~~~~~~~~~~ Some definitions, for instance @runST@, must have careful control over float out ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -20,7 +20,7 @@ module GHC.Types.Id.Make ( mkFCallId, - unwrapNewTypeBody, wrapFamInstBody, + wrapNewTypeBody, unwrapNewTypeBody, wrapFamInstBody, DataConBoxer(..), vanillaDataConBoxer, mkDataConRep, mkDataConWorkId, DataConBangOpts (..), BangOpts (..), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6696873e91d463ef522019968169a0e195ab0662...00d4ce0ac8bfc70c8b512995cd2caa71a9eb0542 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6696873e91d463ef522019968169a0e195ab0662...00d4ce0ac8bfc70c8b512995cd2caa71a9eb0542 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 15:07:50 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 11 Apr 2024 11:07:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/set-levels-hnfs Message-ID: <6617fcc612174_c6e62cc833c90580@gitlab.mail> Simon Peyton Jones pushed new branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/set-levels-hnfs You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 15:13:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 11 Apr 2024 11:13:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <6617fe30340f6_c6e62e4edf093476@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 30a72192 by Alex Mason at 2024-04-11T11:13:14-04:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 181b6ff6 by Zubin Duggal at 2024-04-11T11:13:16-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 025ead8f by Andreas Klebinger at 2024-04-11T11:13:17-04:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - 582a2592 by Andreas Klebinger at 2024-04-11T11:13:17-04:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 088433a3 by Ben Gamari at 2024-04-11T11:13:18-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - a5abdbb1 by Ben Gamari at 2024-04-11T11:13:18-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - e8644427 by Ben Gamari at 2024-04-11T11:13:19-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - d229a260 by Ben Gamari at 2024-04-11T11:13:19-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 28 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs - libraries/unix - rts/Exception.cmm - rts/Libdw.c - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr - testsuite/tests/numeric/should_run/all.T - + testsuite/tests/numeric/should_run/mul2int.hs - + testsuite/tests/numeric/should_run/mul2int.stdout - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -1556,7 +1556,7 @@ genCCall target dest_regs arg_regs bid = do -- pprTraceM "genCCall target" (ppr target) -- pprTraceM "genCCall formal" (ppr dest_regs) -- pprTraceM "genCCall actual" (ppr arg_regs) - + platform <- getPlatform case target of -- The target :: ForeignTarget call can either -- be a foreign procedure with an address expr @@ -1584,7 +1584,6 @@ genCCall target dest_regs arg_regs bid = do let (_res_hints, arg_hints) = foreignTargetHints target arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints - platform <- getPlatform let packStack = platformOS platform == OSDarwin (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL @@ -1625,6 +1624,139 @@ genCCall target dest_regs arg_regs bid = do | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + PrimTarget (MO_S_Mul2 w) + -- Life is easier when we're working with word sized operands, + -- we can use SMULH to compute the high 64 bits, and dst_needed + -- checks if the high half's bits are all the same as the low half's + -- top bit. + | w == W64 + , [src_a, src_b] <- arg_regs + -- dst_needed = did the result fit into just the low half + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + -- Are all high bits equal to the sign bit of the low word? + -- nd = (hi == ASR(lo,width-1)) ? 1 : 0 + CMP (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL` + CSET (OpReg W64 nd) NE + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- using the normal 64 bit multiply. Calculating the dst_needed value is + -- complicated a little by the need to be careful when truncation happens. + -- Currently this case can't be generated since + -- timesInt2# :: Int# -> Int# -> (# Int#, Int#, Int# #) + -- TODO: Should this be removed or would other primops be useful? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a', _format_x, code_a) <- getSomeReg src_a + (reg_b', _format_y, code_b) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + -- Do everything in a full 64 bit registers + w' = platformWordWidth platform + + (reg_a, code_a') <- signExtendReg w w' reg_a' + (reg_b, code_b') <- signExtendReg w w' reg_b' + + return ( + code_a `appOL` + code_b `appOL` + code_a' `appOL` + code_b' `snocOL` + -- the low 2w' of lo contains the full multiplication; + -- eg: int8 * int8 -> int16 result + -- so lo is in the last w of the register, and hi is in the second w. + SMULL (OpReg w' lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Make sure we hold onto the sign bits for dst_needed + ASR (OpReg w' hi) (OpReg w' lo) (OpImm (ImmInt $ widthInBits w)) `appOL` + -- lo can now be truncated so we can get at it's top bit easily. + truncateReg w' w lo `snocOL` + -- Note the use of CMN (compare negative), not CMP: we want to + -- test if the top half is negative one and the top + -- bit of the bottom half is positive one. eg: + -- hi = 0b1111_1111 (actually 64 bits) + -- lo = 0b1010_1111 (-81, so the result didn't need the top half) + -- lo' = ASR(lo,7) (second reg of SMN) + -- = 0b0000_0001 (theeshift gives us 1 for negative, + -- and 0 for positive) + -- hi == -lo'? + -- 0b1111_1111 == 0b1111_1111 (yes, top half is just overflow) + -- Another way to think of this is if hi + lo' == 0, which is what + -- CMN really is under the hood. + CMN (OpReg w' hi) (OpRegShift w' lo SLSR (widthInBits w - 1)) `snocOL` + -- Set dst_needed to 1 if hi and lo' were (negatively) equal + CSET (OpReg w' nd) EQ `appOL` + -- Finally truncate hi to drop any extraneous sign bits. + truncateReg w' w hi + , Nothing) + -- Can't handle > 64 bit operands + | otherwise -> unsupported (MO_S_Mul2 w) + PrimTarget (MO_U_Mul2 w) + -- The unsigned case is much simpler than the signed, all we need to + -- do is the multiplication straight into the destination registers. + | w == W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + UMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- Need to be careful to truncate the low half, but the upper half should be + -- be ok if the invariant in [Signed arithmetic on AArch64] is maintained. + -- Currently this case can't be produced by the compiler since + -- timesWord2# :: Word# -> Word# -> (# Word#, Word# #) + -- TODO: Remove? Or would the extra primop be useful for avoiding the extra + -- steps needed to do this in userland? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + w' = opRegWidth w + return ( + code_x `appOL` + code_y `snocOL` + -- UMULL: Xd = Wa * Wb with 64 bit result + -- W64 inputs should have been caught by case above + UMULL (OpReg W64 lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Extract and truncate high result + -- hi[w:0] = lo[2w:w] + UBFX (OpReg W64 hi) (OpReg W64 lo) + (OpImm (ImmInt $ widthInBits w)) -- lsb + (OpImm (ImmInt $ widthInBits w)) -- width to extract + `appOL` + truncateReg W64 w lo + , Nothing) + | otherwise -> unsupported (MO_U_Mul2 w) + + -- or a possibly side-effecting machine operation -- mop :: CallishMachOp (see GHC.Cmm.MachOp) PrimTarget mop -> do @@ -1714,7 +1846,6 @@ genCCall target dest_regs arg_regs bid = do -- Arithmatic -- These are not supported on X86, so I doubt they are used much. - MO_S_Mul2 _w -> unsupported mop MO_S_QuotRem _w -> unsupported mop MO_U_QuotRem _w -> unsupported mop MO_U_QuotRem2 _w -> unsupported mop @@ -1723,7 +1854,6 @@ genCCall target dest_regs arg_regs bid = do MO_SubWordC _w -> unsupported mop MO_AddIntC _w -> unsupported mop MO_SubIntC _w -> unsupported mop - MO_U_Mul2 _w -> unsupported mop -- Memory Ordering MO_AcquireFence -> return (unitOL DMBISH, Nothing) ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -79,11 +79,14 @@ regUsageOfInstr platform instr = case instr of -- 1. Arithmetic Instructions ------------------------------------------------ ADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) CMP l r -> usage (regOp l ++ regOp r, []) + CMN l r -> usage (regOp l ++ regOp r, []) MSUB dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) MUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) NEG dst src -> usage (regOp src, regOp dst) SMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) UDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -209,11 +212,14 @@ patchRegsOfInstr instr env = case instr of -- 1. Arithmetic Instructions ---------------------------------------------- ADD o1 o2 o3 -> ADD (patchOp o1) (patchOp o2) (patchOp o3) CMP o1 o2 -> CMP (patchOp o1) (patchOp o2) + CMN o1 o2 -> CMN (patchOp o1) (patchOp o2) MSUB o1 o2 o3 o4 -> MSUB (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) MUL o1 o2 o3 -> MUL (patchOp o1) (patchOp o2) (patchOp o3) NEG o1 o2 -> NEG (patchOp o1) (patchOp o2) SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2) (patchOp o3) SMULL o1 o2 o3 -> SMULL (patchOp o1) (patchOp o2) (patchOp o3) + UMULH o1 o2 o3 -> UMULH (patchOp o1) (patchOp o2) (patchOp o3) + UMULL o1 o2 o3 -> UMULL (patchOp o1) (patchOp o2) (patchOp o3) SDIV o1 o2 o3 -> SDIV (patchOp o1) (patchOp o2) (patchOp o3) SUB o1 o2 o3 -> SUB (patchOp o1) (patchOp o2) (patchOp o3) UDIV o1 o2 o3 -> UDIV (patchOp o1) (patchOp o2) (patchOp o3) @@ -540,6 +546,7 @@ data Instr -- | ADR ... -- | ADRP ... | CMP Operand Operand -- rd - op2 + | CMN Operand Operand -- rd + op2 -- | MADD ... -- | MNEG ... | MSUB Operand Operand Operand Operand -- rd = ra - rn × rm @@ -562,8 +569,8 @@ data Instr -- | UMADDL ... -- Xd = Xa + Wn × Wm -- | UMNEGL ... -- Xd = - Wn × Wm -- | UMSUBL ... -- Xd = Xa - Wn × Wm - -- | UMULH ... -- Xd = (Xn × Xm)_127:64 - -- | UMULL ... -- Xd = Wn × Wm + | UMULH Operand Operand Operand -- Xd = (Xn × Xm)_127:64 + | UMULL Operand Operand Operand -- Xd = Wn × Wm -- 2. Bit Manipulation Instructions ---------------------------------------- | SBFM Operand Operand Operand Operand -- rd = rn[i,j] @@ -644,12 +651,15 @@ instrCon i = POP_STACK_FRAME{} -> "POP_STACK_FRAME" ADD{} -> "ADD" CMP{} -> "CMP" + CMN{} -> "CMN" MSUB{} -> "MSUB" MUL{} -> "MUL" NEG{} -> "NEG" SDIV{} -> "SDIV" SMULH{} -> "SMULH" SMULL{} -> "SMULL" + UMULH{} -> "UMULH" + UMULL{} -> "UMULL" SUB{} -> "SUB" UDIV{} -> "UDIV" SBFM{} -> "SBFM" ===================================== compiler/GHC/CmmToAsm/AArch64/Ppr.hs ===================================== @@ -372,12 +372,15 @@ pprInstr platform instr = case instr of CMP o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 | otherwise -> op2 (text "\tcmp") o1 o2 + CMN o1 o2 -> op2 (text "\tcmn") o1 o2 MSUB o1 o2 o3 o4 -> op4 (text "\tmsub") o1 o2 o3 o4 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul") o1 o2 o3 | otherwise -> op3 (text "\tmul") o1 o2 o3 SMULH o1 o2 o3 -> op3 (text "\tsmulh") o1 o2 o3 SMULL o1 o2 o3 -> op3 (text "\tsmull") o1 o2 o3 + UMULH o1 o2 o3 -> op3 (text "\tumulh") o1 o2 o3 + UMULL o1 o2 o3 -> op3 (text "\tumull") o1 o2 o3 NEG o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfneg") o1 o2 | otherwise -> op2 (text "\tneg") o1 o2 ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -76,7 +76,8 @@ initStgToCmmConfig dflags mod = StgToCmmConfig | otherwise -> const True - , stgToCmmAllowIntMul2Instr = (ncg && x86ish) || llvm + , stgToCmmAllowIntMul2Instr = (ncg && (x86ish || aarch64)) || llvm + , stgToCmmAllowWordMul2Instr = (ncg && (x86ish || ppc || aarch64)) || llvm -- SIMD flags , stgToCmmVecInstrsErr = vec_err , stgToCmmAvx = isAvxEnabled dflags @@ -92,6 +93,9 @@ initStgToCmmConfig dflags mod = StgToCmmConfig JSPrimitives -> (False, False) NcgPrimitives -> (True, False) LlvmPrimitives -> (False, True) + aarch64 = case platformArch platform of + ArchAArch64 -> True + _ -> False x86ish = case platformArch platform of ArchX86 -> True ArchX86_64 -> True ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1565,8 +1565,8 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots (root_errs, rootSummariesOk) <- partitionWithM getRootSummary roots -- #17549 let root_map = mkRootMap rootSummariesOk checkDuplicates root_map - (deps, pkg_deps, map0) <- loopSummaries rootSummariesOk (M.empty, Set.empty, root_map) - let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) (hsc_all_home_unit_ids hsc_env) (Set.toList pkg_deps) + (deps, map0) <- loopSummaries rootSummariesOk (M.empty, root_map) + let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) let unit_env = hsc_unit_env hsc_env let tmpfs = hsc_tmpfs hsc_env @@ -1660,19 +1660,19 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This loops over all the mod summaries in the dependency graph, accumulates the actual dependencies for each module/unit loopSummaries :: [ModSummary] - -> (M.Map NodeKey ModuleGraphNode, Set.Set (UnitId, UnitId), + -> (M.Map NodeKey ModuleGraphNode, DownsweepCache) - -> IO ((M.Map NodeKey ModuleGraphNode), Set.Set (UnitId, UnitId), DownsweepCache) + -> IO ((M.Map NodeKey ModuleGraphNode), DownsweepCache) loopSummaries [] done = return done - loopSummaries (ms:next) (done, pkgs, summarised) + loopSummaries (ms:next) (done, summarised) | Just {} <- M.lookup k done - = loopSummaries next (done, pkgs, summarised) + = loopSummaries next (done, summarised) -- Didn't work out what the imports mean yet, now do that. | otherwise = do - (final_deps, pkgs1, done', summarised') <- loopImports (calcDeps ms) done summarised + (final_deps, done', summarised') <- loopImports (calcDeps ms) done summarised -- This has the effect of finding a .hs file if we are looking at the .hs-boot file. - (_, _, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' - loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', pkgs1 `Set.union` pkgs, summarised'') + (_, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' + loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', summarised'') where k = NodeKey_Module (msKey ms) @@ -1692,18 +1692,17 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- Visited set; the range is a list because -- the roots can have the same module names -- if allow_dup_roots is True - -> IO ([NodeKey], Set.Set (UnitId, UnitId), - + -> IO ([NodeKey], M.Map NodeKey ModuleGraphNode, DownsweepCache) -- The result is the completed NodeMap - loopImports [] done summarised = return ([], Set.empty, done, summarised) + loopImports [] done summarised = return ([], done, summarised) loopImports ((home_uid,mb_pkg, gwib) : ss) done summarised | Just summs <- M.lookup cache_key summarised = case summs of [Right ms] -> do let nk = NodeKey_Module (msKey ms) - (rest, pkgs, summarised', done') <- loopImports ss done summarised - return (nk: rest, pkgs, summarised', done') + (rest, summarised', done') <- loopImports ss done summarised + return (nk: rest, summarised', done') [Left _err] -> loopImports ss done summarised _errs -> do @@ -1715,69 +1714,77 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots Nothing excl_mods case mb_s of NotThere -> loopImports ss done summarised - External uid -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (other_deps, Set.insert (homeUnitId home_unit, uid) pkgs, done', summarised') + External _ -> do + (other_deps, done', summarised') <- loopImports ss done summarised + return (other_deps, done', summarised') FoundInstantiation iud -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (NodeKey_Unit iud : other_deps, pkgs, done', summarised') + (other_deps, done', summarised') <- loopImports ss done summarised + return (NodeKey_Unit iud : other_deps, done', summarised') FoundHomeWithError (_uid, e) -> loopImports ss done (Map.insert cache_key [(Left e)] summarised) FoundHome s -> do - (done', pkgs1, summarised') <- - loopSummaries [s] (done, Set.empty, Map.insert cache_key [Right s] summarised) - (other_deps, pkgs2, final_done, final_summarised) <- loopImports ss done' summarised' + (done', summarised') <- + loopSummaries [s] (done, Map.insert cache_key [Right s] summarised) + (other_deps, final_done, final_summarised) <- loopImports ss done' summarised' -- MP: This assumes that we can only instantiate non home units, which is probably fair enough for now. - return (NodeKey_Module (msKey s) : other_deps, pkgs1 `Set.union` pkgs2, final_done, final_summarised) + return (NodeKey_Module (msKey s) : other_deps, final_done, final_summarised) where cache_key = (home_uid, mb_pkg, unLoc <$> gwib) home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod --- This function checks then important property that if both p and q are home units +-- | This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] --- Fast path, trivially closed. -checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] - | otherwise = - let res = foldMap loop home_imp_ids - -- Now check whether everything which transitively depends on a home_unit is actually a home_unit - -- These units are the ones which we need to load as home packages but failed to do for some reason, - -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids - then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] - +-- +-- See Note [Multiple Home Units], section 'Closure Property'. +checkHomeUnitsClosed :: UnitEnv -> [DriverMessages] +checkHomeUnitsClosed ue + | Set.null bad_unit_ids = [] + | otherwise = [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] where + home_id_set = unitEnv_keys $ ue_home_unit_graph ue + bad_unit_ids = upwards_closure Set.\\ home_id_set rootLoc = mkGeneralSrcSpan (fsLit "") - -- TODO: This could repeat quite a bit of work but I struggled to write this function. - -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit - loop (from_uid, uid) = - let us = ue_findHomeUnitEnv from_uid ue in - let um = unitInfoMap (homeUnitEnv_units us) in - case lookupUniqMap um uid of - Nothing -> pprPanic "uid not found" (ppr uid) - Just ui -> - let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set - in - -- Case 1: The unit directly depends on a home_id - if not (null home_depends) - then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res - -- Case 2: Check the rest of the dependencies, and then see if any of them depended on - else - let res = foldMap (loop . (from_uid,)) other_depends - in - if not (Set.null res) - then Set.insert uid res - else res + + graph :: Graph (Node UnitId UnitId) + graph = graphFromEdgedVerticesUniq graphNodes + + -- downwards closure of graph + downwards_closure + = graphFromEdgedVerticesUniq [ DigraphNode uid uid (Set.toList deps) + | (uid, deps) <- M.toList (allReachable graph node_key)] + + inverse_closure = transposeG downwards_closure + + upwards_closure = Set.fromList $ map node_key $ reachablesG inverse_closure [DigraphNode uid uid [] | uid <- Set.toList home_id_set] + + all_unit_direct_deps :: UniqMap UnitId (Set.Set UnitId) + all_unit_direct_deps + = unitEnv_foldWithKey go emptyUniqMap $ ue_home_unit_graph ue + where + go rest this this_uis = + plusUniqMap_C Set.union + (addToUniqMap_C Set.union external_depends this (Set.fromList $ this_deps)) + rest + where + external_depends = mapUniqMap (Set.fromList . unitDepends) (unitInfoMap this_units) + this_units = homeUnitEnv_units this_uis + this_deps = [ toUnitId unit | (unit,Just _) <- explicitUnits this_units] + + graphNodes :: [Node UnitId UnitId] + graphNodes = go Set.empty home_id_set + where + go done todo + = case Set.minView todo of + Nothing -> [] + Just (uid, todo') + | Set.member uid done -> go done todo' + | otherwise -> case lookupUniqMap all_unit_direct_deps uid of + Nothing -> pprPanic "uid not found" (ppr (uid, all_unit_direct_deps)) + Just depends -> + let todo'' = (depends Set.\\ done) `Set.union` todo' + in DigraphNode uid uid (Set.toList depends) : go (Set.insert uid done) todo'' -- | Update the every ModSummary that is depended on -- by a module that needs template haskell. We enable codegen to ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -70,6 +70,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmAllowQuotRem2 :: !Bool -- ^ Allowed to generate QuotRem , stgToCmmAllowExtendedAddSubInstrs :: !Bool -- ^ Allowed to generate AddWordC, SubWordC, Add2, etc. , stgToCmmAllowIntMul2Instr :: !Bool -- ^ Allowed to generate IntMul2 instruction + , stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction , stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks. ------------------------------ SIMD flags ------------------------------------ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1623,7 +1623,7 @@ emitPrimOp cfg primop = else Right genericIntSubCOp WordMul2Op -> \args -> opCallishHandledLater args $ - if allowExtAdd + if allowWord2Mul then Left (MO_U_Mul2 (wordWidth platform)) else Right genericWordMul2Op @@ -1850,6 +1850,7 @@ emitPrimOp cfg primop = allowQuotRem2 = stgToCmmAllowQuotRem2 cfg allowExtAdd = stgToCmmAllowExtendedAddSubInstrs cfg allowInt2Mul = stgToCmmAllowIntMul2Instr cfg + allowWord2Mul = stgToCmmAllowWordMul2Instr cfg allowFMA = stgToCmmAllowFMAInstr cfg ===================================== libraries/base/changelog.md ===================================== @@ -4,6 +4,7 @@ * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x0a0]\n\t" + "str x21, [%0, 0x0a8]\n\t" + "str x22, [%0, 0x0b0]\n\t" + "str x23, [%0, 0x0b8]\n\t" + "str x24, [%0, 0x0c0]\n\t" + "str x25, [%0, 0x0c8]\n\t" + "str x26, [%0, 0x0d0]\n\t" + "str x27, [%0, 0x0d8]\n\t" + "str x28, [%0, 0x0e0]\n\t" + "str x29, [%0, 0x0e8]\n\t" + "str x30, [%0, 0x0f0]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x0f8]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x100]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { ===================================== rts/STM.c ===================================== @@ -31,10 +31,8 @@ * interface. In the Haskell RTS this means it is suitable only for * non-THREADED_RTS builds. * - * STM_CG_LOCK uses coarse-grained locking -- a single 'stm lock' is acquired - * during an invocation on the STM interface. Note that this does not mean that - * transactions are simply serialized -- the lock is only held *within* the - * implementation of stmCommitTransaction, stmWait etc. + * STM_CG_LOCK was a historic locking mode using coarse-grained locking + * It has been removed, look at the git history if you are interest in it. * * STM_FG_LOCKS uses fine-grained locking -- locking is done on a per-TVar basis * and, when committing a transaction, no locks are acquired for TVars that have @@ -42,19 +40,14 @@ * * Concurrency control is implemented in the functions: * - * lock_stm - * unlock_stm * lock_tvar / cond_lock_tvar * unlock_tvar * - * The choice between STM_UNIPROC / STM_CG_LOCK / STM_FG_LOCKS affects the + * The choice between STM_UNIPROC / STM_FG_LOCKS affects the * implementation of these functions. * - * lock_stm & unlock_stm are straightforward : they acquire a simple spin-lock - * using STM_CG_LOCK, and otherwise they are no-ops. - * * lock_tvar / cond_lock_tvar and unlock_tvar are more complex because they have - * other effects (present in STM_UNIPROC and STM_CG_LOCK builds) as well as the + * other effects (present in STM_UNIPROC builds) as well as the * actual business of manipulating a lock (present only in STM_FG_LOCKS builds). * This is because locking a TVar is implemented by writing the lock holder's * TRec into the TVar's current_value field: @@ -167,7 +160,6 @@ static int shake(void) { /*......................................................................*/ #define IF_STM_UNIPROC(__X) do { } while (0) -#define IF_STM_CG_LOCK(__X) do { } while (0) #define IF_STM_FG_LOCKS(__X) do { } while (0) #if defined(STM_UNIPROC) @@ -175,14 +167,6 @@ static int shake(void) { #define IF_STM_UNIPROC(__X) do { __X } while (0) static const StgBool config_use_read_phase = false; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgTRecHeader *trec STG_UNUSED, StgTVar *s STG_UNUSED) { @@ -210,64 +194,9 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgTVar *s STG_UNUSED, StgClosure *expected) { StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); - return (result == expected); -} -#endif - -#if defined(STM_CG_LOCK) /*........................................*/ - -#undef IF_STM_CG_LOCK -#define IF_STM_CG_LOCK(__X) do { __X } while (0) -static const StgBool config_use_read_phase = false; -static volatile StgTRecHeader *smp_locked = NULL; - -static void lock_stm(StgTRecHeader *trec) { - while (cas(&smp_locked, NULL, trec) != NULL) { } - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); - ASSERT(smp_locked == trec); - RELEASE_STORE(&smp_locked, 0); -} - -static StgClosure *lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED) { - StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); - ASSERT(smp_locked == trec); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); result = ACQUIRE_LOAD(&s->current_value); - return result; -} - -static void *unlock_tvar(Capability *cap, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s, - StgClosure *c, - StgBool force_update) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); - ASSERT(smp_locked == trec); - if (force_update) { - StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); - RELEASE_STORE(&s->current_value, c); - dirty_TVAR(cap, s, old_value); - } -} - -static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED, - StgClosure *expected) { - StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - ASSERT(smp_locked == trec); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %d", result ? "success" : "failure"); + // TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); return (result == expected); } #endif @@ -278,19 +207,11 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, #define IF_STM_FG_LOCKS(__X) do { __X } while (0) static const StgBool config_use_read_phase = true; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap, StgTRecHeader *trec, StgTVar *s STG_UNUSED) { StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); + // TRACE("%p : lock_tvar(%p)", trec, s); do { const StgInfoTable *info; do { @@ -313,7 +234,7 @@ static void unlock_tvar(Capability *cap, StgTVar *s, StgClosure *c, StgBool force_update STG_UNUSED) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); + // TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, (StgClosure *) trec); @@ -325,14 +246,14 @@ static StgBool cond_lock_tvar(Capability *cap, StgClosure *expected) { StgClosure *result; StgWord w; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); w = cas((void *)&(s -> current_value), (StgWord)expected, (StgWord)trec); result = (StgClosure *)w; IF_NONMOVING_WRITE_BARRIER_ENABLED { if (result) updateRemembSetPushClosure(cap, expected); } - TRACE("%p : %s", trec, result ? "success" : "failure"); + // TRACE("%p : %s", trec, result ? "success" : "failure"); return (result == expected); } #endif @@ -438,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -760,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -778,6 +739,8 @@ static StgBool validate_and_acquire_ownership (Capability *cap, int acquire_all, int retain_ownership) { StgBool result; + TRACE("cap %d, trec %p : validate_and_acquire_ownership, all: %d, retrain: %d", + cap->no, trec, acquire_all, retain_ownership); if (shake()) { TRACE("%p : shake, pretending trec is invalid when it may not be", trec); @@ -828,6 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -878,12 +842,10 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { /************************************************************************/ void stmPreGCHook (Capability *cap) { - lock_stm(NO_TREC); TRACE("stmPreGCHook"); cap->free_tvar_watch_queues = END_STM_WATCH_QUEUE; cap->free_trec_chunks = END_STM_CHUNK_LIST; cap->free_trec_headers = NO_TREC; - unlock_stm(NO_TREC); } /************************************************************************/ @@ -959,8 +921,6 @@ void stmAbortTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; if (et == NO_TREC) { // We're a top-level transaction: remove any watch queue entries that @@ -984,8 +944,6 @@ void stmAbortTransaction(Capability *cap, } trec -> state = TREC_ABORTED; - unlock_stm(trec); - TRACE("%p : stmAbortTransaction done", trec); } @@ -1013,35 +971,149 @@ void stmCondemnTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); if (trec -> state == TREC_WAITING) { ASSERT(trec -> enclosing_trec == NO_TREC); TRACE("%p : stmCondemnTransaction condemning waiting transaction", trec); remove_watch_queue_entries_for_trec(cap, trec); } trec -> state = TREC_CONDEMNED; - unlock_stm(trec); TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +We validate STM transactions for two purposes: +* Ensure the trec (transaction log) is valid *after* execution. Either during + commit or after an exception has occured. Potentially locking the tvars in + the process. This is done by validate_and_acquire_ownership. +* Terminate transactions early after their trec became invalid. + This is done by validate_trec_optimistic, + +Note that the second point is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +We want to to always get a precise result for both checks. And indeed for the +non-threaded runtime this is reasonably (see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we still use for post-run validation. +While this can lead to validation spuriously failing in edge cases when multiple +threads perform validation in parallel the relevant transactions will simply be +restarted and as long as the false-negative rate is reasonably low this is not +problematic. + +However compared to post-run validation in-flight validation can happen multiple +times per transaction. This means even a fairly low rate of spurious validation +failures will result in a large performance hit. In the worst case preventing +progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve the behaviour of in-flight validations by taking advantage +of the fact that we can allow false positives for these. + +The biggest overhead we can reduce for in-flight validation is locking. We simply +won't take any locks for in-flight validation. If the tvar is already locked we +simply assume the value in our trec is still valid. + +This has the following effects: + +Benefits: +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. I think this +is not an issue. The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. At at least not any more likely than some of the other similarly +unlikely live-lock scenarious for the STM implementation. + +Alternatives: + +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + + +A1: +Take locks for in-flight validation opportunistically to improve things. +While this would solve lock contention/false positives caused +by concurrent in-flight validations. It would still result in in-flight validation +potentially triggering false-negatives during post-run validation by holding a +lock a post-run validation is trying to take. Neither is it guaranteed to +recognize a looping transaction as invalid, so this does not seem like an +improvement to the lock-free inflight validation. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +potentially false-positives by keeping track of how often we couldn't validate +locked tvars. Could be done fine grained on a trec-entry bases or for the trec +overall. + +A3: +When encountering a locked tvar, validate the trec based on the value of the +tvar before it was locked. This could be done by either adding another field +to the tvar, or by looking for the expected value in the trec that holds the +lock of the tvar. But neither option sounds great. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - t = trec; StgBool result = true; while (t != NO_TREC) { - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -1049,12 +1121,9 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { trec -> state = TREC_CONDEMNED; } - unlock_stm(trec); - TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { @@ -1087,8 +1156,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitTransaction()", trec); ASSERT(trec != NO_TREC); - lock_stm(trec); - ASSERT(trec -> enclosing_trec == NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); @@ -1112,6 +1179,7 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { max_concurrent_commits = ((max_commits_at_end - max_commits_at_start) + (getNumCapabilities() * TOKEN_BATCH_SIZE)); if (((max_concurrent_commits >> 32) > 0) || shake()) { + TRACE("STM - Max commit number exceeded"); result = false; } } @@ -1145,8 +1213,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitTransaction()=%d", trec, result); @@ -1162,8 +1228,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitNestedTransaction() into %p", trec, trec -> enclosing_trec); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; bool result = validate_and_acquire_ownership(cap, trec, (!config_use_read_phase), true); if (result) { @@ -1196,8 +1260,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitNestedTransaction()=%d", trec, result); @@ -1214,7 +1276,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); if (result) { // The transaction is valid so far so we can actually start waiting. @@ -1237,7 +1298,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { // TRec. } else { - unlock_stm(trec); free_stg_trec_header(cap, trec); } @@ -1249,7 +1309,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { void stmWaitUnlock(Capability *cap, StgTRecHeader *trec) { revert_ownership(cap, trec, true); - unlock_stm(trec); } /*......................................................................*/ @@ -1263,7 +1322,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { ASSERT((trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); TRACE("%p : validation %s", trec, result ? "succeeded" : "failed"); if (result) { @@ -1280,7 +1338,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { } free_stg_trec_header(cap, trec); } - unlock_stm(trec); TRACE("%p : stmReWait()=%d", trec, result); return result; ===================================== rts/STM.h ===================================== @@ -6,24 +6,21 @@ * *---------------------------------------------------------------------- - STM.h defines the C-level interface to the STM. + STM.h defines the C-level interface to the STM. The design follows that of the PPoPP 2005 paper "Composable memory transactions" extended to include fine-grained locking of TVars. Three different implementations can be built. In overview: - + STM_UNIPROC -- no locking at all: not safe for concurrent invocations - - STM_CG_LOCK -- coarse-grained locking : a single mutex protects all - TVars - + STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at most one TRec at any time. This allows dynamically non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- - extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + extra versioning information is retained in the + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -72,7 +69,7 @@ void stmAbortTransaction(Capability *cap, StgTRecHeader *trec); void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec); /* - * Ensure that a subsequent commit / validation will fail. We use this + * Ensure that a subsequent commit / validation will fail. We use this * in our current handling of transactions that may have become invalid * and started looping. We strip their stack back to the ATOMICALLY_FRAME, * and, when the thread is next scheduled, discover it to be invalid and @@ -87,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -106,14 +110,14 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); These four operations return boolean results which should be interpreted as follows: - true => The transaction record was definitely valid + true => The transaction record was definitely valid false => The transaction record may not have been valid Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be - nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + nested are themselves valid. Callers can check this with + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in @@ -151,7 +155,7 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec); * Test whether the current transaction context is valid and, if so, * start the thread waiting for updates to any of the tvars it has * ready from and mark it as blocked. It is an error to call stmWait - * if the thread is already waiting. + * if the thread is already waiting. */ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec); @@ -180,7 +184,7 @@ StgBool stmReWait(Capability *cap, StgTSO *tso); */ StgClosure *stmReadTVar(Capability *cap, - StgTRecHeader *trec, + StgTRecHeader *trec, StgTVar *tvar); /* Update the logical contents of 'tvar' within the context of the @@ -189,7 +193,7 @@ StgClosure *stmReadTVar(Capability *cap, void stmWriteTVar(Capability *cap, StgTRecHeader *trec, - StgTVar *tvar, + StgTVar *tvar, StgClosure *new_value); /*----------------------------------------------------------------------*/ ===================================== rts/Schedule.c ===================================== @@ -1106,7 +1106,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile ===================================== @@ -0,0 +1,23 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +SETUP=../Setup -v0 + +mhu-perf: clean + $(MAKE) -s --no-print-directory clean + ./genLargeHMU + '$(GHC_PKG)' init tmp.d + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make Setup + for dir in unit-p*; do \ + cd $$dir && $(SETUP) clean && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --ipid=$$dir-0.1.0.0 --with-ghc='$(TEST_HC)' --with-hc-pkg='$(GHC_PKG)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d && $(SETUP) build && $(SETUP) register --inplace && cd ..; \ + done; + + +ifeq "$(CLEANUP)" "1" + $(MAKE) -s --no-print-directory clean +endif + +clean : + $(RM) -r unitTop* unit-p* top*/ tmp*.d inst-* *.o *.hi */*.o */*.hi */Setup$(exeext) */dist Setup$(exeext) + ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs ===================================== @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -0,0 +1,10 @@ +test('mhu-perf', + [ collect_compiler_stats('bytes allocated',2), + extra_files(['genLargeHMU','Setup.hs']), + pre_cmd('$MAKE -s --no-print-directory mhu-perf'), + js_broken(22349), + when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests + compile_timeout_multiplier(5) + ], + multiunit_compile, + [['unitTop1', 'unitTop2'], '-fhide-source-paths']) ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU ===================================== @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of packages with $WIDTH modules on each layer +# Every package on layer N depends on all the packages on layer N-1 +# unitTop imports all the units from the last layer +DEPTH=8 +WIDTH=8 +for i in $(seq -w 1 $WIDTH); do + mkdir unit-p0M$i + echo "module DummyLevel0M$i where" > unit-p0M$i/DummyLevel0M$i.hs; + cat > unit-p0M$i/unit-p0M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel0M$i + build-depends: base +EOF +done +for l in $(seq 1 $DEPTH); do + for i in $(seq -w 1 $WIDTH); do + mkdir unit-p${l}M$i + cat > unit-p${l}M$i/unit-p${l}M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel${l}M$i + build-depends: base +EOF + echo "module DummyLevel${l}M$i where" > unit-p${l}M$i/DummyLevel${l}M$i.hs; + for j in $(seq -w 1 $WIDTH); do + echo " , unit-p$((l-1))M$j" >> unit-p${l}M$i/unit-p${l}M$i.cabal + echo "import DummyLevel$((l-1))M$j" >> unit-p${l}M$i/DummyLevel${l}M$i.hs; + done + done +done +mkdir top1 +echo "module Top1 where" > top1/Top1.hs +echo "-package-db ./tmp.d -i -itop1 Top1 -this-unit-id unit-top1 -package base" > unitTop1; +for j in $(seq -w 1 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop1; + echo "import DummyLevel${DEPTH}M$j" >> top1/Top1.hs; +done +mkdir top2 +echo "module Top2 where" > top2/Top2.hs +echo "-package-db ./tmp.d -i -itop2 Top2 -this-unit-id unit-top2 -package base" > unitTop2; +for j in $(seq -w 2 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop2; + echo "import DummyLevel${DEPTH}M$j" >> top2/Top2.hs; +done ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr ===================================== @@ -0,0 +1,2 @@ +[1 of 2] Compiling Top1[unit-top1] +[2 of 2] Compiling Top2[unit-top2] ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -50,6 +50,7 @@ test('T4383', normal, compile_and_run, ['']) test('add2', normal, compile_and_run, ['-fobject-code']) test('mul2', normal, compile_and_run, ['-fobject-code']) +test('mul2int', normal, compile_and_run, ['-fobject-code']) test('quotRem2', normal, compile_and_run, ['-fobject-code']) test('T5863', normal, compile_and_run, ['']) ===================================== testsuite/tests/numeric/should_run/mul2int.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE MagicHash, UnboxedTuples #-} + +import GHC.Exts +import Data.Bits + +main :: IO () +main = do g 5 6 + g (-5) 6 + g 0x7ECA71DBFF1B7D8C 49 + g (-0x7ECA71DBFF1B7D8C) 49 + g 0x7ECA71DBFF1B7D8C 0x7E0EC51DFD94FE35 + g 0x7ECA71DBFF1B7D8C (-0x7E0EC51DFD94FE35) + + +g :: Int -> Int -> IO () +g wx@(I# x) wy@(I# y) + = do putStrLn "-----" + putStrLn ("Doing " ++ show wx ++ " * " ++ show wy) + case x `timesInt2#` y of + (# n, h, l #) -> + do let wh = I# h + wl = I# l + wlw = W# (int2Word# l) + wn = I# n + r | wn == 1 = shiftL (fromIntegral wh) (finiteBitSize wh) + + fromIntegral wlw + | otherwise = fromIntegral wl + + putStrLn ("High: " ++ show wh) + putStrLn ("Low: " ++ show wl) + putStrLn ("Needed: " ++ show wn) + putStrLn ("Result: " ++ show (r :: Integer)) + putStrLn ("Should be: " ++ show (fromIntegral wx * fromIntegral wy :: Integer)) + + ===================================== testsuite/tests/numeric/should_run/mul2int.stdout ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing 9136239983766240652 * 49 +High: 24 +Low: 4953901435516553164 +Needed: 1 +Result: 447675759204545791948 +Should be: 447675759204545791948 +----- +Doing -9136239983766240652 * 49 +High: -25 +Low: -4953901435516553164 +Needed: 1 +Result: -447675759204545791948 +Should be: -447675759204545791948 +----- +Doing 9136239983766240652 * 9083414231051992629 +High: 4498802171008813567 +Low: 3355592377236579836 +Needed: 1 +Result: 82988252286848496451678442784944154108 +Should be: 82988252286848496451678442784944154108 +----- +Doing 9136239983766240652 * -9083414231051992629 +High: -4498802171008813568 +Low: -3355592377236579836 +Needed: 1 +Result: -82988252286848496451678442784944154108 +Should be: -82988252286848496451678442784944154108 ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,6 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [], compile_and_run, ['-threaded -with-rtsopts "-N2"']) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7f2abae8e15758629909ad6e8cded4aec4361bc...d229a2600ceaa880f691f776d871fe255a34e3b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7f2abae8e15758629909ad6e8cded4aec4361bc...d229a2600ceaa880f691f776d871fe255a34e3b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 15:25:21 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 11 Apr 2024 11:25:21 -0400 Subject: [Git][ghc/ghc][wip/T20749] 19 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <661800e1d6b97_c6e621080344112578@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 36ce14c0 by Sebastian Graf at 2024-04-10T17:45:54+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - e2021976 by Sebastian Graf at 2024-04-11T17:24:47+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68499bef56baf617dd17168c25437d8f692ba5d7...e2021976f4954e133d47209f76a24b5ae0fea20e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68499bef56baf617dd17168c25437d8f692ba5d7...e2021976f4954e133d47209f76a24b5ae0fea20e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 15:49:37 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 11 Apr 2024 11:49:37 -0400 Subject: [Git][ghc/ghc][wip/T20749] Make DataCon workers strict in strict fields (#20749) Message-ID: <661806916b36e_c6e62134f958118837@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: 87b509f2 by Sebastian Graf at 2024-04-11T17:49:08+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 24 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Misc.hs - testsuite/tests/dmdanal/sigs/T16859.stderr - + testsuite/tests/simplCore/should_run/T20749.hs - + testsuite/tests/simplCore/should_run/T20749.stdout - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/simplStg/should_compile/inferTags002.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -640,6 +640,8 @@ pcDataConWithFixity' declared_infix dc_name wrk_key rri -- See Note [Constructor tag allocation] and #14657 data_con = mkDataCon dc_name declared_infix prom_info (map (const no_bang) arg_tys) + (map (const HsLazy) arg_tys) + (map (const NotMarkedStrict) arg_tys) [] -- No labelled fields tyvars ex_tyvars conc_tyvars ===================================== compiler/GHC/Core.hs ===================================== @@ -42,7 +42,7 @@ module GHC.Core ( foldBindersOfBindStrict, foldBindersOfBindsStrict, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, - collectArgs, stripNArgs, collectArgsTicks, flattenBinds, + collectArgs, collectValArgs, stripNArgs, collectArgsTicks, flattenBinds, collectFunSimple, exprToType, @@ -1029,6 +1029,64 @@ tail position: A cast changes the type, but the type must be the same. But operationally, casts are vacuous, so this is a bit unfortunate! See #14610 for ideas how to fix this. +Note [Strict fields in Core] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Evaluating a data constructor worker evaluates its strict fields. + +In other words, if `MkT` is strict in its first field and `xs` reduces to +`error "boom"`, then `MkT xs b` will throw that error. +Consequently, it is sound to seq the field before the call to the constructor, +e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`. +Let's call this transformation "field seq insertion". + +Note in particular that the data constructor application `MkT xs b` above is +*not* a value, unless `xs` is! + +This has pervasive effect on the Core pipeline: + + * `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the + strict arguments of a DataCon worker are values/ok-for-spec themselves. + + * `exprIsConApp_maybe` inserts field seqs in the `FloatBind`s it returns, so + that the Simplifier, Constant-folding, the pattern-match checker, etc. + all see the inserted field seqs when they match on strict workers. Often this + is just to emphasise strict semantics, but for case-of-known constructor + and case-to-let, field insertion is *vital*, otherwise these transformations + would lose field seqs that the user expects to happen, perhaps in order to + fix a space leak. For example, + case MkT xs b of MkT xs' b' -> b' + optimising this expression with case-of-known-con must leave behind the + field seq on `xs`, thus + case xs of xs' { __DEFAULT -> b } + + * The demand signature of a data constructor is strict in strict field + position when otherwise it is lazy. Likewise the demand *transformer* + of a DataCon worker can stricten up demands on strict field args. + See Note [Demand transformer for data constructors]. + + * In the absence of `-fpedantic-bottoms`, it is still possible that some seqs + are ultimately dropped or delayed due to eta-expansion. + See Note [Dealing with bottom]. + +Strict field semantics is exploited in STG by Note [Tag Inference]: +It performs field seq insertion to statically guarantee *taggedness* of strict +fields, establishing the Note [STG Strict Field Invariant]. (Happily, most +of those seqs are immediately detected as redundant by tag inference and are +omitted.) From then on, DataCon worker semantics are actually lazy, hence it is +important that STG passes maintain the Strict Field Invariant. + +Historical Note: +The delightfully simple description of strict field semantics is the result of +a long saga (#20749, the bits about strict data constructors in #21497, #22475), +where we tried a more lenient (but actually not) semantics first that would +allow both strict and lazy implementations of DataCon workers. This was favoured +because the "pervasive effect" throughout the compiler was deemed too large +(when it really turned out to be quite modest). +Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the +same way as above, otherwise the analysis would not be conservative wrt. the +lenient semantics (which includes the strict one). It is also much harder to +explain and maintain, as it turned out. + ************************************************************************ * * In/Out type synonyms @@ -2158,6 +2216,17 @@ collectArgs expr go (App f a) as = go f (a:as) go e as = (e, as) +-- | Takes a nested application expression and returns the function +-- being applied and the arguments to which it is applied +collectValArgs :: Expr b -> (Expr b, [Arg b]) +collectValArgs expr + = go expr [] + where + go (App f a) as + | isValArg a = go f (a:as) + | otherwise = go f as + go e as = (e, as) + -- | Takes a nested application expression and returns the function -- being applied. Looking through casts and ticks to find it. collectFunSimple :: Expr b -> Expr b ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -49,7 +49,8 @@ module GHC.Core.DataCon ( dataConIsInfix, dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitTyThings, - dataConRepStrictness, dataConImplBangs, dataConBoxer, + dataConRepStrictness, dataConRepStrictness_maybe, + dataConImplBangs, dataConBoxer, splitDataProductType_maybe, @@ -60,7 +61,7 @@ module GHC.Core.DataCon ( isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, dataConUserTyVarsNeedWrapper, checkDataConTyVars, - isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, + isBanged, isUnpacked, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, -- ** Promotion related functions @@ -97,6 +98,7 @@ import GHC.Types.Unique.FM ( UniqFM ) import GHC.Types.Unique.Set import GHC.Builtin.Uniques( mkAlphaTyVarUnique ) import GHC.Data.Graph.UnVar -- UnVarSet and operations +import GHC.Data.Maybe (orElse) import {-# SOURCE #-} GHC.Tc.Utils.TcType ( ConcreteTyVars ) @@ -524,6 +526,18 @@ data DataCon -- Matches 1-1 with dcOrigArgTys -- Hence length = dataConSourceArity dataCon + dcImplBangs :: [HsImplBang], + -- The actual decisions made (including failures) + -- about the original arguments; 1-1 with orig_arg_tys + -- See Note [Bangs on data constructor arguments] + + dcStricts :: [StrictnessMark], + -- One mark for every field of the DataCon worker; + -- if it's empty, then all fields are lazy, + -- otherwise it has the same length as dataConRepArgTys. + -- See also Note [Strict fields in Core] in GHC.Core + -- for the effect on the strictness signature + dcFields :: [FieldLabel], -- Field labels for this constructor, in the -- same order as the dcOrigArgTys; @@ -826,13 +840,6 @@ data DataConRep -- after unboxing and flattening, -- and *including* all evidence args - , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] - - , dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures) - -- about the original arguments; 1-1 with orig_arg_tys - -- See Note [Bangs on data constructor arguments] - } type DataConEnv a = UniqFM DataCon a -- Keyed by DataCon @@ -901,43 +908,8 @@ eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Data-con worker strictness] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Notice that we do *not* say the worker Id is strict even if the data -constructor is declared strict - e.g. data T = MkT ![Int] Bool -Even though most often the evals are done by the *wrapper* $WMkT, there are -situations in which tag inference will re-insert evals around the worker. -So for all intents and purposes the *worker* MkT is strict, too! - -Unfortunately, if we exposed accurate strictness of DataCon workers, we'd -see the following transformation: - - f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs - ==> { drop-seq, binder swap on xs' } - f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs - ==> { case-to-let } - f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs! - -I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs` -and then doing case-to-let. The issue is that `exprIsHNF` currently says that -every DataCon worker app is a value. The implicit assumption is that surrounding -evals will have evaluated strict fields like `xs` before! But now that we had -just dropped the eval on `xs`, that assumption is no longer valid. - -Long story short: By keeping the demand signature lazy, the Simplifier will not -drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others -remains sound. - -Similarly, during demand analysis in dmdTransformDataConSig, we bump up the -field demand with `C_01`, *not* `C_11`, because the latter exposes too much -strictness that will drop the eval on `xs` above. - -This issue is discussed at length in -"Failed idea: no wrappers for strict data constructors" in #21497 and #22475. - -Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool @@ -963,8 +935,8 @@ Terminology: the flag settings in the importing module. Also see Note [Bangs on imported data constructors] in GHC.Types.Id.Make -* The dcr_bangs field of the dcRep field records the [HsImplBang] - If T was defined in this module, Without -O the dcr_bangs might be +* The dcImplBangs field records the [HsImplBang] + If T was defined in this module, Without -O the dcImplBangs might be [HsStrict _, HsStrict _, HsLazy] With -O it might be [HsStrict _, HsUnpack _, HsLazy] @@ -973,6 +945,19 @@ Terminology: With -XStrictData it might be [HsStrict _, HsUnpack _, HsStrict _] +* Core passes will often need to know whether the DataCon worker or wrapper in + an application is strict in some (lifted) field or not. This is tracked in the + demand signature attached to a DataCon's worker resp. wrapper Id. + + So if you've got a DataCon dc, you can get the demand signature by + `idDmdSig (dataConWorkId dc)` and make out strict args by testing with + `isStrictDmd`. Similarly, `idDmdSig <$> dataConWrapId_maybe dc` gives + you the demand signature of the wrapper, if it exists. + + These demand signatures are set in GHC.Types.Id.Make.mkDataConWorkId, + compute from the single source of truth `dataConRepStrictness`, which is + generated from `dcStricts`. + Note [Detecting useless UNPACK pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to issue a warning when there's an UNPACK pragma in the source code, @@ -1008,7 +993,6 @@ we consult HsImplBang: The boolean flag is used only for this warning. See #11270 for motivation. - ************************************************************************ * * \subsection{Instances} @@ -1110,6 +1094,11 @@ isBanged (HsUnpack {}) = True isBanged (HsStrict {}) = True isBanged HsLazy = False +isUnpacked :: HsImplBang -> Bool +isUnpacked (HsUnpack {}) = True +isUnpacked (HsStrict {}) = False +isUnpacked HsLazy = False + isSrcStrict :: SrcStrictness -> Bool isSrcStrict SrcStrict = True isSrcStrict _ = False @@ -1135,13 +1124,15 @@ cbvFromStrictMark MarkedStrict = MarkedCbv -- | Build a new data constructor mkDataCon :: Name - -> Bool -- ^ Is the constructor declared infix? - -> TyConRepName -- ^ TyConRepName for the promoted TyCon - -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user - -> [FieldLabel] -- ^ Field labels for the constructor, - -- if it is a record, otherwise empty - -> [TyVar] -- ^ Universals. - -> [TyCoVar] -- ^ Existentials. + -> Bool -- ^ Is the constructor declared infix? + -> TyConRepName -- ^ TyConRepName for the promoted TyCon + -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user + -> [HsImplBang] -- ^ Strictness/unpack annotations, as inferred by the compiler + -> [StrictnessMark] -- ^ Strictness marks for the DataCon worker's fields in Core + -> [FieldLabel] -- ^ Field labels for the constructor, + -- if it is a record, otherwise empty + -> [TyVar] -- ^ Universals. + -> [TyCoVar] -- ^ Existentials. -> ConcreteTyVars -- ^ TyVars which must be instantiated with -- concrete types @@ -1163,7 +1154,9 @@ mkDataCon :: Name -- Can get the tag from the TyCon mkDataCon name declared_infix prom_info - arg_stricts -- Must match orig_arg_tys 1-1 + arg_stricts -- Must match orig_arg_tys 1-1 + impl_bangs -- Must match orig_arg_tys 1-1 + str_marks -- Must be empty or match dataConRepArgTys 1-1 fields univ_tvs ex_tvs conc_tvs user_tvbs eq_spec theta @@ -1180,6 +1173,8 @@ mkDataCon name declared_infix prom_info = con where is_vanilla = null ex_tvs && null eq_spec && null theta + str_marks' | not $ any isMarkedStrict str_marks = [] + | otherwise = str_marks con = MkData {dcName = name, dcUnique = nameUnique name, dcVanilla = is_vanilla, dcInfix = declared_infix, @@ -1192,7 +1187,8 @@ mkDataCon name declared_infix prom_info dcStupidTheta = stupid_theta, dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, dcRepTyCon = rep_tycon, - dcSrcBangs = arg_stricts, + dcSrcBangs = arg_stricts, dcImplBangs = impl_bangs, + dcStricts = str_marks', dcFields = fields, dcTag = tag, dcRepType = rep_ty, dcWorkId = work_id, dcRep = rep, @@ -1436,19 +1432,27 @@ isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 dataConRepStrictness :: DataCon -> [StrictnessMark] --- ^ Give the demands on the arguments of a --- Core constructor application (Con dc args) -dataConRepStrictness dc = case dcRep dc of - NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc] - DCR { dcr_stricts = strs } -> strs +-- ^ Give the demands on the runtime arguments of a Core DataCon worker +-- application. +-- The length of the list matches `dataConRepArgTys` (e.g., the number +-- of runtime arguments). +dataConRepStrictness dc + = dataConRepStrictness_maybe dc + `orElse` replicate (dataConRepArity dc) NotMarkedStrict + +dataConRepStrictness_maybe :: DataCon -> Maybe [StrictnessMark] +-- ^ Give the demands on the runtime arguments of a Core DataCon worker +-- application or `Nothing` if all of them are lazy. +-- The length of the list matches `dataConRepArgTys` (e.g., the number +-- of runtime arguments). +dataConRepStrictness_maybe dc + | null (dcStricts dc) = Nothing + | otherwise = Just (dcStricts dc) dataConImplBangs :: DataCon -> [HsImplBang] -- The implementation decisions about the strictness/unpack of each -- source program argument to the data constructor -dataConImplBangs dc - = case dcRep dc of - NoDataConRep -> replicate (dcSourceArity dc) HsLazy - DCR { dcr_bangs = bangs } -> bangs +dataConImplBangs dc = dcImplBangs dc dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -1533,7 +1533,7 @@ myExprIsCheap (AE { am_opts = opts, am_sigs = sigs }) e mb_ty -- See Note [Eta expanding through dictionaries] -- See Note [Eta expanding through CallStacks] - cheap_fun e = exprIsCheapX (myIsCheapApp sigs) e + cheap_fun e = exprIsCheapX (myIsCheapApp sigs) False e -- | A version of 'isCheapApp' that considers results from arity analysis. -- See Note [Arity analysis] for what's in the signature environment and why ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -209,7 +209,7 @@ cprAnal, cprAnal' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' cprAnal env e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ - cprAnal' env e + cprAnal' env e cprAnal' _ (Lit lit) = (topCprType, Lit lit) cprAnal' _ (Type ty) = (topCprType, Type ty) -- Doesn't happen, in fact @@ -296,9 +296,16 @@ data TermFlag -- Better than using a Bool -- See Note [Nested CPR] exprTerminates :: CoreExpr -> TermFlag +-- ^ A /very/ simple termination analysis. exprTerminates e - | exprIsHNF e = Terminates -- A /very/ simple termination analysis. - | otherwise = MightDiverge + | exprIsHNF e = Terminates + | exprOkForSpeculation e = Terminates + | otherwise = MightDiverge + -- Annyingly, we have to check both for HNF and ok-for-spec. + -- * `I# (x# *# 2#)` is ok-for-spec, but not in HNF. Still worth CPR'ing! + -- * `lvl` is an HNF if its unfolding is evaluated + -- (perhaps `lvl = I# 0#` at top-level). But, tiresomely, it is never + -- ok-for-spec due to Note [exprOkForSpeculation and evaluated variables]. cprAnalApp :: AnalEnv -> CoreExpr -> [(CprType, CoreArg)] -> (CprType, CoreExpr) -- Main function that takes care of /nested/ CPR. See Note [Nested CPR] @@ -367,8 +374,8 @@ cprTransformDataConWork env con args , wkr_arity <= mAX_CPR_SIZE -- See Note [Trimming to mAX_CPR_SIZE] , args `lengthIs` wkr_arity , ae_rec_dc env con /= DefinitelyRecursive -- See Note [CPR for recursive data constructors] - -- , pprTrace "cprTransformDataConWork" (ppr con <+> ppr wkr_arity <+> ppr args) True - = CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) + = -- pprTraceWith "cprTransformDataConWork" (\r -> ppr con <+> ppr wkr_arity <+> ppr args <+> ppr r) $ + CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) | otherwise = topCprType where @@ -505,7 +512,8 @@ cprAnalBind env id rhs | isDataStructure id -- Data structure => no code => no need to analyse rhs = (id, rhs, env) | otherwise - = (id `setIdCprSig` sig', rhs', env') + = -- pprTrace "cprAnalBind" (ppr id <+> ppr sig <+> ppr sig') + (id `setIdCprSig` sig', rhs', env') where (rhs_ty, rhs') = cprAnal env rhs -- possibly trim thunk CPR info ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -824,6 +824,10 @@ to the Divergence lattice, but in practice it turned out to be hard to untaint from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. +You might think that we should check for side-effects rather than just for +precise exceptions. Right you are! See Note [Side-effects and strictness] +for why we unfortunately do not. + Note [Demand analysis for recursive data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T11545 features a single-product, recursive data type ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -8,14 +8,13 @@ module GHC.Core.Opt.Simplify.Env ( -- * The simplifier mode - SimplMode(..), updMode, - smPedanticBottoms, smPlatform, + SimplMode(..), updMode, smPlatform, -- * Environments SimplEnv(..), pprSimplEnv, -- Temp not abstract seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle, seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames, - seOptCoercionOpts, sePedanticBottoms, sePhase, sePlatform, sePreInline, + seOptCoercionOpts, sePhase, sePlatform, sePreInline, seRuleOpts, seRules, seUnfoldingOpts, mkSimplEnv, extendIdSubst, extendCvIdSubst, extendTvSubst, extendCvSubst, @@ -235,9 +234,6 @@ seNames env = sm_names (seMode env) seOptCoercionOpts :: SimplEnv -> OptCoercionOpts seOptCoercionOpts env = sm_co_opt_opts (seMode env) -sePedanticBottoms :: SimplEnv -> Bool -sePedanticBottoms env = smPedanticBottoms (seMode env) - sePhase :: SimplEnv -> CompilerPhase sePhase env = sm_phase (seMode env) @@ -292,9 +288,6 @@ instance Outputable SimplMode where where pp_flag f s = ppUnless f (text "no") <+> s -smPedanticBottoms :: SimplMode -> Bool -smPedanticBottoms opts = ao_ped_bot (sm_arity_opts opts) - smPlatform :: SimplMode -> Platform smPlatform opts = roPlatform (sm_rule_opts opts) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Core.Reduction import GHC.Core.Coercion.Opt ( optCoercion ) import GHC.Core.FamInstEnv ( FamInstEnv, topNormaliseType_maybe ) import GHC.Core.DataCon - ( DataCon, dataConWorkId, dataConRepStrictness + ( DataCon, dataConWorkId, dataConRepStrictness, dataConRepStrictness_maybe , dataConRepArgTys, isUnboxedTupleDataCon , StrictnessMark (..) ) import GHC.Core.Opt.Stats ( Tick(..) ) @@ -2205,14 +2205,14 @@ zap the SubstEnv. This is VITAL. Consider We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!! -Note [Fast path for data constructors] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Fast path for lazy data constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For applications of a data constructor worker, the full glory of rebuildCall is a waste of effort; * They never inline, obviously * They have no rewrite rules -* They are not strict (see Note [Data-con worker strictness] - in GHC.Core.DataCon) +* Though they might be strict (see Note [Strict fields in Core] in GHC.Core), + we will exploit that strictness through their demand signature So it's fine to zoom straight to `rebuild` which just rebuilds the call in a very straightforward way. @@ -2236,7 +2236,8 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont - | isDataConWorkId var -- See Note [Fast path for data constructors] + | Just dc <- isDataConWorkId_maybe var -- See Note [Fast path for lazy data constructors] + , Nothing <- dataConRepStrictness_maybe dc = rebuild env (Var var) cont | otherwise = case substId env var of @@ -3421,7 +3422,7 @@ a case pattern. This is *important*. Consider We really must record that b is already evaluated so that we don't go and re-evaluate it when constructing the result. -See Note [Data-con worker strictness] in GHC.Core.DataCon +See Note [Strict fields in Core] in GHC.Core. NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1277,11 +1277,8 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplifier produces rhs[exp/a], changing semantics if exp is not ok-for-spec -- Good: returning (Mk#, [x]) with a float of case exp of x { DEFAULT -> [] } -- simplifier produces case exp of a { DEFAULT -> exp[x/a] } - = let arg' = subst_expr subst arg - bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) - float = FloatCase arg' bndr DEFAULT [] - subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) mco) + , (subst', float, bndr) <- case_bind subst arg arg_type + = go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise = go subst floats fun (CC (subst_expr subst arg : args) mco) @@ -1324,8 +1321,10 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun - = succeedWith in_scope floats $ - pushCoDataCon con args mco + , (in_scope', seq_floats, args') <- mkFieldSeqFloats in_scope con args + -- mkFieldSeqFloats: See Note [Strict fields in Core] + = succeedWith in_scope' (seq_floats ++ floats) $ + pushCoDataCon con args' mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1411,6 +1410,38 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr extend (Left in_scope) v e = Right (extendSubst (mkEmptySubst in_scope) v e) extend (Right s) v e = Right (extendSubst s v e) + case_bind :: Either InScopeSet Subst -> CoreExpr -> Type -> (Either InScopeSet Subst, FloatBind, Id) + case_bind subst expr expr_ty = (subst', float, bndr) + where + bndr = setCaseBndrEvald MarkedStrict $ + uniqAway (subst_in_scope subst) $ + mkWildValBinder ManyTy expr_ty + subst' = subst_extend_in_scope subst bndr + expr' = subst_expr subst expr + float = FloatCase expr' bndr DEFAULT [] + + mkFieldSeqFloats :: InScopeSet -> DataCon -> [CoreExpr] -> (InScopeSet, [FloatBind], [CoreExpr]) + -- See Note [Strict fields in Core] for what a field seq is and why we + -- insert them + mkFieldSeqFloats in_scope dc args + | Nothing <- dataConRepStrictness_maybe dc + = (in_scope, [], args) + | otherwise + = (in_scope', floats', ty_args ++ val_args') + where + (ty_args, val_args) = splitAtList (dataConUnivAndExTyCoVars dc) args + (in_scope', floats', val_args') = foldr do_one (in_scope, [], []) $ zipEqual "mkFieldSeqFloats" str_marks val_args + str_marks = dataConRepStrictness dc + do_one (str, arg) (in_scope,floats,args) + | NotMarkedStrict <- str = no_seq + | exprIsHNF arg = no_seq + | otherwise = (in_scope', float:floats, Var bndr:args) + where + no_seq = (in_scope, floats, arg:args) + (in_scope', float, bndr) = + case case_bind (Left in_scope) arg (exprType arg) of + (Left in_scope', float, bndr) -> (in_scope', float, bndr) + (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right) -- See Note [exprIsConApp_maybe on literal strings] dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -55,7 +55,7 @@ module GHC.Core.Type ( splitForAllForAllTyBinders, splitForAllForAllTyBinder_maybe, splitForAllTyCoVar_maybe, splitForAllTyCoVar, splitForAllTyVar_maybe, splitForAllCoVar_maybe, - splitPiTy_maybe, splitPiTy, splitPiTys, + splitPiTy_maybe, splitPiTy, splitPiTys, collectPiTyBinders, getRuntimeArgTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, @@ -291,6 +291,7 @@ import GHC.Utils.Panic import GHC.Data.FastString import GHC.Data.Maybe ( orElse, isJust, firstJust ) +import GHC.List (build) -- $type_classification -- #type_classification# @@ -2032,6 +2033,18 @@ splitPiTys ty = split ty ty [] split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs split orig_ty _ bs = (reverse bs, orig_ty) +collectPiTyBinders :: Type -> [PiTyBinder] +collectPiTyBinders ty = build $ \c n -> + let + split (ForAllTy b res) = Named b `c` split res + split (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) + = Anon (Scaled w arg) af `c` split res + split ty | Just ty' <- coreView ty = split ty' + split _ = n + in + split ty +{-# INLINE collectPiTyBinders #-} + -- | Extracts a list of run-time arguments from a function type, -- looking through newtypes to the right of arrows. -- ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1493,18 +1493,23 @@ in this (which it previously was): in \w. v True -} --------------------- -exprIsWorkFree :: CoreExpr -> Bool -- See Note [exprIsWorkFree] -exprIsWorkFree e = exprIsCheapX isWorkFreeApp e - -exprIsCheap :: CoreExpr -> Bool -exprIsCheap e = exprIsCheapX isCheapApp e +------------------------------------- +type CheapAppFun = Id -> Arity -> Bool + -- Is an application of this function to n *value* args + -- always cheap, assuming the arguments are cheap? + -- True mainly of data constructors, partial applications; + -- but with minor variations: + -- isWorkFreeApp + -- isCheapApp + -- isExpandableApp -exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool +exprIsCheapX :: CheapAppFun -> Bool -> CoreExpr -> Bool {-# INLINE exprIsCheapX #-} --- allow specialization of exprIsCheap and exprIsWorkFree +-- allow specialization of exprIsCheap, exprIsWorkFree and exprIsExpandable -- instead of having an unknown call to ok_app -exprIsCheapX ok_app e +-- expandable: Only True for exprIsExpandable, where Case and Let are never +-- expandable. +exprIsCheapX ok_app expandable e = ok e where ok e = go 0 e @@ -1515,7 +1520,7 @@ exprIsCheapX ok_app e go _ (Type {}) = True go _ (Coercion {}) = True go n (Cast e _) = go n e - go n (Case scrut _ _ alts) = ok scrut && + go n (Case scrut _ _ alts) = not expandable && ok scrut && and [ go n rhs | Alt _ _ rhs <- alts ] go n (Tick t e) | tickishCounts t = False | otherwise = go n e @@ -1523,90 +1528,26 @@ exprIsCheapX ok_app e | otherwise = go n e go n (App f e) | isRuntimeArg e = go (n+1) f && ok e | otherwise = go n f - go n (Let (NonRec _ r) e) = go n e && ok r - go n (Let (Rec prs) e) = go n e && all (ok . snd) prs + go n (Let (NonRec _ r) e) = not expandable && go n e && ok r + go n (Let (Rec prs) e) = not expandable && go n e && all (ok . snd) prs -- Case: see Note [Case expressions are work-free] -- App, Let: see Note [Arguments and let-bindings exprIsCheapX] +-------------------- +exprIsWorkFree :: CoreExpr -> Bool +-- See Note [exprIsWorkFree] +exprIsWorkFree e = exprIsCheapX isWorkFreeApp False e -{- Note [exprIsExpandable] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -An expression is "expandable" if we are willing to duplicate it, if doing -so might make a RULE or case-of-constructor fire. Consider - let x = (a,b) - y = build g - in ....(case x of (p,q) -> rhs)....(foldr k z y).... - -We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), -but we do want - - * the case-expression to simplify - (via exprIsConApp_maybe, exprIsLiteral_maybe) - - * the foldr/build RULE to fire - (by expanding the unfolding during rule matching) - -So we classify the unfolding of a let-binding as "expandable" (via the -uf_expandable field) if we want to do this kind of on-the-fly -expansion. Specifically: - -* True of constructor applications (K a b) - -* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. - (NB: exprIsCheap might not be true of this) - -* False of case-expressions. If we have - let x = case ... in ...(case x of ...)... - we won't simplify. We have to inline x. See #14688. - -* False of let-expressions (same reason); and in any case we - float lets out of an RHS if doing so will reveal an expandable - application (see SimplEnv.doFloatFromRhs). - -* Take care: exprIsExpandable should /not/ be true of primops. I - found this in test T5623a: - let q = /\a. Ptr a (a +# b) - in case q @ Float of Ptr v -> ...q... - - q's inlining should not be expandable, else exprIsConApp_maybe will - say that (q @ Float) expands to (Ptr a (a +# b)), and that will - duplicate the (a +# b) primop, which we should not do lightly. - (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) --} +-------------------- +exprIsCheap :: CoreExpr -> Bool +-- See Note [exprIsCheap] +exprIsCheap e = exprIsCheapX isCheapApp False e -------------------------------------- +-------------------- exprIsExpandable :: CoreExpr -> Bool -- See Note [exprIsExpandable] -exprIsExpandable e - = ok e - where - ok e = go 0 e - - -- n is the number of value arguments - go n (Var v) = isExpandableApp v n - go _ (Lit {}) = True - go _ (Type {}) = True - go _ (Coercion {}) = True - go n (Cast e _) = go n e - go n (Tick t e) | tickishCounts t = False - | otherwise = go n e - go n (Lam x e) | isRuntimeVar x = n==0 || go (n-1) e - | otherwise = go n e - go n (App f e) | isRuntimeArg e = go (n+1) f && ok e - | otherwise = go n f - go _ (Case {}) = False - go _ (Let {}) = False - - -------------------------------------- -type CheapAppFun = Id -> Arity -> Bool - -- Is an application of this function to n *value* args - -- always cheap, assuming the arguments are cheap? - -- True mainly of data constructors, partial applications; - -- but with minor variations: - -- isWorkFreeApp - -- isCheapApp +exprIsExpandable e = exprIsCheapX isExpandableApp True e isWorkFreeApp :: CheapAppFun isWorkFreeApp fn n_val_args @@ -1626,7 +1567,7 @@ isCheapApp fn n_val_args | isDeadEndId fn = True -- See Note [isCheapApp: bottoming functions] | otherwise = case idDetails fn of - DataConWorkId {} -> True -- Actually handled by isWorkFreeApp + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId op _ -> primOpIsCheap op @@ -1641,6 +1582,7 @@ isExpandableApp fn n_val_args | isWorkFreeApp fn n_val_args = True | otherwise = case idDetails fn of + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId {} -> False @@ -1672,6 +1614,50 @@ isExpandableApp fn n_val_args I'm not sure why we have a special case for bottoming functions in isCheapApp. Maybe we don't need it. +Note [exprIsExpandable] +~~~~~~~~~~~~~~~~~~~~~~~ +An expression is "expandable" if we are willing to duplicate it, if doing +so might make a RULE or case-of-constructor fire. Consider + let x = (a,b) + y = build g + in ....(case x of (p,q) -> rhs)....(foldr k z y).... + +We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), +but we do want + + * the case-expression to simplify + (via exprIsConApp_maybe, exprIsLiteral_maybe) + + * the foldr/build RULE to fire + (by expanding the unfolding during rule matching) + +So we classify the unfolding of a let-binding as "expandable" (via the +uf_expandable field) if we want to do this kind of on-the-fly +expansion. Specifically: + +* True of constructor applications (K a b) + +* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. + (NB: exprIsCheap might not be true of this) + +* False of case-expressions. If we have + let x = case ... in ...(case x of ...)... + we won't simplify. We have to inline x. See #14688. + +* False of let-expressions (same reason); and in any case we + float lets out of an RHS if doing so will reveal an expandable + application (see SimplEnv.doFloatFromRhs). + +* Take care: exprIsExpandable should /not/ be true of primops. I + found this in test T5623a: + let q = /\a. Ptr a (a +# b) + in case q @ Float of Ptr v -> ...q... + + q's inlining should not be expandable, else exprIsConApp_maybe will + say that (q @ Float) expands to (Ptr a (a +# b)), and that will + duplicate the (a +# b) primop, which we should not do lightly. + (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) + Note [isExpandableApp: bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's important that isExpandableApp does not respond True to bottoming @@ -1852,7 +1838,7 @@ expr_ok fun_ok primop_ok other_expr _ -> False ----------------------------- -app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool +app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreArg] -> Bool app_ok fun_ok primop_ok fun args | not (fun_ok fun) = False -- This code path is only taken for Note [Speculative evaluation] @@ -1867,13 +1853,11 @@ app_ok fun_ok primop_ok fun args -- DFuns terminate, unless the dict is implemented -- with a newtype in which case they may not - DataConWorkId {} -> args_ok - -- The strictness of the constructor has already - -- been expressed by its "wrapper", so we don't need - -- to take the arguments into account - -- Well, we thought so. But it's definitely wrong! - -- See #20749 and Note [How untagged pointers can - -- end up in strict fields] in GHC.Stg.InferTags + DataConWorkId dc + | Just str_marks <- dataConRepStrictness_maybe dc + -> fields_ok str_marks + | otherwise + -> args_ok ClassOpId _ is_terminating_result | is_terminating_result -- See Note [exprOkForSpeculation and type classes] @@ -1923,7 +1907,7 @@ app_ok fun_ok primop_ok fun args -- Even if a function call itself is OK, any unlifted -- args are still evaluated eagerly and must be checked - args_ok = and (zipWith arg_ok arg_tys args) + args_ok = all2Prefix arg_ok arg_tys args arg_ok :: PiTyVarBinder -> CoreExpr -> Bool arg_ok (Named _) _ = True -- A type argument arg_ok (Anon ty _) arg -- A term argument @@ -1932,6 +1916,17 @@ app_ok fun_ok primop_ok fun args | otherwise = expr_ok fun_ok primop_ok arg + -- Used for DataCon worker arguments + fields_ok str_marks = all3Prefix field_ok arg_tys str_marks args + field_ok :: PiTyVarBinder -> StrictnessMark -> CoreExpr -> Bool + field_ok (Named _) _ _ = True + field_ok (Anon ty _) str arg + | NotMarkedStrict <- str -- iff it's a lazy field + , definitelyLiftedType (scaledThing ty) -- and its type is lifted + = True -- then the worker app does not eval + | otherwise + = expr_ok fun_ok primop_ok arg + ----------------------------- altsAreExhaustive :: [Alt b] -> Bool -- True <=> the case alternatives are definitely exhaustive @@ -2157,12 +2152,14 @@ exprIsConLike = exprIsHNFlike isConLikeId isConLikeUnfolding -- or PAPs. -- exprIsHNFlike :: HasDebugCallStack => (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool -exprIsHNFlike is_con is_con_unf = is_hnf_like +exprIsHNFlike is_con is_con_unf e + = -- pprTraceWith "hnf" (\r -> ppr r <+> ppr e) $ + is_hnf_like e where is_hnf_like (Var v) -- NB: There are no value args at this point - = id_app_is_value v 0 -- Catches nullary constructors, - -- so that [] and () are values, for example - -- and (e.g.) primops that don't have unfoldings + = id_app_is_value v [] -- Catches nullary constructors, + -- so that [] and () are values, for example + -- and (e.g.) primops that don't have unfoldings || is_con_unf (idUnfolding v) -- Check the thing's unfolding; it might be bound to a value -- or to a guaranteed-evaluated variable (isEvaldUnfolding) @@ -2186,7 +2183,7 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like -- See Note [exprIsHNF Tick] is_hnf_like (Cast e _) = is_hnf_like e is_hnf_like (App e a) - | isValArg a = app_is_value e 1 + | isValArg a = app_is_value e [a] | otherwise = is_hnf_like e is_hnf_like (Let _ e) = is_hnf_like e -- Lazy let(rec)s don't affect us is_hnf_like (Case e b _ as) @@ -2194,26 +2191,54 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like = is_hnf_like rhs is_hnf_like _ = False - -- 'n' is the number of value args to which the expression is applied - -- And n>0: there is at least one value argument - app_is_value :: CoreExpr -> Int -> Bool - app_is_value (Var f) nva = id_app_is_value f nva - app_is_value (Tick _ f) nva = app_is_value f nva - app_is_value (Cast f _) nva = app_is_value f nva - app_is_value (App f a) nva - | isValArg a = - app_is_value f (nva + 1) && - not (needsCaseBinding (exprType a) a) - -- For example f (x /# y) where f has arity two, and the first - -- argument is unboxed. This is not a value! - -- But f 34# is a value. - -- NB: Check app_is_value first, the arity check is cheaper - | otherwise = app_is_value f nva - app_is_value _ _ = False - - id_app_is_value id n_val_args - = is_con id - || idArity id > n_val_args + -- Collect arguments through Casts and Ticks and call id_app_is_value + app_is_value :: CoreExpr -> [CoreArg] -> Bool + app_is_value (Var f) as = id_app_is_value f as + app_is_value (Tick _ f) as = app_is_value f as + app_is_value (Cast f _) as = app_is_value f as + app_is_value (App f a) as | isValArg a = app_is_value f (a:as) + | otherwise = app_is_value f as + app_is_value _ _ = False + + id_app_is_value id val_args + -- First handle saturated applications of DataCons with strict fields + | Just dc <- isDataConWorkId_maybe id -- DataCon + , Just str_marks <- dataConRepStrictness_maybe dc -- with strict fields + , assert (val_args `leLength` str_marks) True + , val_args `equalLength` str_marks -- in a saturated app + = all3Prefix check_field val_arg_tys str_marks val_args + + -- Now all applications except saturated DataCon apps with strict fields + | idArity id > length val_args + -- PAP: Check unlifted val_args + || is_con id && isNothing (isDataConWorkId_maybe id >>= dataConRepStrictness_maybe) + -- Either a lazy DataCon or a CONLIKE. + -- Hence we only need to check unlifted val_args here. + -- NB: We assume that CONLIKEs are lazy, which is their entire + -- point. + = all2Prefix check_arg val_arg_tys val_args + + | otherwise + = False + where + fun_ty = idType id + val_arg_tys = mapMaybe anonPiTyBinderType_maybe (collectPiTyBinders fun_ty) + -- val_arg_tys = map exprType val_args, but much less costly. + -- The obvious definition regresses T16577 by 30% so we don't do it. + + check_arg a_ty a + | mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- Check unliftedness; for example f (x /# 12#) where f has arity two, + -- and the first argument is unboxed. This is not a value! + -- But f 34# is a value, so check args for HNFs. + -- NB: We check arity (and CONLIKEness) first because it's cheaper + -- and we reject quickly on saturated apps. + check_field a_ty str a + | isMarkedStrict str || mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- isMarkedStrict: Respect Note [Strict fields in Core] +{-# INLINE exprIsHNFlike #-} {- Note [exprIsHNF Tick] @@ -2775,7 +2800,7 @@ This means the seqs on x and y both become no-ops and compared to the first vers The downside is that the caller of $wfoo potentially has to evaluate `y` once if we can't prove it isn't already evaluated. But y coming out of a strict field is in WHNF so safe to evaluated. And most of the time it will be properly tagged+evaluated -already at the call site because of the Strict Field Invariant! See Note [Strict Field Invariant] for more in this. +already at the call site because of the Strict Field Invariant! See Note [STG Strict Field Invariant] for more in this. This makes GHC itself around 1% faster despite doing slightly more work! So this is generally quite good. We only apply this when we think there is a benefit in doing so however. There are a number of cases in which ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -65,8 +65,8 @@ With nofib being ~0.3% faster as well. See Note [Tag inference passes] for how we proceed to generate and use this information. -Note [Strict Field Invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [STG Strict Field Invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As part of tag inference we introduce the Strict Field Invariant. Which consists of us saying that: @@ -82,7 +82,7 @@ and will be tagged with `001` or `010` respectively. It will never point to a thunk, nor will it be tagged `000` (meaning "might be a thunk"). NB: Note that the proper tag for some objects is indeed `000`. Currently this is the case for PAPs. -This works analogous to how `WorkerLikeId`s work. See also Note [CBV Function Ids]. +This works analogous to how CBV functions work. See also Note [CBV Function Ids]. Why do we care? Because if we have code like: @@ -104,7 +104,7 @@ where we: * If not we convert `StrictJust x` into `case x of x' -> StrictJust x'` This is usually very beneficial but can cause regressions in rare edge cases where -we fail to proof that x is properly tagged, or where it simply isn't. +we fail to prove that x is properly tagged, or where it simply isn't. See Note [How untagged pointers can end up in strict fields] for how the second case can arise. @@ -125,15 +125,33 @@ Note that there are similar constraints around Note [CBV Function Ids]. Note [How untagged pointers can end up in strict fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Since the resolution of #20749 where Core passes assume that DataCon workers +evaluate their strict fields, it is pretty simple to see how the Simplifier +might exploit that knowledge to drop evals. Example: + + data T a = MkT !a + f :: [Int] -> T [Int] + f xs = xs `seq` MkT xs + +in Core we will have + + f = \xs -> MkT @[Int] xs + +No eval left there. + Consider data Set a = Tip | Bin !a (Set a) (Set a) We make a wrapper for Bin that evaluates its arguments $WBin x a b = case x of xv -> Bin xv a b Here `xv` will always be evaluated and properly tagged, just as the -Strict Field Invariant requires. +Note [STG Strict Field Invariant] requires. + +But alas, the Simplifier can destroy the invariant: see #15696. +Indeed, as Note [Strict fields in Core] explains, Core passes +assume that Data constructor workers evaluate their strict fields, +so the Simplifier will drop seqs freely. -But alas the Simplifier can destroy the invariant: see #15696. We start with thk = f () g x = ...(case thk of xv -> Bin xv Tip Tip)... @@ -154,7 +172,7 @@ Now you can see that the argument of Bin, namely thk, points to the thunk, not to the value as it did before. In short, although it may be rare, the output of optimisation passes -cannot guarantee to obey the Strict Field Invariant. For this reason +cannot guarantee to obey the Note [STG Strict Field Invariant]. For this reason we run tag inference. See Note [Tag inference passes]. Note [Tag inference passes] @@ -164,7 +182,7 @@ Tag inference proceeds in two passes: The result is then attached to /binders/. This is implemented by `inferTagsAnal` in GHC.Stg.InferTags * The second pass walks over the AST checking if the Strict Field Invariant is upheld. - See Note [Strict Field Invariant]. + See Note [STG Strict Field Invariant]. If required this pass modifies the program to uphold this invariant. Tag information is also moved from /binders/ to /occurrences/ during this pass. This is done by `GHC.Stg.InferTags.Rewrite (rewriteTopBinds)`. ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -57,7 +57,7 @@ The work of this pass is simple: * For any strict field we check if the argument is known to be properly tagged. * If it's not known to be properly tagged, we wrap the whole thing in a case, which will force the argument before allocation. -This is described in detail in Note [Strict Field Invariant]. +This is described in detail in Note [STG Strict Field Invariant]. The only slight complication is that we have to make sure not to invalidate free variable analysis in the process. @@ -210,7 +210,7 @@ When compiling bytecode we call myCoreToStg to get STG code first. myCoreToStg in turn calls out to stg2stg which runs the STG to STG passes followed by free variables analysis and the tag inference pass including its rewriting phase at the end. -Running tag inference is important as it upholds Note [Strict Field Invariant]. +Running tag inference is important as it upholds Note [STG Strict Field Invariant]. While code executed by GHCi doesn't take advantage of the SFI it can call into compiled code which does. So it must still make sure that the SFI is upheld. See also #21083 and #22042. ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -884,7 +884,7 @@ mostly relating to under what circumstances it evaluates its argument. Today, that story is simple: A dataToTag primop always evaluates its argument, unless tag inference determines the argument was already evaluated and correctly tagged. Getting here was a long journey, with -many similarities to the story behind Note [Strict Field Invariant] in +many similarities to the story behind Note [STG Strict Field Invariant] in GHC.Stg.InferTags. See also #15696. -} ===================================== compiler/GHC/Tc/TyCl/Build.hs ===================================== @@ -183,14 +183,15 @@ buildDataCon fam_envs dc_bang_opts src_name declared_infix prom_info src_bangs tag = lookupNameEnv_NF tag_map src_name -- See Note [Constructor tag allocation], fixes #14657 data_con = mkDataCon src_name declared_infix prom_info - src_bangs field_lbls + src_bangs impl_bangs str_marks field_lbls univ_tvs ex_tvs noConcreteTyVars user_tvbs eq_spec ctxt arg_tys res_ty NoPromInfo rep_tycon tag stupid_ctxt dc_wrk dc_rep dc_wrk = mkDataConWorkId work_name data_con - dc_rep = initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) + (dc_rep, impl_bangs, str_marks) = + initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) ; traceIf (text "buildDataCon 2" <+> ppr src_name) ; return data_con } ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1391,33 +1391,16 @@ arguments. That is the job of dmdTransformDataConSig. More precisely, * it returns the demands on the arguments; in the above example that is [SL, A] -Nasty wrinkle. Consider this code (#22475 has more realistic examples but -assume this is what the demand analyser sees) - - data T = MkT !Int Bool - get :: T -> Bool - get (MkT _ b) = b - - foo = let v::Int = I# 7 - t::T = MkT v True - in get t - -Now `v` is unused by `get`, /but/ we can't give `v` an Absent demand, -else we'll drop the binding and replace it with an error thunk. -Then the code generator (more specifically GHC.Stg.InferTags.Rewrite) -will add an extra eval of MkT's argument to give - foo = let v::Int = error "absent" - t::T = case v of v' -> MkT v' True - in get t - -Boo! Because of this extra eval (added in STG-land), the truth is that `MkT` -may (or may not) evaluate its arguments (as established in #21497). Hence the -use of `bump` in dmdTransformDataConSig, which adds in a `C_01` eval. The -`C_01` says "may or may not evaluate" which is absolutely faithful to what -InferTags.Rewrite does. - -In particular it is very important /not/ to make that a `C_11` eval, -see Note [Data-con worker strictness]. +When the data constructor worker has strict fields, an additional seq +will be inserted for each field (Note [Strict fields in Core]). +Hence we add an additional `seqDmd` for each strict field to emulate +field seq insertion. + +For example, consider `data SP a b = MkSP !a !b` and expression `MkSP x y`, +with the same sub-demand P(SL,A). +The strict fields bump up the strictness; we'd get [SL,1!A] for the field +demands. Note that the first demand was unaffected by the seq, whereas +the second, previously absent demand became `seqDmd` exactly. -} {- ********************************************************************* @@ -1617,6 +1600,29 @@ a bad fit because expression may not throw a precise exception (increasing precision of the analysis), but that's just a favourable guess. +Note [Side-effects and strictness] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Due to historic reasons and the continued effort not to cause performance +regressions downstream, Strictness Analysis is currently prone to discarding +observable side-effects (other than precise exceptions, see +Note [Precise exceptions and strictness analysis]) in some cases. For example, + f :: MVar () -> Int -> IO Int + f mv x = putMVar mv () >> (x `seq` return x) +The call to `putMVar` is an observable side-effect. Yet, Strictness Analysis +currently concludes that `f` is strict in `x` and uses call-by-value. +That means `f mv (error "boom")` will error out with the imprecise exception +rather performing the side-effect. + +This is a conscious violation of the semantics described in the paper +"a semantics for imprecise exceptions"; so it would be great if we could +identify the offending primops and extend the idea in +Note [Which scrutinees may throw precise exceptions] to general side-effects. + +Unfortunately, the existing has-side-effects classification for primops is +too conservative, listing `writeMutVar#` and even `readMutVar#` as +side-effecting. That is due to #3207. A possible way forward is described in +#17900, but no effort has been so far towards a resolution. + Note [Exceptions and strictness] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to smart about catching exceptions, but we aren't anymore. @@ -2333,7 +2339,8 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd - str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] + str_field_dmd = seqDmd -- See the bit about strict fields + -- in Note [Demand transformer for data constructors] -- | A special 'DmdTransformer' for dictionary selectors that feeds the demand -- on the result into the indicated dictionary component (if saturated). ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -260,7 +260,7 @@ The invariants around the arguments of call by value function like Ids are then: * Any `WorkerLikeId` * Some `JoinId` bindings. -This works analogous to the Strict Field Invariant. See also Note [Strict Field Invariant]. +This works analogous to the Strict Field Invariant. See also Note [STG Strict Field Invariant]. To make this work what we do is: * During W/W and SpecConstr any worker/specialized binding we introduce ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Core.Coercion import GHC.Core.Reduction import GHC.Core.Make import GHC.Core.FVs ( mkRuleInfo ) -import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase, coreAltsType ) +import GHC.Core.Utils ( exprType, mkCast, coreAltsType ) import GHC.Core.Unfold.Make import GHC.Core.SimpleOpt import GHC.Core.TyCon @@ -594,8 +594,12 @@ mkDataConWorkId wkr_name data_con = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty alg_wkr_info where - tycon = dataConTyCon data_con -- The representation TyCon - wkr_ty = dataConRepType data_con + tycon = dataConTyCon data_con -- The representation TyCon + wkr_ty = dataConRepType data_con + univ_tvs = dataConUnivTyVars data_con + ex_tcvs = dataConExTyCoVars data_con + arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys + str_marks = dataConRepStrictness data_con ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo @@ -603,12 +607,19 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setDmdSigInfo` wkr_sig + -- Workers eval their strict fields + -- See Note [Strict fields in Core] `setLFInfo` wkr_lf_info - -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + wkr_sig = mkClosedDmdSig wkr_dmds topDiv + wkr_dmds = map mk_dmd str_marks + mk_dmd MarkedStrict = evalDmd + mk_dmd NotMarkedStrict = topDmd + -- See Note [LFInfo of DataCon workers and wrappers] wkr_lf_info | wkr_arity == 0 = LFCon data_con @@ -616,9 +627,6 @@ mkDataConWorkId wkr_name data_con -- LFInfo stores post-unarisation arity ----------- Workers for newtypes -------------- - univ_tvs = dataConUnivTyVars data_con - ex_tcvs = dataConExTyCoVars data_con - arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma @@ -786,10 +794,10 @@ mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon - -> UniqSM DataConRep + -> UniqSM (DataConRep, [HsImplBang], [StrictnessMark]) mkDataConRep dc_bang_opts fam_envs wrap_name data_con | not wrapper_reqd - = return NoDataConRep + = return (NoDataConRep, arg_ibangs, rep_strs) | otherwise = do { wrap_args <- mapM (newLocal (fsLit "conrep")) wrap_arg_tys @@ -853,11 +861,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con ; return (DCR { dcr_wrap_id = wrap_id , dcr_boxer = mk_boxer boxers - , dcr_arg_tys = rep_tys - , dcr_stricts = rep_strs - -- For newtypes, dcr_bangs is always [HsLazy]. - -- See Note [HsImplBangs for newtypes]. - , dcr_bangs = arg_ibangs }) } + , dcr_arg_tys = rep_tys } + , arg_ibangs, rep_strs) } where (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys, _orig_res_ty) @@ -907,8 +912,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. -- See dataConUserTyVarsNeedWrapper below. - && (any isBanged (ev_ibangs ++ arg_ibangs))) - -- Some forcing/unboxing (includes eq_spec) + && (any isUnpacked (ev_ibangs ++ arg_ibangs))) + -- Some unboxing (includes eq_spec) || isFamInstTyCon tycon -- Cast result || (dataConUserTyVarsNeedWrapper data_con -- If the data type was written with GADT syntax and @@ -1184,7 +1189,7 @@ dataConArgRep arg_ty HsLazy = ([(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) dataConArgRep arg_ty (HsStrict _) - = ([(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) + = ([(arg_ty, MarkedStrict)], (unitUnboxer, unitBoxer)) -- Seqs are inserted in STG dataConArgRep arg_ty (HsUnpack Nothing) = dataConArgUnpack arg_ty @@ -1214,9 +1219,6 @@ wrapCo co rep_ty (unbox_rep, box_rep) -- co :: arg_ty ~ rep_ty ; return (rep_ids, rep_expr `Cast` mkSymCo sco) } ------------------------ -seqUnboxer :: Unboxer -seqUnboxer v = return ([v], mkDefaultCase (Var v) v) - unitUnboxer :: Unboxer unitUnboxer v = return ([v], \e -> e) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Utils.Misc ( dropWhileEndLE, spanEnd, last2, lastMaybe, onJust, - List.foldl1', foldl2, count, countWhile, all2, + List.foldl1', foldl2, count, countWhile, all2, all2Prefix, all3Prefix, lengthExceeds, lengthIs, lengthIsNot, lengthAtLeast, lengthAtMost, lengthLessThan, @@ -652,6 +652,30 @@ all2 _ [] [] = True all2 p (x:xs) (y:ys) = p x y && all2 p xs ys all2 _ _ _ = False +all2Prefix :: (a -> b -> Bool) -> [a] -> [b] -> Bool +-- ^ `all2Prefix p xs ys` is a fused version of `and $ zipWith2 p xs ys`. +-- So if one list is shorter than the other, `p` is assumed to be `True` for the +-- suffix. +all2Prefix p = foldr k z + where + k x go ys' = case ys' of + (y:ys'') -> p x y && go ys'' + _ -> True + z _ = True +{-# INLINE all2Prefix #-} + +all3Prefix :: (a -> b -> c -> Bool) -> [a] -> [b] -> [c] -> Bool +-- ^ `all3Prefix p xs ys zs` is a fused version of `and $ zipWith3 p xs ys zs`. +-- So if one list is shorter than the others, `p` is assumed to be `True` for +-- the suffix. +all3Prefix p = foldr k z + where + k x go ys' zs' = case (ys',zs') of + (y:ys'',z:zs'') -> p x y z && go ys'' zs'' + _ -> False + z _ _ = True +{-# INLINE all3Prefix #-} + -- Count the number of times a predicate is true count :: (a -> Bool) -> [a] -> Int ===================================== testsuite/tests/dmdanal/sigs/T16859.stderr ===================================== @@ -4,7 +4,7 @@ T16859.bar: <1!A> T16859.baz: <1L><1!P(L)><1C(1,L)> T16859.buz: <1!P(L,L)> T16859.foo: <1L> -T16859.mkInternalName: <1!P(L)><1L><1L> +T16859.mkInternalName: <1!P(L)> T16859.n_loc: <1!P(A,A,A,1L)> T16859.n_occ: <1!P(A,1!P(L,L),A,A)> T16859.n_sort: <1!P(1L,A,A,A)> ===================================== testsuite/tests/simplCore/should_run/T20749.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE UnliftedDatatypes #-} +import Data.Kind +import GHC.Exts + +type StrictPair :: Type -> Type -> UnliftedType +data StrictPair a b = SP !a !b + +f :: StrictPair Int Int -> StrictPair Int Int -> Int -> Bool +{-# OPAQUE f #-} +f (SP x _) (SP _ y) z = x < y + z + +g :: Int -> [Int] -> Int +{-# OPAQUE g #-} +g x ys = h ys + where + h [] = 0 + h (y:ys) = case SP x 27 of + u -> if f u u y then x else x + h ys + +main :: IO () +main = print (g undefined []) ===================================== testsuite/tests/simplCore/should_run/T20749.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -107,6 +107,7 @@ test('UnliftedArgRule', normal, compile_and_run, ['']) test('T21229', normal, compile_and_run, ['-O']) test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) +test('T20749', normal, compile_and_run, ['']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) ===================================== testsuite/tests/simplStg/should_compile/inferTags002.stderr ===================================== @@ -1,88 +1,30 @@ -==================== Output Cmm ==================== -[M.$WMkT_entry() { // [R3, R2] - { info_tbls: [(cym, - label: block_cym_info - rep: StackRep [False] - srt: Nothing), - (cyp, - label: M.$WMkT_info - rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } - srt: Nothing), - (cys, - label: block_cys_info - rep: StackRep [False] - srt: Nothing)] - stack_info: arg_space: 8 - } - {offset - cyp: // global - if ((Sp + -16) < SpLim) (likely: False) goto cyv; else goto cyw; - cyv: // global - R1 = M.$WMkT_closure; - call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - cyw: // global - I64[Sp - 16] = cym; - R1 = R2; - P64[Sp - 8] = R3; - Sp = Sp - 16; - if (R1 & 7 != 0) goto cym; else goto cyn; - cyn: // global - call (I64[R1])(R1) returns to cym, args: 8, res: 8, upd: 8; - cym: // global - I64[Sp] = cys; - _sy8::P64 = R1; - R1 = P64[Sp + 8]; - P64[Sp + 8] = _sy8::P64; - call stg_ap_0_fast(R1) returns to cys, args: 8, res: 8, upd: 8; - cys: // global - Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto cyA; else goto cyz; - cyA: // global - HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cys, args: 8, res: 8, upd: 8; - cyz: // global - I64[Hp - 16] = M.MkT_con_info; - P64[Hp - 8] = P64[Sp + 8]; - P64[Hp] = R1; - R1 = Hp - 15; - Sp = Sp + 16; - call (P64[Sp])(R1) args: 8, res: 0, upd: 8; - } - }, - section ""data" . M.$WMkT_closure" { - M.$WMkT_closure: - const M.$WMkT_info; - }] - - - ==================== Output Cmm ==================== [M.f_entry() { // [R2] - { info_tbls: [(cyK, - label: block_cyK_info + { info_tbls: [(cAs, + label: block_info rep: StackRep [] srt: Nothing), - (cyN, + (cAv, label: M.f_info rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} } srt: Nothing)] stack_info: arg_space: 8 } {offset - cyN: // global - if ((Sp + -8) < SpLim) (likely: False) goto cyO; else goto cyP; - cyO: // global + _lbl_: // global + if ((Sp + -8) < SpLim) (likely: False) goto cAw; else goto cAx; + _lbl_: // global R1 = M.f_closure; call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8; - cyP: // global - I64[Sp - 8] = cyK; + _lbl_: // global + I64[Sp - 8] = cAs; R1 = R2; Sp = Sp - 8; - if (R1 & 7 != 0) goto cyK; else goto cyL; - cyL: // global - call (I64[R1])(R1) returns to cyK, args: 8, res: 8, upd: 8; - cyK: // global + if (R1 & 7 != 0) goto cAs; else goto cAt; + _lbl_: // global + call (I64[R1])(R1) returns to cAs, args: 8, res: 8, upd: 8; + _lbl_: // global R1 = P64[R1 + 15]; Sp = Sp + 8; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; @@ -97,47 +39,47 @@ ==================== Output Cmm ==================== [M.MkT_entry() { // [R3, R2] - { info_tbls: [(cz1, - label: block_cz1_info + { info_tbls: [(cAJ, + label: block_info rep: StackRep [False] srt: Nothing), - (cz4, + (cAM, label: M.MkT_info rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } srt: Nothing), - (cz7, - label: block_cz7_info + (cAP, + label: block_info rep: StackRep [False] srt: Nothing)] stack_info: arg_space: 8 } {offset - cz4: // global - if ((Sp + -16) < SpLim) (likely: False) goto cza; else goto czb; - cza: // global + _lbl_: // global + if ((Sp + -16) < SpLim) (likely: False) goto cAS; else goto cAT; + _lbl_: // global R1 = M.MkT_closure; call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - czb: // global - I64[Sp - 16] = cz1; + _lbl_: // global + I64[Sp - 16] = cAJ; R1 = R2; P64[Sp - 8] = R3; Sp = Sp - 16; - if (R1 & 7 != 0) goto cz1; else goto cz2; - cz2: // global - call (I64[R1])(R1) returns to cz1, args: 8, res: 8, upd: 8; - cz1: // global - I64[Sp] = cz7; - _tyf::P64 = R1; + if (R1 & 7 != 0) goto cAJ; else goto cAK; + _lbl_: // global + call (I64[R1])(R1) returns to cAJ, args: 8, res: 8, upd: 8; + _lbl_: // global + I64[Sp] = cAP; + __locVar_::P64 = R1; R1 = P64[Sp + 8]; - P64[Sp + 8] = _tyf::P64; - call stg_ap_0_fast(R1) returns to cz7, args: 8, res: 8, upd: 8; - cz7: // global + P64[Sp + 8] = __locVar_::P64; + call stg_ap_0_fast(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto czf; else goto cze; - czf: // global + if (Hp > HpLim) (likely: False) goto cAX; else goto cAW; + _lbl_: // global HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cz7, args: 8, res: 8, upd: 8; - cze: // global + call stg_gc_unpt_r1(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global I64[Hp - 16] = M.MkT_con_info; P64[Hp - 8] = P64[Sp + 8]; P64[Hp] = R1; @@ -155,14 +97,14 @@ ==================== Output Cmm ==================== [M.MkT_con_entry() { // [] - { info_tbls: [(czl, + { info_tbls: [(cB3, label: M.MkT_con_info rep: HeapRep 2 ptrs { Con {tag: 0 descr:"main:M.MkT"} } srt: Nothing)] stack_info: arg_space: 8 } {offset - czl: // global + _lbl_: // global R1 = R1 + 1; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87b509f2cd35fac07e9013a43747d9b897260e22 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87b509f2cd35fac07e9013a43747d9b897260e22 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 18:07:06 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 14:07:06 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 8 commits: JS: reenable h$appendToHsString optimization (#24495) Message-ID: <661826ca8a087_fe0dde38a28879b2@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 6ce42495 by Sylvain Henry at 2024-04-11T14:06:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). (cherry picked from commit b36ee57bfbecc628b7f0919e1e59b7066495034f) - - - - - cc690f6e by Sylvain Henry at 2024-04-11T14:06:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 (cherry picked from commit 527616e950fd8942c182be903d176f4b9890ee5a) - - - - - 656395ec by Luite Stegeman at 2024-04-11T14:06:46-04:00 Update correct counter in bumpTickyAllocd (cherry picked from commit 0c4a96862081f03e2946a2ed7e80c108f06205a1) - - - - - fb7dfdf0 by Ben Gamari at 2024-04-11T14:06:46-04:00 testsuite: Fix T24598 with unregisterised compiler (cherry picked from commit 9b9e031b67dbc812c156a4773c0c9d293451fefa) - - - - - 0dd8f0bc by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint (cherry picked from commit 1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9) - - - - - 9745a63e by Simon Peyton Jones at 2024-04-11T14:06:46-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 (cherry picked from commit faa30b41a6f941627ddeeba805815b2742d312d1) - - - - - ed927271 by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. (cherry picked from commit 19883a23b8bc704118fa663d8bab00a503b5a527) - - - - - 220cda2c by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. (cherry picked from commit 12b997df559365e6188824fb10f5f61c2e9075e4) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/SourceText.hs - compiler/GHC/Types/SrcLoc.hs - rts/js/string.js - testsuite/tests/ffi/should_run/T24598c_cmm.cmm - + testsuite/tests/javascript/Makefile - + testsuite/tests/javascript/T24495.hs - + testsuite/tests/javascript/T24495.stdout - testsuite/tests/javascript/all.T - testsuite/tests/saks/should_compile/saks018.hs - testsuite/tests/saks/should_compile/saks021.hs - testsuite/tests/saks/should_fail/all.T - + testsuite/tests/saks/should_fail/saks018-fail.hs - + testsuite/tests/saks/should_fail/saks018-fail.stderr - + testsuite/tests/saks/should_fail/saks021-fail.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7717cc9d40b9ef7afc28af795f2e45315c9555c...220cda2c7d3055499b7b40ea4dbf2a0ed7bf18e0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7717cc9d40b9ef7afc28af795f2e45315c9555c...220cda2c7d3055499b7b40ea4dbf2a0ed7bf18e0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 21:13:30 2024 From: gitlab at gitlab.haskell.org (Oleg Grenrus (@phadej)) Date: Thu, 11 Apr 2024 17:13:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fs-modified-utf8 Message-ID: <6618527aad378_9891d9aeca082187@gitlab.mail> Oleg Grenrus pushed new branch wip/fs-modified-utf8 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fs-modified-utf8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 21:19:33 2024 From: gitlab at gitlab.haskell.org (Oleg Grenrus (@phadej)) Date: Thu, 11 Apr 2024 17:19:33 -0400 Subject: [Git][ghc/ghc][wip/fs-modified-utf8] FastString is a __Modified__ UTF-8 Message-ID: <661853e58d3cf_9891dabacc0851b7@gitlab.mail> Oleg Grenrus pushed to branch wip/fs-modified-utf8 at Glasgow Haskell Compiler / GHC Commits: d7c5f733 by Oleg Grenrus at 2024-04-12T00:19:25+03:00 FastString is a __Modified__ UTF-8 - - - - - 3 changed files: - compiler/GHC/Data/FastString.hs - libraries/ghc-boot/GHC/Data/ShortText.hs - libraries/ghc-boot/GHC/Utils/Encoding/UTF8.hs Changes: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -198,8 +198,8 @@ mkFastZStringString str = FastZString (BSC.pack str) -- ----------------------------------------------------------------------------- -{-| A 'FastString' is a UTF-8 encoded string together with a unique ID. All -'FastString's are stored in a global hashtable to support fast O(1) +{-| A 'FastString' is a Modified UTF-8 encoded string together with a unique ID. +All 'FastString's are stored in a global hashtable to support fast O(1) comparison. It is also associated with a lazy reference to the Z-encoding ===================================== libraries/ghc-boot/GHC/Data/ShortText.hs ===================================== @@ -24,6 +24,10 @@ -- Very similar to FastString, but not hash-consed and with some extra instances and -- functions for serialisation and I/O. Should be imported qualified. +-- +-- /Note:/ This string is stored in Modified UTF8 format, +-- thus it's not byte-compatible with @ShortText@ type in @text-short@ +-- package. module GHC.Data.ShortText ( -- * ShortText ===================================== libraries/ghc-boot/GHC/Utils/Encoding/UTF8.hs ===================================== @@ -7,7 +7,7 @@ -- of the package database (needed in both ghc and in ghc-pkg) lives in -- `ghc-boot` and uses ShortText, which in turn depends on this module. --- | Simple, non-streaming UTF-8 codecs. +-- | Simple, non-streaming Modified UTF-8 codecs. -- -- This is one of several UTF-8 implementations provided by GHC; see Note -- [GHC's many UTF-8 implementations] in "GHC.Encoding.UTF8" for an View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7c5f7338e90cbbf02fa2659309e8db4bb57a7f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7c5f7338e90cbbf02fa2659309e8db4bb57a7f9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 22:04:37 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 11 Apr 2024 18:04:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <66185e75b8664_9891d11577181097fa@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 232d6105 by Alex Mason at 2024-04-11T18:03:52-04:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 96c824de by Zubin Duggal at 2024-04-11T18:03:54-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 399be469 by Andreas Klebinger at 2024-04-11T18:03:55-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - f0f69656 by Ben Gamari at 2024-04-11T18:03:55-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - f216ed22 by Ben Gamari at 2024-04-11T18:03:56-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - df69f218 by Ben Gamari at 2024-04-11T18:03:56-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - f67b13f2 by Ben Gamari at 2024-04-11T18:03:57-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 54321ad1 by Ben Gamari at 2024-04-11T18:03:57-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - bd98a630 by Ben Gamari at 2024-04-11T18:03:58-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 29b9d4e0 by Finley McIlwaine at 2024-04-11T18:03:58-04:00 Correct default -funfolding-use-threshold in docs - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - docs/users_guide/using-optimisation.rst - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs - libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs - libraries/ghc-internal/src/GHC/Internal/List.hs - libraries/unix - rts/Libdw.c - rts/RtsFlags.c - + testsuite/tests/bytecode/T24634/Hello.hs - + testsuite/tests/bytecode/T24634/Main.hs - + testsuite/tests/bytecode/T24634/Makefile - + testsuite/tests/bytecode/T24634/all.T - + testsuite/tests/bytecode/T24634/hello.c - + testsuite/tests/bytecode/T24634/hello.h - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr - testsuite/tests/numeric/should_run/all.T - + testsuite/tests/numeric/should_run/mul2int.hs - + testsuite/tests/numeric/should_run/mul2int.stdout Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -1556,7 +1556,7 @@ genCCall target dest_regs arg_regs bid = do -- pprTraceM "genCCall target" (ppr target) -- pprTraceM "genCCall formal" (ppr dest_regs) -- pprTraceM "genCCall actual" (ppr arg_regs) - + platform <- getPlatform case target of -- The target :: ForeignTarget call can either -- be a foreign procedure with an address expr @@ -1584,7 +1584,6 @@ genCCall target dest_regs arg_regs bid = do let (_res_hints, arg_hints) = foreignTargetHints target arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints - platform <- getPlatform let packStack = platformOS platform == OSDarwin (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL @@ -1625,6 +1624,139 @@ genCCall target dest_regs arg_regs bid = do | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + PrimTarget (MO_S_Mul2 w) + -- Life is easier when we're working with word sized operands, + -- we can use SMULH to compute the high 64 bits, and dst_needed + -- checks if the high half's bits are all the same as the low half's + -- top bit. + | w == W64 + , [src_a, src_b] <- arg_regs + -- dst_needed = did the result fit into just the low half + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + -- Are all high bits equal to the sign bit of the low word? + -- nd = (hi == ASR(lo,width-1)) ? 1 : 0 + CMP (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL` + CSET (OpReg W64 nd) NE + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- using the normal 64 bit multiply. Calculating the dst_needed value is + -- complicated a little by the need to be careful when truncation happens. + -- Currently this case can't be generated since + -- timesInt2# :: Int# -> Int# -> (# Int#, Int#, Int# #) + -- TODO: Should this be removed or would other primops be useful? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a', _format_x, code_a) <- getSomeReg src_a + (reg_b', _format_y, code_b) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + -- Do everything in a full 64 bit registers + w' = platformWordWidth platform + + (reg_a, code_a') <- signExtendReg w w' reg_a' + (reg_b, code_b') <- signExtendReg w w' reg_b' + + return ( + code_a `appOL` + code_b `appOL` + code_a' `appOL` + code_b' `snocOL` + -- the low 2w' of lo contains the full multiplication; + -- eg: int8 * int8 -> int16 result + -- so lo is in the last w of the register, and hi is in the second w. + SMULL (OpReg w' lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Make sure we hold onto the sign bits for dst_needed + ASR (OpReg w' hi) (OpReg w' lo) (OpImm (ImmInt $ widthInBits w)) `appOL` + -- lo can now be truncated so we can get at it's top bit easily. + truncateReg w' w lo `snocOL` + -- Note the use of CMN (compare negative), not CMP: we want to + -- test if the top half is negative one and the top + -- bit of the bottom half is positive one. eg: + -- hi = 0b1111_1111 (actually 64 bits) + -- lo = 0b1010_1111 (-81, so the result didn't need the top half) + -- lo' = ASR(lo,7) (second reg of SMN) + -- = 0b0000_0001 (theeshift gives us 1 for negative, + -- and 0 for positive) + -- hi == -lo'? + -- 0b1111_1111 == 0b1111_1111 (yes, top half is just overflow) + -- Another way to think of this is if hi + lo' == 0, which is what + -- CMN really is under the hood. + CMN (OpReg w' hi) (OpRegShift w' lo SLSR (widthInBits w - 1)) `snocOL` + -- Set dst_needed to 1 if hi and lo' were (negatively) equal + CSET (OpReg w' nd) EQ `appOL` + -- Finally truncate hi to drop any extraneous sign bits. + truncateReg w' w hi + , Nothing) + -- Can't handle > 64 bit operands + | otherwise -> unsupported (MO_S_Mul2 w) + PrimTarget (MO_U_Mul2 w) + -- The unsigned case is much simpler than the signed, all we need to + -- do is the multiplication straight into the destination registers. + | w == W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + UMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- Need to be careful to truncate the low half, but the upper half should be + -- be ok if the invariant in [Signed arithmetic on AArch64] is maintained. + -- Currently this case can't be produced by the compiler since + -- timesWord2# :: Word# -> Word# -> (# Word#, Word# #) + -- TODO: Remove? Or would the extra primop be useful for avoiding the extra + -- steps needed to do this in userland? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + w' = opRegWidth w + return ( + code_x `appOL` + code_y `snocOL` + -- UMULL: Xd = Wa * Wb with 64 bit result + -- W64 inputs should have been caught by case above + UMULL (OpReg W64 lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Extract and truncate high result + -- hi[w:0] = lo[2w:w] + UBFX (OpReg W64 hi) (OpReg W64 lo) + (OpImm (ImmInt $ widthInBits w)) -- lsb + (OpImm (ImmInt $ widthInBits w)) -- width to extract + `appOL` + truncateReg W64 w lo + , Nothing) + | otherwise -> unsupported (MO_U_Mul2 w) + + -- or a possibly side-effecting machine operation -- mop :: CallishMachOp (see GHC.Cmm.MachOp) PrimTarget mop -> do @@ -1714,7 +1846,6 @@ genCCall target dest_regs arg_regs bid = do -- Arithmatic -- These are not supported on X86, so I doubt they are used much. - MO_S_Mul2 _w -> unsupported mop MO_S_QuotRem _w -> unsupported mop MO_U_QuotRem _w -> unsupported mop MO_U_QuotRem2 _w -> unsupported mop @@ -1723,7 +1854,6 @@ genCCall target dest_regs arg_regs bid = do MO_SubWordC _w -> unsupported mop MO_AddIntC _w -> unsupported mop MO_SubIntC _w -> unsupported mop - MO_U_Mul2 _w -> unsupported mop -- Memory Ordering MO_AcquireFence -> return (unitOL DMBISH, Nothing) ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -79,11 +79,14 @@ regUsageOfInstr platform instr = case instr of -- 1. Arithmetic Instructions ------------------------------------------------ ADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) CMP l r -> usage (regOp l ++ regOp r, []) + CMN l r -> usage (regOp l ++ regOp r, []) MSUB dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) MUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) NEG dst src -> usage (regOp src, regOp dst) SMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) UDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -209,11 +212,14 @@ patchRegsOfInstr instr env = case instr of -- 1. Arithmetic Instructions ---------------------------------------------- ADD o1 o2 o3 -> ADD (patchOp o1) (patchOp o2) (patchOp o3) CMP o1 o2 -> CMP (patchOp o1) (patchOp o2) + CMN o1 o2 -> CMN (patchOp o1) (patchOp o2) MSUB o1 o2 o3 o4 -> MSUB (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) MUL o1 o2 o3 -> MUL (patchOp o1) (patchOp o2) (patchOp o3) NEG o1 o2 -> NEG (patchOp o1) (patchOp o2) SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2) (patchOp o3) SMULL o1 o2 o3 -> SMULL (patchOp o1) (patchOp o2) (patchOp o3) + UMULH o1 o2 o3 -> UMULH (patchOp o1) (patchOp o2) (patchOp o3) + UMULL o1 o2 o3 -> UMULL (patchOp o1) (patchOp o2) (patchOp o3) SDIV o1 o2 o3 -> SDIV (patchOp o1) (patchOp o2) (patchOp o3) SUB o1 o2 o3 -> SUB (patchOp o1) (patchOp o2) (patchOp o3) UDIV o1 o2 o3 -> UDIV (patchOp o1) (patchOp o2) (patchOp o3) @@ -540,6 +546,7 @@ data Instr -- | ADR ... -- | ADRP ... | CMP Operand Operand -- rd - op2 + | CMN Operand Operand -- rd + op2 -- | MADD ... -- | MNEG ... | MSUB Operand Operand Operand Operand -- rd = ra - rn × rm @@ -562,8 +569,8 @@ data Instr -- | UMADDL ... -- Xd = Xa + Wn × Wm -- | UMNEGL ... -- Xd = - Wn × Wm -- | UMSUBL ... -- Xd = Xa - Wn × Wm - -- | UMULH ... -- Xd = (Xn × Xm)_127:64 - -- | UMULL ... -- Xd = Wn × Wm + | UMULH Operand Operand Operand -- Xd = (Xn × Xm)_127:64 + | UMULL Operand Operand Operand -- Xd = Wn × Wm -- 2. Bit Manipulation Instructions ---------------------------------------- | SBFM Operand Operand Operand Operand -- rd = rn[i,j] @@ -644,12 +651,15 @@ instrCon i = POP_STACK_FRAME{} -> "POP_STACK_FRAME" ADD{} -> "ADD" CMP{} -> "CMP" + CMN{} -> "CMN" MSUB{} -> "MSUB" MUL{} -> "MUL" NEG{} -> "NEG" SDIV{} -> "SDIV" SMULH{} -> "SMULH" SMULL{} -> "SMULL" + UMULH{} -> "UMULH" + UMULL{} -> "UMULL" SUB{} -> "SUB" UDIV{} -> "UDIV" SBFM{} -> "SBFM" ===================================== compiler/GHC/CmmToAsm/AArch64/Ppr.hs ===================================== @@ -372,12 +372,15 @@ pprInstr platform instr = case instr of CMP o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 | otherwise -> op2 (text "\tcmp") o1 o2 + CMN o1 o2 -> op2 (text "\tcmn") o1 o2 MSUB o1 o2 o3 o4 -> op4 (text "\tmsub") o1 o2 o3 o4 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul") o1 o2 o3 | otherwise -> op3 (text "\tmul") o1 o2 o3 SMULH o1 o2 o3 -> op3 (text "\tsmulh") o1 o2 o3 SMULL o1 o2 o3 -> op3 (text "\tsmull") o1 o2 o3 + UMULH o1 o2 o3 -> op3 (text "\tumulh") o1 o2 o3 + UMULL o1 o2 o3 -> op3 (text "\tumull") o1 o2 o3 NEG o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfneg") o1 o2 | otherwise -> op2 (text "\tneg") o1 o2 ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -76,7 +76,8 @@ initStgToCmmConfig dflags mod = StgToCmmConfig | otherwise -> const True - , stgToCmmAllowIntMul2Instr = (ncg && x86ish) || llvm + , stgToCmmAllowIntMul2Instr = (ncg && (x86ish || aarch64)) || llvm + , stgToCmmAllowWordMul2Instr = (ncg && (x86ish || ppc || aarch64)) || llvm -- SIMD flags , stgToCmmVecInstrsErr = vec_err , stgToCmmAvx = isAvxEnabled dflags @@ -92,6 +93,9 @@ initStgToCmmConfig dflags mod = StgToCmmConfig JSPrimitives -> (False, False) NcgPrimitives -> (True, False) LlvmPrimitives -> (False, True) + aarch64 = case platformArch platform of + ArchAArch64 -> True + _ -> False x86ish = case platformArch platform of ArchX86 -> True ArchX86_64 -> True ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1565,8 +1565,8 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots (root_errs, rootSummariesOk) <- partitionWithM getRootSummary roots -- #17549 let root_map = mkRootMap rootSummariesOk checkDuplicates root_map - (deps, pkg_deps, map0) <- loopSummaries rootSummariesOk (M.empty, Set.empty, root_map) - let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) (hsc_all_home_unit_ids hsc_env) (Set.toList pkg_deps) + (deps, map0) <- loopSummaries rootSummariesOk (M.empty, root_map) + let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) let unit_env = hsc_unit_env hsc_env let tmpfs = hsc_tmpfs hsc_env @@ -1660,19 +1660,19 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This loops over all the mod summaries in the dependency graph, accumulates the actual dependencies for each module/unit loopSummaries :: [ModSummary] - -> (M.Map NodeKey ModuleGraphNode, Set.Set (UnitId, UnitId), + -> (M.Map NodeKey ModuleGraphNode, DownsweepCache) - -> IO ((M.Map NodeKey ModuleGraphNode), Set.Set (UnitId, UnitId), DownsweepCache) + -> IO ((M.Map NodeKey ModuleGraphNode), DownsweepCache) loopSummaries [] done = return done - loopSummaries (ms:next) (done, pkgs, summarised) + loopSummaries (ms:next) (done, summarised) | Just {} <- M.lookup k done - = loopSummaries next (done, pkgs, summarised) + = loopSummaries next (done, summarised) -- Didn't work out what the imports mean yet, now do that. | otherwise = do - (final_deps, pkgs1, done', summarised') <- loopImports (calcDeps ms) done summarised + (final_deps, done', summarised') <- loopImports (calcDeps ms) done summarised -- This has the effect of finding a .hs file if we are looking at the .hs-boot file. - (_, _, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' - loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', pkgs1 `Set.union` pkgs, summarised'') + (_, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' + loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', summarised'') where k = NodeKey_Module (msKey ms) @@ -1692,18 +1692,17 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- Visited set; the range is a list because -- the roots can have the same module names -- if allow_dup_roots is True - -> IO ([NodeKey], Set.Set (UnitId, UnitId), - + -> IO ([NodeKey], M.Map NodeKey ModuleGraphNode, DownsweepCache) -- The result is the completed NodeMap - loopImports [] done summarised = return ([], Set.empty, done, summarised) + loopImports [] done summarised = return ([], done, summarised) loopImports ((home_uid,mb_pkg, gwib) : ss) done summarised | Just summs <- M.lookup cache_key summarised = case summs of [Right ms] -> do let nk = NodeKey_Module (msKey ms) - (rest, pkgs, summarised', done') <- loopImports ss done summarised - return (nk: rest, pkgs, summarised', done') + (rest, summarised', done') <- loopImports ss done summarised + return (nk: rest, summarised', done') [Left _err] -> loopImports ss done summarised _errs -> do @@ -1715,69 +1714,77 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots Nothing excl_mods case mb_s of NotThere -> loopImports ss done summarised - External uid -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (other_deps, Set.insert (homeUnitId home_unit, uid) pkgs, done', summarised') + External _ -> do + (other_deps, done', summarised') <- loopImports ss done summarised + return (other_deps, done', summarised') FoundInstantiation iud -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (NodeKey_Unit iud : other_deps, pkgs, done', summarised') + (other_deps, done', summarised') <- loopImports ss done summarised + return (NodeKey_Unit iud : other_deps, done', summarised') FoundHomeWithError (_uid, e) -> loopImports ss done (Map.insert cache_key [(Left e)] summarised) FoundHome s -> do - (done', pkgs1, summarised') <- - loopSummaries [s] (done, Set.empty, Map.insert cache_key [Right s] summarised) - (other_deps, pkgs2, final_done, final_summarised) <- loopImports ss done' summarised' + (done', summarised') <- + loopSummaries [s] (done, Map.insert cache_key [Right s] summarised) + (other_deps, final_done, final_summarised) <- loopImports ss done' summarised' -- MP: This assumes that we can only instantiate non home units, which is probably fair enough for now. - return (NodeKey_Module (msKey s) : other_deps, pkgs1 `Set.union` pkgs2, final_done, final_summarised) + return (NodeKey_Module (msKey s) : other_deps, final_done, final_summarised) where cache_key = (home_uid, mb_pkg, unLoc <$> gwib) home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod --- This function checks then important property that if both p and q are home units +-- | This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] --- Fast path, trivially closed. -checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] - | otherwise = - let res = foldMap loop home_imp_ids - -- Now check whether everything which transitively depends on a home_unit is actually a home_unit - -- These units are the ones which we need to load as home packages but failed to do for some reason, - -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids - then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] - +-- +-- See Note [Multiple Home Units], section 'Closure Property'. +checkHomeUnitsClosed :: UnitEnv -> [DriverMessages] +checkHomeUnitsClosed ue + | Set.null bad_unit_ids = [] + | otherwise = [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] where + home_id_set = unitEnv_keys $ ue_home_unit_graph ue + bad_unit_ids = upwards_closure Set.\\ home_id_set rootLoc = mkGeneralSrcSpan (fsLit "") - -- TODO: This could repeat quite a bit of work but I struggled to write this function. - -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit - loop (from_uid, uid) = - let us = ue_findHomeUnitEnv from_uid ue in - let um = unitInfoMap (homeUnitEnv_units us) in - case lookupUniqMap um uid of - Nothing -> pprPanic "uid not found" (ppr uid) - Just ui -> - let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set - in - -- Case 1: The unit directly depends on a home_id - if not (null home_depends) - then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res - -- Case 2: Check the rest of the dependencies, and then see if any of them depended on - else - let res = foldMap (loop . (from_uid,)) other_depends - in - if not (Set.null res) - then Set.insert uid res - else res + + graph :: Graph (Node UnitId UnitId) + graph = graphFromEdgedVerticesUniq graphNodes + + -- downwards closure of graph + downwards_closure + = graphFromEdgedVerticesUniq [ DigraphNode uid uid (Set.toList deps) + | (uid, deps) <- M.toList (allReachable graph node_key)] + + inverse_closure = transposeG downwards_closure + + upwards_closure = Set.fromList $ map node_key $ reachablesG inverse_closure [DigraphNode uid uid [] | uid <- Set.toList home_id_set] + + all_unit_direct_deps :: UniqMap UnitId (Set.Set UnitId) + all_unit_direct_deps + = unitEnv_foldWithKey go emptyUniqMap $ ue_home_unit_graph ue + where + go rest this this_uis = + plusUniqMap_C Set.union + (addToUniqMap_C Set.union external_depends this (Set.fromList $ this_deps)) + rest + where + external_depends = mapUniqMap (Set.fromList . unitDepends) (unitInfoMap this_units) + this_units = homeUnitEnv_units this_uis + this_deps = [ toUnitId unit | (unit,Just _) <- explicitUnits this_units] + + graphNodes :: [Node UnitId UnitId] + graphNodes = go Set.empty home_id_set + where + go done todo + = case Set.minView todo of + Nothing -> [] + Just (uid, todo') + | Set.member uid done -> go done todo' + | otherwise -> case lookupUniqMap all_unit_direct_deps uid of + Nothing -> pprPanic "uid not found" (ppr (uid, all_unit_direct_deps)) + Just depends -> + let todo'' = (depends Set.\\ done) `Set.union` todo' + in DigraphNode uid uid (Set.toList depends) : go (Set.insert uid done) todo'' -- | Update the every ModSummary that is depended on -- by a module that needs template haskell. We enable codegen to ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -70,6 +70,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmAllowQuotRem2 :: !Bool -- ^ Allowed to generate QuotRem , stgToCmmAllowExtendedAddSubInstrs :: !Bool -- ^ Allowed to generate AddWordC, SubWordC, Add2, etc. , stgToCmmAllowIntMul2Instr :: !Bool -- ^ Allowed to generate IntMul2 instruction + , stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction , stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks. ------------------------------ SIMD flags ------------------------------------ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1623,7 +1623,7 @@ emitPrimOp cfg primop = else Right genericIntSubCOp WordMul2Op -> \args -> opCallishHandledLater args $ - if allowExtAdd + if allowWord2Mul then Left (MO_U_Mul2 (wordWidth platform)) else Right genericWordMul2Op @@ -1850,6 +1850,7 @@ emitPrimOp cfg primop = allowQuotRem2 = stgToCmmAllowQuotRem2 cfg allowExtAdd = stgToCmmAllowExtendedAddSubInstrs cfg allowInt2Mul = stgToCmmAllowIntMul2Instr cfg + allowWord2Mul = stgToCmmAllowWordMul2Instr cfg allowFMA = stgToCmmAllowFMAInstr cfg ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1626,7 +1626,7 @@ as such you shouldn't need to set any of them explicitly. A flag :ghc-flag:`-funfolding-use-threshold=⟨n⟩`. .. ghc-flag:: -funfolding-use-threshold=⟨n⟩ - :shortdesc: *default: 80.* Tweak unfolding settings. + :shortdesc: *default: 90.* Tweak unfolding settings. :type: dynamic :category: ===================================== libraries/base/changelog.md ===================================== @@ -4,6 +4,7 @@ * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, ===================================== libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs ===================================== @@ -75,4 +75,4 @@ throwIfNull = throwIf (== nullPtr) . const -- void :: IO a -> IO () void act = act >> return () -{-# DEPRECATED void "use 'GHC.Internal.Control.Monad.void' instead" #-} -- deprecated in 7.6 +{-# DEPRECATED void "use 'Control.Monad.void' instead" #-} -- deprecated in 7.6 ===================================== libraries/ghc-internal/src/GHC/Internal/List.hs ===================================== @@ -90,7 +90,7 @@ head (x:_) = x head [] = badHead {-# NOINLINE [1] head #-} -{-# WARNING in "x-partial" head "This is a partial function, it throws an error on empty lists. Use pattern matching, 'GHC.Internal.Data.List.uncons' or 'GHC.Internal.Data.Maybe.listToMaybe' instead. Consider refactoring to use \"Data.List.NonEmpty\"." #-} +{-# WARNING in "x-partial" head "This is a partial function, it throws an error on empty lists. Use pattern matching, 'Data.List.uncons' or 'Data.Maybe.listToMaybe' instead. Consider refactoring to use \"Data.List.NonEmpty\"." #-} badHead :: HasCallStack => a badHead = errorEmptyList "head" ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x0a0]\n\t" + "str x21, [%0, 0x0a8]\n\t" + "str x22, [%0, 0x0b0]\n\t" + "str x23, [%0, 0x0b8]\n\t" + "str x24, [%0, 0x0c0]\n\t" + "str x25, [%0, 0x0c8]\n\t" + "str x26, [%0, 0x0d0]\n\t" + "str x27, [%0, 0x0d8]\n\t" + "str x28, [%0, 0x0e0]\n\t" + "str x29, [%0, 0x0e8]\n\t" + "str x30, [%0, 0x0f0]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x0f8]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x100]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { ===================================== rts/RtsFlags.c ===================================== @@ -1959,6 +1959,9 @@ static void normaliseRtsOpts (void) if (RtsFlags.GcFlags.maxHeapSize != 0 && RtsFlags.GcFlags.heapSizeSuggestion > RtsFlags.GcFlags.maxHeapSize) { + errorBelch("Maximum heap size (-M) is smaller than suggested heap size (-H)\n" + "Setting maximum heap size to suggested heap size ( %" FMT_Word64 " )", + (StgWord64) RtsFlags.GcFlags.maxHeapSize * (StgWord64) BLOCK_SIZE); RtsFlags.GcFlags.maxHeapSize = RtsFlags.GcFlags.heapSizeSuggestion; } ===================================== testsuite/tests/bytecode/T24634/Hello.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE CApiFFI #-} +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE TemplateHaskell #-} + +module Hello where + +import Language.Haskell.TH +import Language.Haskell.TH.Syntax + +foreign import capi "hello.h say_hello" say_hello :: IO Int + +mkHello :: DecsQ +mkHello = do + n <- runIO say_hello + [d| hello :: IO Int + hello = return $(lift n) |] ===================================== testsuite/tests/bytecode/T24634/Main.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Hello + +$(mkHello) + +main :: IO () +main = hello >>= print ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +bytecode-capi: + $(TEST_HC) -c hello.c + $(TEST_HC) -c -fbyte-code-and-object-code Hello.hs + $(TEST_HC) -fprefer-byte-code hello.o Main.hs + ./Main ===================================== testsuite/tests/bytecode/T24634/all.T ===================================== @@ -0,0 +1,7 @@ +test('T24634', + [extra_files(['hello.h', 'hello.c', 'Hello.hs', 'Main.hs']), + req_interp, + expect_broken(24634), + ], + makefile_test, + ['']) ===================================== testsuite/tests/bytecode/T24634/hello.c ===================================== @@ -0,0 +1,5 @@ +#include "hello.h" + +int say_hello() { + return 42; +} ===================================== testsuite/tests/bytecode/T24634/hello.h ===================================== @@ -0,0 +1 @@ +int say_hello(void); ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile ===================================== @@ -0,0 +1,23 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +SETUP=../Setup -v0 + +mhu-perf: clean + $(MAKE) -s --no-print-directory clean + ./genLargeHMU + '$(GHC_PKG)' init tmp.d + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make Setup + for dir in unit-p*; do \ + cd $$dir && $(SETUP) clean && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --ipid=$$dir-0.1.0.0 --with-ghc='$(TEST_HC)' --with-hc-pkg='$(GHC_PKG)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d && $(SETUP) build && $(SETUP) register --inplace && cd ..; \ + done; + + +ifeq "$(CLEANUP)" "1" + $(MAKE) -s --no-print-directory clean +endif + +clean : + $(RM) -r unitTop* unit-p* top*/ tmp*.d inst-* *.o *.hi */*.o */*.hi */Setup$(exeext) */dist Setup$(exeext) + ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs ===================================== @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -0,0 +1,10 @@ +test('mhu-perf', + [ collect_compiler_stats('bytes allocated',2), + extra_files(['genLargeHMU','Setup.hs']), + pre_cmd('$MAKE -s --no-print-directory mhu-perf'), + js_broken(22349), + when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests + compile_timeout_multiplier(5) + ], + multiunit_compile, + [['unitTop1', 'unitTop2'], '-fhide-source-paths']) ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU ===================================== @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of packages with $WIDTH modules on each layer +# Every package on layer N depends on all the packages on layer N-1 +# unitTop imports all the units from the last layer +DEPTH=8 +WIDTH=8 +for i in $(seq -w 1 $WIDTH); do + mkdir unit-p0M$i + echo "module DummyLevel0M$i where" > unit-p0M$i/DummyLevel0M$i.hs; + cat > unit-p0M$i/unit-p0M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel0M$i + build-depends: base +EOF +done +for l in $(seq 1 $DEPTH); do + for i in $(seq -w 1 $WIDTH); do + mkdir unit-p${l}M$i + cat > unit-p${l}M$i/unit-p${l}M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel${l}M$i + build-depends: base +EOF + echo "module DummyLevel${l}M$i where" > unit-p${l}M$i/DummyLevel${l}M$i.hs; + for j in $(seq -w 1 $WIDTH); do + echo " , unit-p$((l-1))M$j" >> unit-p${l}M$i/unit-p${l}M$i.cabal + echo "import DummyLevel$((l-1))M$j" >> unit-p${l}M$i/DummyLevel${l}M$i.hs; + done + done +done +mkdir top1 +echo "module Top1 where" > top1/Top1.hs +echo "-package-db ./tmp.d -i -itop1 Top1 -this-unit-id unit-top1 -package base" > unitTop1; +for j in $(seq -w 1 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop1; + echo "import DummyLevel${DEPTH}M$j" >> top1/Top1.hs; +done +mkdir top2 +echo "module Top2 where" > top2/Top2.hs +echo "-package-db ./tmp.d -i -itop2 Top2 -this-unit-id unit-top2 -package base" > unitTop2; +for j in $(seq -w 2 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop2; + echo "import DummyLevel${DEPTH}M$j" >> top2/Top2.hs; +done ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr ===================================== @@ -0,0 +1,2 @@ +[1 of 2] Compiling Top1[unit-top1] +[2 of 2] Compiling Top2[unit-top2] ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -50,6 +50,7 @@ test('T4383', normal, compile_and_run, ['']) test('add2', normal, compile_and_run, ['-fobject-code']) test('mul2', normal, compile_and_run, ['-fobject-code']) +test('mul2int', normal, compile_and_run, ['-fobject-code']) test('quotRem2', normal, compile_and_run, ['-fobject-code']) test('T5863', normal, compile_and_run, ['']) ===================================== testsuite/tests/numeric/should_run/mul2int.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE MagicHash, UnboxedTuples #-} + +import GHC.Exts +import Data.Bits + +main :: IO () +main = do g 5 6 + g (-5) 6 + g 0x7ECA71DBFF1B7D8C 49 + g (-0x7ECA71DBFF1B7D8C) 49 + g 0x7ECA71DBFF1B7D8C 0x7E0EC51DFD94FE35 + g 0x7ECA71DBFF1B7D8C (-0x7E0EC51DFD94FE35) + + +g :: Int -> Int -> IO () +g wx@(I# x) wy@(I# y) + = do putStrLn "-----" + putStrLn ("Doing " ++ show wx ++ " * " ++ show wy) + case x `timesInt2#` y of + (# n, h, l #) -> + do let wh = I# h + wl = I# l + wlw = W# (int2Word# l) + wn = I# n + r | wn == 1 = shiftL (fromIntegral wh) (finiteBitSize wh) + + fromIntegral wlw + | otherwise = fromIntegral wl + + putStrLn ("High: " ++ show wh) + putStrLn ("Low: " ++ show wl) + putStrLn ("Needed: " ++ show wn) + putStrLn ("Result: " ++ show (r :: Integer)) + putStrLn ("Should be: " ++ show (fromIntegral wx * fromIntegral wy :: Integer)) + + ===================================== testsuite/tests/numeric/should_run/mul2int.stdout ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing 9136239983766240652 * 49 +High: 24 +Low: 4953901435516553164 +Needed: 1 +Result: 447675759204545791948 +Should be: 447675759204545791948 +----- +Doing -9136239983766240652 * 49 +High: -25 +Low: -4953901435516553164 +Needed: 1 +Result: -447675759204545791948 +Should be: -447675759204545791948 +----- +Doing 9136239983766240652 * 9083414231051992629 +High: 4498802171008813567 +Low: 3355592377236579836 +Needed: 1 +Result: 82988252286848496451678442784944154108 +Should be: 82988252286848496451678442784944154108 +----- +Doing 9136239983766240652 * -9083414231051992629 +High: -4498802171008813568 +Low: -3355592377236579836 +Needed: 1 +Result: -82988252286848496451678442784944154108 +Should be: -82988252286848496451678442784944154108 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d229a2600ceaa880f691f776d871fe255a34e3b0...29b9d4e012f78fcaae1ccb1f5a51f3a41988f104 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d229a2600ceaa880f691f776d871fe255a34e3b0...29b9d4e012f78fcaae1ccb1f5a51f3a41988f104 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 11 22:49:30 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 18:49:30 -0400 Subject: [Git][ghc/ghc][wip/bump-parsec] 79 commits: EPA: Fix FamDecl range Message-ID: <661868fad0072_9891d179fbd41262f0@gitlab.mail> Ben Gamari pushed to branch wip/bump-parsec at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 2d9afd11 by Ben Gamari at 2024-04-11T18:49:17-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 20 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/afd51cf0263ea75f263f3344aa37a03389562955...2d9afd113d6ba67b977e47940148847b4bbe05ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/afd51cf0263ea75f263f3344aa37a03389562955...2d9afd113d6ba67b977e47940148847b4bbe05ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 01:23:38 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 11 Apr 2024 21:23:38 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 2 commits: Bump parsec submodule to upstream master Message-ID: <66188d1ac9c60_9891d2ab42b01316ed@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 178f20ce by Ben Gamari at 2024-04-11T18:51:33-04:00 Bump parsec submodule to upstream master - - - - - 4cf82155 by Ben Gamari at 2024-04-11T21:22:14-04:00 testsuite: More aggressive normalisation of process004 output It turns out that this test uses `execvp`, not `exec` on CentOS 7. Normalise this spurious difference away. - - - - - 3 changed files: - libraries/parsec - testsuite/tests/process/all.T - utils/haddock Changes: ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 0736c51d0b39a9852cd39259af4cfaf6cafe36a3 +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== testsuite/tests/process/all.T ===================================== @@ -1,6 +1,10 @@ -# some platforms use spawnp instead of exec in some cases, resulting +# some platforms use spawnp or execvp instead of exec in some cases, resulting # in spurious error output changes. -normalise_exec = normalise_fun(lambda s: s.replace('posix_spawnp', 'exec')) +normalise_exec = normalise_fun( + lambda s: s.replace('posix_spawnp', 'exec'), + lambda s: s.replace('execvp', 'exec'), + lambda s: s.replace('execvpe', 'exec'), +) test('process001', [req_process], compile_and_run, ['']) test('process002', [fragile_for(16547, concurrent_ways), req_process], compile_and_run, ['']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 1432bcc943d41736eca491ecec4eb9a6304dab36 +Subproject commit 5007fd360e73b5253a9a1b371bfae653b00d03c6 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/220cda2c7d3055499b7b40ea4dbf2a0ed7bf18e0...4cf82155ab7ed13249681a2fdf5a88dc93bf1e0b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/220cda2c7d3055499b7b40ea4dbf2a0ed7bf18e0...4cf82155ab7ed13249681a2fdf5a88dc93bf1e0b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 03:56:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 11 Apr 2024 23:56:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <6618b0e9aa778_9891d3f9bdb817192a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: a00b0223 by Alex Mason at 2024-04-11T23:54:55-04:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 29773610 by Ben Gamari at 2024-04-11T23:54:55-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - 6ec3a41c by Zubin Duggal at 2024-04-11T23:54:56-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 8bc83252 by Andreas Klebinger at 2024-04-11T23:54:57-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - 3d20f746 by Ben Gamari at 2024-04-11T23:54:57-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - c079ec41 by Ben Gamari at 2024-04-11T23:54:58-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - a2871b08 by Ben Gamari at 2024-04-11T23:54:59-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - d702bc06 by Ben Gamari at 2024-04-11T23:54:59-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 8f88ffc4 by Ben Gamari at 2024-04-11T23:55:00-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 44d01be2 by Ben Gamari at 2024-04-11T23:55:00-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - c0cfe6c7 by Finley McIlwaine at 2024-04-11T23:55:00-04:00 Correct default -funfolding-use-threshold in docs - - - - - f654fcd7 by Oleg Grenrus at 2024-04-11T23:55:01-04:00 FastString is a __Modified__ UTF-8 - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/exts/applicative_do.rst - docs/users_guide/exts/arrows.rst - docs/users_guide/exts/binary_literals.rst - docs/users_guide/exts/constrained_class_methods.rst - docs/users_guide/exts/constraint_kind.rst - docs/users_guide/exts/data_kinds.rst - docs/users_guide/exts/default_signatures.rst - docs/users_guide/exts/derive_any_class.rst - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/deriving_strategies.rst - docs/users_guide/exts/deriving_via.rst - docs/users_guide/exts/disambiguate_record_fields.rst - docs/users_guide/exts/empty_case.rst - docs/users_guide/exts/existential_quantification.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/field_selectors.rst - docs/users_guide/exts/functional_dependencies.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29b9d4e012f78fcaae1ccb1f5a51f3a41988f104...f654fcd7505749929eaa5d7c56c6abd6deddb9b3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29b9d4e012f78fcaae1ccb1f5a51f3a41988f104...f654fcd7505749929eaa5d7c56c6abd6deddb9b3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 07:26:59 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 12 Apr 2024 03:26:59 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Fix linker issue Message-ID: <6618e24350bd6_10a7841671d84714dc@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 1bb2fd79 by Sven Tennie at 2024-04-12T07:26:50+00:00 Fix linker issue Local symbols don't get GOT entries. Fake them with extra symbols instead. Such that R_RISCV_CALL_PLT has an address to load and jump to. - - - - - 1 changed file: - rts/linker/elf_reloc_riscv64.c Changes: ===================================== rts/linker/elf_reloc_riscv64.c ===================================== @@ -454,9 +454,23 @@ int32_t computeAddend(ElfRelocationATable * relaTab, unsigned relNo, Elf_Rel *re return S + A - P; case R_RISCV_CALL: case R_RISCV_CALL_PLT: { + addr_t GOT_Target; + if (GOT_S != 0) { + // 1. Public symbol with GOT entry. + GOT_Target = GOT_S; + } else { + // 2. Fake GOT entry with symbol extra entry. + SymbolExtra *symbolExtra = makeSymbolExtra(oc, ELF_R_SYM(rel->r_info), S); + addr_t* FAKE_GOT_S = &symbolExtra->addr; + IF_DEBUG(linker, debugBelch("R_RISCV_CALL_PLT w/ SymbolExtra = %p , " + "entry = 0x%lx\n", + symbolExtra, FAKE_GOT_S)); + GOT_Target = FAKE_GOT_S; + } + if (findStub(section, (void **)&S, 0)) { /* did not find it. Crete a new stub. */ - if (makeStub(section, (void **)&S, (void *)GOT_S, 0)) { + if (makeStub(section, (void **)&S, (void *)GOT_Target, 0)) { abort(/* could not find or make stub */); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1bb2fd798f14a6a8f06d3193eadebaf102469d83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1bb2fd798f14a6a8f06d3193eadebaf102469d83 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 07:32:05 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 12 Apr 2024 03:32:05 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Add missing relocation to name (string) mapping Message-ID: <6618e375a03c5_10a78418275487203e@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: 79bdf61d by Sven Tennie at 2024-04-12T09:31:55+02:00 Add missing relocation to name (string) mapping - - - - - 1 changed file: - rts/linker/elf_reloc_riscv64.c Changes: ===================================== rts/linker/elf_reloc_riscv64.c ===================================== @@ -66,6 +66,10 @@ char *relocationTypeToString(Elf64_Xword type) { return "R_RISCV_PCREL_LO12_S"; case R_RISCV_RELAX: return "R_RISCV_RELAX"; + case R_RISCV_RVC_BRANCH: + return "R_RISCV_RVC_BRANCH"; + case R_RISCV_RVC_JUMP: + return "R_RISCV_RVC_JUMP"; default: return "Unknown relocation type"; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/79bdf61d1e82202329e7e89e4fcdfb9805b5a62f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/79bdf61d1e82202329e7e89e4fcdfb9805b5a62f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 08:14:01 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 04:14:01 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <6618ed498e3ec_10a7841e4de9089849@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: cc3ab32e by Simon Peyton Jones at 2024-04-12T09:09:03+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. - - - - - 1 changed file: - compiler/GHC/Core/Opt/SetLevels.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,97 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib. It's really + a bit of a heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of doing + so is that we end up floating out a HNF from a cold path (where it might never + get allocated at all) and allocating it all the time regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top] + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation: saves_alloc] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1192,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc3ab32ebe0c2f95d0bfefa698400c05bceb03af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc3ab32ebe0c2f95d0bfefa698400c05bceb03af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 08:15:44 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 04:15:44 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <6618edb036d33_10a7841eeec14904c0@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 123faa9b by Simon Peyton Jones at 2024-04-12T09:15:33+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. - - - - - 1 changed file: - compiler/GHC/Core/Opt/SetLevels.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,98 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of doing + so is that we end up floating out a HNF from a cold path (where it might never + get allocated at all) and allocating it all the time regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top] + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation: saves_alloc] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1193,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/123faa9b7ffda0d8aabc8e401d74d63c783db3f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/123faa9b7ffda0d8aabc8e401d74d63c783db3f3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 08:17:54 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 04:17:54 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <6618ee32d037a_10a784202053893864@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 2812ec54 by Simon Peyton Jones at 2024-04-12T09:17:44+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. - - - - - 1 changed file: - compiler/GHC/Core/Opt/SetLevels.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,99 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top] + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation: saves_alloc] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1194,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2812ec5429a01a672dde9740304ea4202f642c2d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2812ec5429a01a672dde9740304ea4202f642c2d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 08:22:03 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 04:22:03 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <6618ef2b866a9_10a784216fc90956fb@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 9d70b0b8 by Simon Peyton Jones at 2024-04-12T09:21:53+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - 2 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - testsuite/tests/simplCore/should_compile/T18013.stderr Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,99 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top] + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation: saves_alloc] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1194,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d70b0b8e4e1e058769d05c3ae36569ad90cec2b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d70b0b8e4e1e058769d05c3ae36569ad90cec2b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 08:53:32 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 12 Apr 2024 04:53:32 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <6618f68ced1c7_10a78426331001085d4@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: b06519e2 by Teo Camarasu at 2024-04-12T09:52:24+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 15 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libffi-tarballs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,116 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to +-- convert TH ASTs returned by splices into the Hs AST, both of which do not +-- depend on the fully qualified name of the type to serialise! Importantly, +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] is +-- unaffected, because the desugaring refers to names in the in-tree TH +-- library, which is built in the next stage, stage1, and later. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a +-- single version of template-haskell. +-- (Beyond the fact that doing otherwise would invite even +-- more "which `template-haskell` is this" confusion, it +-- would also result in confusing linker errors: see for +-- example #21981. In principle we could likely lift this +-- restriction with more aggressive name mangling, but the +-- knock-on effects of doing so are unexplored.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +160,7 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell + , templateHaskellNext , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libffi-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 89a9b01c5647c8f0d3899435b99df690f582e9f1 +Subproject commit 5624fd5c8bbce8432cd3c0b0ea92d152a1bba047 ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.* + else + build-depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) -import Data.Int +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word -import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) import Data.Array.Byte (ByteArray(..)) +import Data.Char (ord) +import Data.Int +import Data.Ratio +import Data.Void ( Void, absurd ) +import GHC.CString ( unpackCString# ) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.ST (ST(..), runST) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import Numeric.Natural +import qualified Data.Fixed as Fixed +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from ../template-haskell/template-haskell.cabal.in by -- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b06519e2ece645ffa9e80b7b6a43ddd2e6e840ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b06519e2ece645ffa9e80b7b6a43ddd2e6e840ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:22:46 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 12 Apr 2024 05:22:46 -0400 Subject: [Git][ghc/ghc][wip/T24124] 428 commits: Turn -Wtype-equality-out-of-scope on by default Message-ID: <6618fd66a54e6_10a7842c356981373c@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 7c28f974 by Sebastian Graf at 2024-04-12T11:21:37+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 19 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - .gitmodules - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c362c07867e5cb62c53909bfc6cddffe73691d62...7c28f974f990f56747f45dbee823d68bb6e6a519 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c362c07867e5cb62c53909bfc6cddffe73691d62...7c28f974f990f56747f45dbee823d68bb6e6a519 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:26:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 05:26:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: users-guide: Clarify language extension documentation Message-ID: <6618fe60670d_10a7842e39c1415507d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 73102daf by Ben Gamari at 2024-04-12T05:25:55-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - 8240c69c by Zubin Duggal at 2024-04-12T05:25:56-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 988ba1da by Andreas Klebinger at 2024-04-12T05:25:57-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - b2374c09 by Ben Gamari at 2024-04-12T05:25:57-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - b85a0f6e by Ben Gamari at 2024-04-12T05:25:58-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 431db3aa by Ben Gamari at 2024-04-12T05:25:58-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - 0658d603 by Ben Gamari at 2024-04-12T05:25:59-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 88634099 by Ben Gamari at 2024-04-12T05:25:59-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - ac4f917a by Ben Gamari at 2024-04-12T05:26:00-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 93b31c58 by Finley McIlwaine at 2024-04-12T05:26:00-04:00 Correct default -funfolding-use-threshold in docs - - - - - c9811d9e by Oleg Grenrus at 2024-04-12T05:26:01-04:00 FastString is a __Modified__ UTF-8 - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Make.hs - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/exts/applicative_do.rst - docs/users_guide/exts/arrows.rst - docs/users_guide/exts/binary_literals.rst - docs/users_guide/exts/constrained_class_methods.rst - docs/users_guide/exts/constraint_kind.rst - docs/users_guide/exts/data_kinds.rst - docs/users_guide/exts/default_signatures.rst - docs/users_guide/exts/derive_any_class.rst - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/deriving_strategies.rst - docs/users_guide/exts/deriving_via.rst - docs/users_guide/exts/disambiguate_record_fields.rst - docs/users_guide/exts/empty_case.rst - docs/users_guide/exts/existential_quantification.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/field_selectors.rst - docs/users_guide/exts/functional_dependencies.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/gadt_syntax.rst - docs/users_guide/exts/generalised_list_comprehensions.rst - docs/users_guide/exts/generics.rst - docs/users_guide/exts/hex_float_literals.rst - docs/users_guide/exts/implicit_parameters.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f654fcd7505749929eaa5d7c56c6abd6deddb9b3...c9811d9e02c922046b6c7395aa643109f0ca2ebc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f654fcd7505749929eaa5d7c56c6abd6deddb9b3...c9811d9e02c922046b6c7395aa643109f0ca2ebc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:31:03 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 12 Apr 2024 05:31:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24651 Message-ID: <6618ff578d5b0_10a7842f275681603e1@gitlab.mail> Teo Camarasu pushed new branch wip/T24651 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24651 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:38:31 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 12 Apr 2024 05:38:31 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <6619011722f3f_10a78430d682816408c@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: 1aadfdb5 by Sebastian Graf at 2024-04-12T11:33:32+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 23 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - + testsuite/tests/dmdanal/should_run/T24124b.hs - testsuite/tests/dmdanal/should_run/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_MAGIC (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -159,19 +159,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -306,6 +306,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -596,7 +603,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -649,7 +656,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -681,7 +688,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -843,13 +850,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 ty alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 ty alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -938,14 +955,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -987,7 +1004,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1006,9 +1023,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1021,7 +1038,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1031,7 +1048,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1057,24 +1074,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1121,13 +1153,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1183,13 +1215,13 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1198,10 +1230,10 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1481,11 +1513,12 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] ; let arity = cpeArgArity env dec arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } @@ -1704,6 +1737,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1817,6 +1895,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -1983,23 +2064,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2017,6 +2118,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2049,7 +2151,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2510,7 +2612,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2237,8 +2238,93 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect so +that GHC's optimisations must preserve the evaluation "exactly here" in the +state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place. This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + +(SEQ3) + Why return the value? So that we can control sharing of seq'd + values: in + let x = e in x `seq` ... x ... + We don't want to inline x, so better to represent it as + let x = e in case seq# x RW of (# _, x' #) -> ... x' ... + also it matches the type of rseq in the Eval monad. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -24,7 +26,7 @@ -- ----------------------------------------------------------------------------- -module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..) ) where +module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) ) where -------------------------------------------------- -- See Note [magicIds] in GHC.Types.Id.Make @@ -119,6 +121,14 @@ runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). {-# NOINLINE runRW# #-} -- runRW# is inlined manually in CorePrep runRW# m = m realWorld# +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | @'dataToTag#'@ evaluates its argument and returns the index -- (starting at zero) of the constructor used to produce that -- argument. Any algebraic data type with all of its constructors ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,36 @@ +{-# LANGUAGE MagicHash #-} + +import GHC.Exts +import Debug.Trace +import GHC.IO +import GHC.ST + +data StrictPair a b = !a :*: !b + +strictFun :: Int -> Int +{-# OPAQUE strictFun #-} +strictFun x = x*x*x + +opaqueId :: a -> a +{-# OPAQUE opaqueId #-} +{-# RULES + "opaqueId/noinline" opaqueId = noinline +#-} +-- work around noinline's special desugaring +opaqueId v = v + +evaluateST :: a -> ST s a +-- hide the fact that we are actually in IO because !11515 +-- causes seq# to look like it can throw precise exceptions +evaluateST x = ST (\s -> seq# x s) + +fun :: Int -> Int -> ST s Int +{-# OPAQUE fun #-} +fun = lazy $ \ !x y -> do + -- This should evaluate x before y. + _ <- evaluateST $ opaqueId (x :*: x) + _ <- evaluateST y + evaluateST $! strictFun x + +main :: IO () +main = () <$ stToIO (fun (trace "x eval'd" 12) (trace "y eval'd" 13)) ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,3 +4,4 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile_and_run, ['-O']) ===================================== testsuite/tests/dmdanal/should_run/T24124b.hs ===================================== @@ -0,0 +1,9 @@ +import Control.Exception + +f :: Int -> Int -> IO Int +f x y = do + evaluate x + pure $! y + 1 +{-# NOINLINE f #-} + +main = f (error "should see this") (error "should not see this") >> pure () ===================================== testsuite/tests/dmdanal/should_run/all.T ===================================== @@ -33,3 +33,4 @@ test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) +test('T24124b', exit_code(1), compile_and_run, ['']) ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -17,23 +17,21 @@ T15226b.testFun1 -> b -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=, Unf=OtherCon []] = {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> - let { - sat [Occ=Once1] :: T15226b.StrictPair a b - [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; }; T15226b.testFun :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=, Unf=OtherCon []] = {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; T15226b.MkStrictPair [InlPrag=CONLIKE] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1aadfdb526e726b7dc5d6010212ed02270ef1236 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1aadfdb526e726b7dc5d6010212ed02270ef1236 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:40:39 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 12 Apr 2024 05:40:39 -0400 Subject: [Git][ghc/ghc][wip/T24651] wip Message-ID: <66190197e51c_10a784317c4a816821@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: 57ec63b1 by Teo Camarasu at 2024-04-12T10:40:11+01:00 wip - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -559,11 +559,11 @@ doc-tarball: artifacts: paths: - haddock.html.tar.xz - - haddock/* + - haddock/**/*.html - libraries.html.tar.xz - - libraries/* + - libraries/**/*.html - users_guide.html.tar.xz - - users_guide/* + - users_guide/**/*.html - index.html - "*.pdf" script: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57ec63b1b1bf10bcfe4340c636a186c5b4531812 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57ec63b1b1bf10bcfe4340c636a186c5b4531812 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:41:08 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 12 Apr 2024 05:41:08 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <661901b459f80_10a784323a3b8168595@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: b560f33b by Sebastian Graf at 2024-04-12T11:40:44+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 23 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - + testsuite/tests/dmdanal/should_run/T24124b.hs - testsuite/tests/dmdanal/should_run/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_MAGIC (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -159,19 +159,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -306,6 +306,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -596,7 +603,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -649,7 +656,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -681,7 +688,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -843,13 +850,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 ty alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 ty alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -938,14 +955,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -987,7 +1004,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1006,9 +1023,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1021,7 +1038,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1031,7 +1048,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1057,24 +1074,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1121,13 +1153,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1183,13 +1215,13 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1198,10 +1230,10 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1481,11 +1513,12 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] ; let arity = cpeArgArity env dec arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } @@ -1704,6 +1737,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1817,6 +1895,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -1983,23 +2064,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2017,6 +2118,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2049,7 +2151,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2510,7 +2612,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2237,8 +2238,93 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place. This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + +(SEQ3) + Why return the value? So that we can control sharing of seq'd + values: in + let x = e in x `seq` ... x ... + We don't want to inline x, so better to represent it as + let x = e in case seq# x RW of (# _, x' #) -> ... x' ... + also it matches the type of rseq in the Eval monad. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -24,7 +26,7 @@ -- ----------------------------------------------------------------------------- -module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..) ) where +module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) ) where -------------------------------------------------- -- See Note [magicIds] in GHC.Types.Id.Make @@ -119,6 +121,14 @@ runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). {-# NOINLINE runRW# #-} -- runRW# is inlined manually in CorePrep runRW# m = m realWorld# +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | @'dataToTag#'@ evaluates its argument and returns the index -- (starting at zero) of the constructor used to produce that -- argument. Any algebraic data type with all of its constructors ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,36 @@ +{-# LANGUAGE MagicHash #-} + +import GHC.Exts +import Debug.Trace +import GHC.IO +import GHC.ST + +data StrictPair a b = !a :*: !b + +strictFun :: Int -> Int +{-# OPAQUE strictFun #-} +strictFun x = x*x*x + +opaqueId :: a -> a +{-# OPAQUE opaqueId #-} +{-# RULES + "opaqueId/noinline" opaqueId = noinline +#-} +-- work around noinline's special desugaring +opaqueId v = v + +evaluateST :: a -> ST s a +-- hide the fact that we are actually in IO because !11515 +-- causes seq# to look like it can throw precise exceptions +evaluateST x = ST (\s -> seq# x s) + +fun :: Int -> Int -> ST s Int +{-# OPAQUE fun #-} +fun = lazy $ \ !x y -> do + -- This should evaluate x before y. + _ <- evaluateST $ opaqueId (x :*: x) + _ <- evaluateST y + evaluateST $! strictFun x + +main :: IO () +main = () <$ stToIO (fun (trace "x eval'd" 12) (trace "y eval'd" 13)) ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,3 +4,4 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile_and_run, ['-O']) ===================================== testsuite/tests/dmdanal/should_run/T24124b.hs ===================================== @@ -0,0 +1,9 @@ +import Control.Exception + +f :: Int -> Int -> IO Int +f x y = do + evaluate x + pure $! y + 1 +{-# NOINLINE f #-} + +main = f (error "should see this") (error "should not see this") >> pure () ===================================== testsuite/tests/dmdanal/should_run/all.T ===================================== @@ -33,3 +33,4 @@ test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) +test('T24124b', exit_code(1), compile_and_run, ['']) ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -17,23 +17,21 @@ T15226b.testFun1 -> b -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=, Unf=OtherCon []] = {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> - let { - sat [Occ=Once1] :: T15226b.StrictPair a b - [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; }; T15226b.testFun :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=, Unf=OtherCon []] = {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; T15226b.MkStrictPair [InlPrag=CONLIKE] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b560f33b09dd34c6c7b5de37c7b0f90ddf256586 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b560f33b09dd34c6c7b5de37c7b0f90ddf256586 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 09:47:47 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 12 Apr 2024 05:47:47 -0400 Subject: [Git][ghc/ghc][wip/T24651] Deleted 1 commit: wip Message-ID: <66190343e55db_10a78433acd181703e5@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: 57ec63b1 by Teo Camarasu at 2024-04-12T10:40:11+01:00 wip - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -559,11 +559,11 @@ doc-tarball: artifacts: paths: - haddock.html.tar.xz - - haddock/* + - haddock/**/*.html - libraries.html.tar.xz - - libraries/* + - libraries/**/*.html - users_guide.html.tar.xz - - users_guide/* + - users_guide/**/*.html - index.html - "*.pdf" script: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57ec63b1b1bf10bcfe4340c636a186c5b4531812 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57ec63b1b1bf10bcfe4340c636a186c5b4531812 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 11:27:01 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 07:27:01 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <66191a85c983_15732780c37068943@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 2fb8a828 by Simon Peyton Jones at 2024-04-12T12:26:45+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - 3 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,99 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top] + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1194,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2fb8a82838a492d37c37ec5774be03faae5d2878 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2fb8a82838a492d37c37ec5774be03faae5d2878 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 11:38:57 2024 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Fri, 12 Apr 2024 07:38:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24620 Message-ID: <66191d512e8e4_157327a2f74c7375a@gitlab.mail> Ryan Scott pushed new branch wip/T24620 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24620 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:16:38 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:16:38 -0400 Subject: [Git][ghc/ghc][master] users-guide: Clarify language extension documentation Message-ID: <66192626ab42e_157327fdfd40925ca@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - 30 changed files: - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/exts/applicative_do.rst - docs/users_guide/exts/arrows.rst - docs/users_guide/exts/binary_literals.rst - docs/users_guide/exts/constrained_class_methods.rst - docs/users_guide/exts/constraint_kind.rst - docs/users_guide/exts/data_kinds.rst - docs/users_guide/exts/default_signatures.rst - docs/users_guide/exts/derive_any_class.rst - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/deriving_strategies.rst - docs/users_guide/exts/deriving_via.rst - docs/users_guide/exts/disambiguate_record_fields.rst - docs/users_guide/exts/empty_case.rst - docs/users_guide/exts/existential_quantification.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/field_selectors.rst - docs/users_guide/exts/functional_dependencies.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/gadt_syntax.rst - docs/users_guide/exts/generalised_list_comprehensions.rst - docs/users_guide/exts/generics.rst - docs/users_guide/exts/hex_float_literals.rst - docs/users_guide/exts/implicit_parameters.rst - docs/users_guide/exts/import_qualified_post.rst - docs/users_guide/exts/impredicative_types.rst - docs/users_guide/exts/instances.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e18ce2bc1a315a97f9d13e52a2a09a5337c5d67 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e18ce2bc1a315a97f9d13e52a2a09a5337c5d67 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:19:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:19:06 -0400 Subject: [Git][ghc/ghc][master] driver: Make `checkHomeUnitsClosed` faster Message-ID: <661926ba87ca1_37df3c85584105070@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 6 changed files: - compiler/GHC/Driver/Make.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1565,8 +1565,8 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots (root_errs, rootSummariesOk) <- partitionWithM getRootSummary roots -- #17549 let root_map = mkRootMap rootSummariesOk checkDuplicates root_map - (deps, pkg_deps, map0) <- loopSummaries rootSummariesOk (M.empty, Set.empty, root_map) - let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) (hsc_all_home_unit_ids hsc_env) (Set.toList pkg_deps) + (deps, map0) <- loopSummaries rootSummariesOk (M.empty, root_map) + let closure_errs = checkHomeUnitsClosed (hsc_unit_env hsc_env) let unit_env = hsc_unit_env hsc_env let tmpfs = hsc_tmpfs hsc_env @@ -1660,19 +1660,19 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This loops over all the mod summaries in the dependency graph, accumulates the actual dependencies for each module/unit loopSummaries :: [ModSummary] - -> (M.Map NodeKey ModuleGraphNode, Set.Set (UnitId, UnitId), + -> (M.Map NodeKey ModuleGraphNode, DownsweepCache) - -> IO ((M.Map NodeKey ModuleGraphNode), Set.Set (UnitId, UnitId), DownsweepCache) + -> IO ((M.Map NodeKey ModuleGraphNode), DownsweepCache) loopSummaries [] done = return done - loopSummaries (ms:next) (done, pkgs, summarised) + loopSummaries (ms:next) (done, summarised) | Just {} <- M.lookup k done - = loopSummaries next (done, pkgs, summarised) + = loopSummaries next (done, summarised) -- Didn't work out what the imports mean yet, now do that. | otherwise = do - (final_deps, pkgs1, done', summarised') <- loopImports (calcDeps ms) done summarised + (final_deps, done', summarised') <- loopImports (calcDeps ms) done summarised -- This has the effect of finding a .hs file if we are looking at the .hs-boot file. - (_, _, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' - loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', pkgs1 `Set.union` pkgs, summarised'') + (_, done'', summarised'') <- loopImports (maybeToList hs_file_for_boot) done' summarised' + loopSummaries next (M.insert k (ModuleNode final_deps ms) done'', summarised'') where k = NodeKey_Module (msKey ms) @@ -1692,18 +1692,17 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- Visited set; the range is a list because -- the roots can have the same module names -- if allow_dup_roots is True - -> IO ([NodeKey], Set.Set (UnitId, UnitId), - + -> IO ([NodeKey], M.Map NodeKey ModuleGraphNode, DownsweepCache) -- The result is the completed NodeMap - loopImports [] done summarised = return ([], Set.empty, done, summarised) + loopImports [] done summarised = return ([], done, summarised) loopImports ((home_uid,mb_pkg, gwib) : ss) done summarised | Just summs <- M.lookup cache_key summarised = case summs of [Right ms] -> do let nk = NodeKey_Module (msKey ms) - (rest, pkgs, summarised', done') <- loopImports ss done summarised - return (nk: rest, pkgs, summarised', done') + (rest, summarised', done') <- loopImports ss done summarised + return (nk: rest, summarised', done') [Left _err] -> loopImports ss done summarised _errs -> do @@ -1715,69 +1714,77 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots Nothing excl_mods case mb_s of NotThere -> loopImports ss done summarised - External uid -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (other_deps, Set.insert (homeUnitId home_unit, uid) pkgs, done', summarised') + External _ -> do + (other_deps, done', summarised') <- loopImports ss done summarised + return (other_deps, done', summarised') FoundInstantiation iud -> do - (other_deps, pkgs, done', summarised') <- loopImports ss done summarised - return (NodeKey_Unit iud : other_deps, pkgs, done', summarised') + (other_deps, done', summarised') <- loopImports ss done summarised + return (NodeKey_Unit iud : other_deps, done', summarised') FoundHomeWithError (_uid, e) -> loopImports ss done (Map.insert cache_key [(Left e)] summarised) FoundHome s -> do - (done', pkgs1, summarised') <- - loopSummaries [s] (done, Set.empty, Map.insert cache_key [Right s] summarised) - (other_deps, pkgs2, final_done, final_summarised) <- loopImports ss done' summarised' + (done', summarised') <- + loopSummaries [s] (done, Map.insert cache_key [Right s] summarised) + (other_deps, final_done, final_summarised) <- loopImports ss done' summarised' -- MP: This assumes that we can only instantiate non home units, which is probably fair enough for now. - return (NodeKey_Module (msKey s) : other_deps, pkgs1 `Set.union` pkgs2, final_done, final_summarised) + return (NodeKey_Module (msKey s) : other_deps, final_done, final_summarised) where cache_key = (home_uid, mb_pkg, unLoc <$> gwib) home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod --- This function checks then important property that if both p and q are home units +-- | This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] --- Fast path, trivially closed. -checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] - | otherwise = - let res = foldMap loop home_imp_ids - -- Now check whether everything which transitively depends on a home_unit is actually a home_unit - -- These units are the ones which we need to load as home packages but failed to do for some reason, - -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids - then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] - +-- +-- See Note [Multiple Home Units], section 'Closure Property'. +checkHomeUnitsClosed :: UnitEnv -> [DriverMessages] +checkHomeUnitsClosed ue + | Set.null bad_unit_ids = [] + | otherwise = [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] where + home_id_set = unitEnv_keys $ ue_home_unit_graph ue + bad_unit_ids = upwards_closure Set.\\ home_id_set rootLoc = mkGeneralSrcSpan (fsLit "") - -- TODO: This could repeat quite a bit of work but I struggled to write this function. - -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit - loop (from_uid, uid) = - let us = ue_findHomeUnitEnv from_uid ue in - let um = unitInfoMap (homeUnitEnv_units us) in - case lookupUniqMap um uid of - Nothing -> pprPanic "uid not found" (ppr uid) - Just ui -> - let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set - in - -- Case 1: The unit directly depends on a home_id - if not (null home_depends) - then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res - -- Case 2: Check the rest of the dependencies, and then see if any of them depended on - else - let res = foldMap (loop . (from_uid,)) other_depends - in - if not (Set.null res) - then Set.insert uid res - else res + + graph :: Graph (Node UnitId UnitId) + graph = graphFromEdgedVerticesUniq graphNodes + + -- downwards closure of graph + downwards_closure + = graphFromEdgedVerticesUniq [ DigraphNode uid uid (Set.toList deps) + | (uid, deps) <- M.toList (allReachable graph node_key)] + + inverse_closure = transposeG downwards_closure + + upwards_closure = Set.fromList $ map node_key $ reachablesG inverse_closure [DigraphNode uid uid [] | uid <- Set.toList home_id_set] + + all_unit_direct_deps :: UniqMap UnitId (Set.Set UnitId) + all_unit_direct_deps + = unitEnv_foldWithKey go emptyUniqMap $ ue_home_unit_graph ue + where + go rest this this_uis = + plusUniqMap_C Set.union + (addToUniqMap_C Set.union external_depends this (Set.fromList $ this_deps)) + rest + where + external_depends = mapUniqMap (Set.fromList . unitDepends) (unitInfoMap this_units) + this_units = homeUnitEnv_units this_uis + this_deps = [ toUnitId unit | (unit,Just _) <- explicitUnits this_units] + + graphNodes :: [Node UnitId UnitId] + graphNodes = go Set.empty home_id_set + where + go done todo + = case Set.minView todo of + Nothing -> [] + Just (uid, todo') + | Set.member uid done -> go done todo' + | otherwise -> case lookupUniqMap all_unit_direct_deps uid of + Nothing -> pprPanic "uid not found" (ppr (uid, all_unit_direct_deps)) + Just depends -> + let todo'' = (depends Set.\\ done) `Set.union` todo' + in DigraphNode uid uid (Set.toList depends) : go (Set.insert uid done) todo'' -- | Update the every ModSummary that is depended on -- by a module that needs template haskell. We enable codegen to ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile ===================================== @@ -0,0 +1,23 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +SETUP=../Setup -v0 + +mhu-perf: clean + $(MAKE) -s --no-print-directory clean + ./genLargeHMU + '$(GHC_PKG)' init tmp.d + '$(TEST_HC)' $(TEST_HC_OPTS) -v0 --make Setup + for dir in unit-p*; do \ + cd $$dir && $(SETUP) clean && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --ipid=$$dir-0.1.0.0 --with-ghc='$(TEST_HC)' --with-hc-pkg='$(GHC_PKG)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d && $(SETUP) build && $(SETUP) register --inplace && cd ..; \ + done; + + +ifeq "$(CLEANUP)" "1" + $(MAKE) -s --no-print-directory clean +endif + +clean : + $(RM) -r unitTop* unit-p* top*/ tmp*.d inst-* *.o *.hi */*.o */*.hi */Setup$(exeext) */dist Setup$(exeext) + ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs ===================================== @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -0,0 +1,10 @@ +test('mhu-perf', + [ collect_compiler_stats('bytes allocated',2), + extra_files(['genLargeHMU','Setup.hs']), + pre_cmd('$MAKE -s --no-print-directory mhu-perf'), + js_broken(22349), + when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests + compile_timeout_multiplier(5) + ], + multiunit_compile, + [['unitTop1', 'unitTop2'], '-fhide-source-paths']) ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU ===================================== @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of packages with $WIDTH modules on each layer +# Every package on layer N depends on all the packages on layer N-1 +# unitTop imports all the units from the last layer +DEPTH=8 +WIDTH=8 +for i in $(seq -w 1 $WIDTH); do + mkdir unit-p0M$i + echo "module DummyLevel0M$i where" > unit-p0M$i/DummyLevel0M$i.hs; + cat > unit-p0M$i/unit-p0M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel0M$i + build-depends: base +EOF +done +for l in $(seq 1 $DEPTH); do + for i in $(seq -w 1 $WIDTH); do + mkdir unit-p${l}M$i + cat > unit-p${l}M$i/unit-p${l}M$i.cabal <=1.10 +library + default-language: Haskell2010 + exposed-modules: DummyLevel${l}M$i + build-depends: base +EOF + echo "module DummyLevel${l}M$i where" > unit-p${l}M$i/DummyLevel${l}M$i.hs; + for j in $(seq -w 1 $WIDTH); do + echo " , unit-p$((l-1))M$j" >> unit-p${l}M$i/unit-p${l}M$i.cabal + echo "import DummyLevel$((l-1))M$j" >> unit-p${l}M$i/DummyLevel${l}M$i.hs; + done + done +done +mkdir top1 +echo "module Top1 where" > top1/Top1.hs +echo "-package-db ./tmp.d -i -itop1 Top1 -this-unit-id unit-top1 -package base" > unitTop1; +for j in $(seq -w 1 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop1; + echo "import DummyLevel${DEPTH}M$j" >> top1/Top1.hs; +done +mkdir top2 +echo "module Top2 where" > top2/Top2.hs +echo "-package-db ./tmp.d -i -itop2 Top2 -this-unit-id unit-top2 -package base" > unitTop2; +for j in $(seq -w 2 $WIDTH); do + echo "-package unit-p${DEPTH}M$j" >> unitTop2; + echo "import DummyLevel${DEPTH}M$j" >> top2/Top2.hs; +done ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr ===================================== @@ -0,0 +1,2 @@ +[1 of 2] Compiling Top1[unit-top1] +[2 of 2] Compiling Top2[unit-top2] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a933aff37992ea311a60be878379e7abf650e9fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a933aff37992ea311a60be878379e7abf650e9fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:20:22 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:20:22 -0400 Subject: [Git][ghc/ghc][master] RTS: Emit warning when -M < -H Message-ID: <6619270698ad5_37df3c6bc4981108e6@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - 1 changed file: - rts/RtsFlags.c Changes: ===================================== rts/RtsFlags.c ===================================== @@ -1959,6 +1959,9 @@ static void normaliseRtsOpts (void) if (RtsFlags.GcFlags.maxHeapSize != 0 && RtsFlags.GcFlags.heapSizeSuggestion > RtsFlags.GcFlags.maxHeapSize) { + errorBelch("Maximum heap size (-M) is smaller than suggested heap size (-H)\n" + "Setting maximum heap size to suggested heap size ( %" FMT_Word64 " )", + (StgWord64) RtsFlags.GcFlags.maxHeapSize * (StgWord64) BLOCK_SIZE); RtsFlags.GcFlags.maxHeapSize = RtsFlags.GcFlags.heapSizeSuggestion; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/23c3e624fbb9089d96ff33d043b157e4edd43a79 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/23c3e624fbb9089d96ff33d043b157e4edd43a79 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:20:26 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:20:26 -0400 Subject: [Git][ghc/ghc][master] testsuite: Add broken test for CApiFFI with -fprefer-bytecode Message-ID: <6619270a1e459_37df3c61fa80112031@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - 6 changed files: - + testsuite/tests/bytecode/T24634/Hello.hs - + testsuite/tests/bytecode/T24634/Main.hs - + testsuite/tests/bytecode/T24634/Makefile - + testsuite/tests/bytecode/T24634/all.T - + testsuite/tests/bytecode/T24634/hello.c - + testsuite/tests/bytecode/T24634/hello.h Changes: ===================================== testsuite/tests/bytecode/T24634/Hello.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE CApiFFI #-} +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE TemplateHaskell #-} + +module Hello where + +import Language.Haskell.TH +import Language.Haskell.TH.Syntax + +foreign import capi "hello.h say_hello" say_hello :: IO Int + +mkHello :: DecsQ +mkHello = do + n <- runIO say_hello + [d| hello :: IO Int + hello = return $(lift n) |] ===================================== testsuite/tests/bytecode/T24634/Main.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Hello + +$(mkHello) + +main :: IO () +main = hello >>= print ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +bytecode-capi: + $(TEST_HC) -c hello.c + $(TEST_HC) -c -fbyte-code-and-object-code Hello.hs + $(TEST_HC) -fprefer-byte-code hello.o Main.hs + ./Main ===================================== testsuite/tests/bytecode/T24634/all.T ===================================== @@ -0,0 +1,7 @@ +test('T24634', + [extra_files(['hello.h', 'hello.c', 'Hello.hs', 'Main.hs']), + req_interp, + expect_broken(24634), + ], + makefile_test, + ['']) ===================================== testsuite/tests/bytecode/T24634/hello.c ===================================== @@ -0,0 +1,5 @@ +#include "hello.h" + +int say_hello() { + return 42; +} ===================================== testsuite/tests/bytecode/T24634/hello.h ===================================== @@ -0,0 +1 @@ +int say_hello(void); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d23afb8c63d22af310b3c19f7c311934d02e3a31 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d23afb8c63d22af310b3c19f7c311934d02e3a31 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:21:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:21:06 -0400 Subject: [Git][ghc/ghc][master] base: Deprecate GHC.Pack Message-ID: <66192732c474c_37df3c61d988115518@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 2 changed files: - libraries/base/changelog.md - libraries/base/src/GHC/Pack.hs Changes: ===================================== libraries/base/changelog.md ===================================== @@ -4,6 +4,7 @@ * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* + * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) * Export `foldl'` from `Prelude` ([CLC proposal #167](https://github.com/haskell/core-libraries-committee/issues/167)) * The top-level handler for uncaught exceptions now displays the output of `displayException` rather than `show` ([CLC proposal #198](https://github.com/haskell/core-libraries-committee/issues/198)) * Add `permutations` and `permutations1` to `Data.List.NonEmpty` ([CLC proposal #68](https://github.com/haskell/core-libraries-committee/issues/68)) ===================================== libraries/base/src/GHC/Pack.hs ===================================== @@ -25,6 +25,7 @@ -- module GHC.Pack + {-# DEPRECATED "The exports of this module should be instead imported from GHC.Exts" #-} (packCString#, unpackCString, unpackCString#, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4bb3a5116e7d3061e988041643d5d1742fc395f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4bb3a5116e7d3061e988041643d5d1742fc395f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:21:37 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:21:37 -0400 Subject: [Git][ghc/ghc][master] ghc-internal: Fix mentions of ghc-internal in deprecation warnings Message-ID: <66192751ee612_37df3c88b6841184b5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - 2 changed files: - libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs - libraries/ghc-internal/src/GHC/Internal/List.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs ===================================== @@ -75,4 +75,4 @@ throwIfNull = throwIf (== nullPtr) . const -- void :: IO a -> IO () void act = act >> return () -{-# DEPRECATED void "use 'GHC.Internal.Control.Monad.void' instead" #-} -- deprecated in 7.6 +{-# DEPRECATED void "use 'Control.Monad.void' instead" #-} -- deprecated in 7.6 ===================================== libraries/ghc-internal/src/GHC/Internal/List.hs ===================================== @@ -90,7 +90,7 @@ head (x:_) = x head [] = badHead {-# NOINLINE [1] head #-} -{-# WARNING in "x-partial" head "This is a partial function, it throws an error on empty lists. Use pattern matching, 'GHC.Internal.Data.List.uncons' or 'GHC.Internal.Data.Maybe.listToMaybe' instead. Consider refactoring to use \"Data.List.NonEmpty\"." #-} +{-# WARNING in "x-partial" head "This is a partial function, it throws an error on empty lists. Use pattern matching, 'Data.List.uncons' or 'Data.Maybe.listToMaybe' instead. Consider refactoring to use \"Data.List.NonEmpty\"." #-} badHead :: HasCallStack => a badHead = errorEmptyList "head" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55eb8c98895308d2dd025f7bd64c0b80fce6ace3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55eb8c98895308d2dd025f7bd64c0b80fce6ace3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:22:37 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:22:37 -0400 Subject: [Git][ghc/ghc][master] rts: Implement set_initial_registers for AArch64 Message-ID: <6619278d11125_37df3cb8e9801273b3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 1 changed file: - rts/Libdw.c Changes: ===================================== rts/Libdw.c ===================================== @@ -285,6 +285,9 @@ static bool memory_read(Dwfl *dwfl STG_UNUSED, Dwarf_Addr addr, return true; } +// This function should persist the current machine state and call +// dwfl_thread_state_registers. The register numbering should match +// that defined by the platform's DWARF specification. static bool set_initial_registers(Dwfl_Thread *thread, void *arg); #if defined(x86_64_HOST_ARCH) @@ -315,6 +318,53 @@ static bool set_initial_registers(Dwfl_Thread *thread, ); return dwfl_thread_state_registers(thread, 0, 17, regs); } +#elif defined(aarch64_HOST_ARCH) +// See https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst +static bool set_initial_registers(Dwfl_Thread *thread, + void *arg STG_UNUSED) { + Dwarf_Word regs[33] = {}; + __asm__ ("str x0, [%0, 0x000]\n\t" + "str x1, [%0, 0x008]\n\t" + "str x2, [%0, 0x010]\n\t" + "str x3, [%0, 0x018]\n\t" + "str x4, [%0, 0x020]\n\t" + "str x5, [%0, 0x028]\n\t" + "str x6, [%0, 0x030]\n\t" + "str x7, [%0, 0x038]\n\t" + "str x8, [%0, 0x040]\n\t" + "str x9, [%0, 0x048]\n\t" + "str x10, [%0, 0x050]\n\t" + "str x11, [%0, 0x058]\n\t" + "str x12, [%0, 0x060]\n\t" + "str x13, [%0, 0x068]\n\t" + "str x14, [%0, 0x070]\n\t" + "str x15, [%0, 0x078]\n\t" + "str x16, [%0, 0x080]\n\t" + "str x17, [%0, 0x088]\n\t" + "str x18, [%0, 0x090]\n\t" + "str x19, [%0, 0x098]\n\t" + "str x20, [%0, 0x0a0]\n\t" + "str x21, [%0, 0x0a8]\n\t" + "str x22, [%0, 0x0b0]\n\t" + "str x23, [%0, 0x0b8]\n\t" + "str x24, [%0, 0x0c0]\n\t" + "str x25, [%0, 0x0c8]\n\t" + "str x26, [%0, 0x0d0]\n\t" + "str x27, [%0, 0x0d8]\n\t" + "str x28, [%0, 0x0e0]\n\t" + "str x29, [%0, 0x0e8]\n\t" + "str x30, [%0, 0x0f0]\n\t" + "mov x1, sp\n\t" + "str x1, [%0, 0x0f8]\n\t" + ".here:\n\t" + "adr x1, .here\n\t" + "str x1, [%0, 0x100]\n\t" + : /* no output */ + :"r" (®s[0]) /* input */ + :"x1" /* clobbered */ + ); + return dwfl_thread_state_registers(thread, 0, 33, regs); +} #elif defined(i386_HOST_ARCH) static bool set_initial_registers(Dwfl_Thread *thread, void *arg STG_UNUSED) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0fbd181207c9f3614eca7bc3156ea2b6372a941 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0fbd181207c9f3614eca7bc3156ea2b6372a941 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:23:22 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:23:22 -0400 Subject: [Git][ghc/ghc][master] ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Message-ID: <661927ba4ceb4_37df3cb8e9801320ba@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 1 changed file: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -216,7 +216,8 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , ">= 11": deb11 , "unknown_versioning": deb11 } , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 - , "( >= 16 && < 19 )": ubuntu1804 + , "( >= 16 && < 18 )": deb9 + , "( >= 18 && < 19 )": ubuntu1804 } , "Linux_Mint" : { "< 20": ubuntu1804 , ">= 20": ubuntu2004 } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14c9ec62f842cc28057d8a6089fdeaa634dca2e1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14c9ec62f842cc28057d8a6089fdeaa634dca2e1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:23:50 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:23:50 -0400 Subject: [Git][ghc/ghc][master] Bump unix submodule to 2.8.5.1 Message-ID: <661927d6dd458_37df3cb1604813228f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - 1 changed file: - libraries/unix Changes: ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35a1621e3b14e476a6c34b343a7f0b6b44db0183 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35a1621e3b14e476a6c34b343a7f0b6b44db0183 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:24:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:24:14 -0400 Subject: [Git][ghc/ghc][master] Correct default -funfolding-use-threshold in docs Message-ID: <661927eeafd6_37df3c1095e1013386d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 1 changed file: - docs/users_guide/using-optimisation.rst Changes: ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1626,7 +1626,7 @@ as such you shouldn't need to set any of them explicitly. A flag :ghc-flag:`-funfolding-use-threshold=⟨n⟩`. .. ghc-flag:: -funfolding-use-threshold=⟨n⟩ - :shortdesc: *default: 80.* Tweak unfolding settings. + :shortdesc: *default: 90.* Tweak unfolding settings. :type: dynamic :category: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c24df0e6af4a545921ea783dc54d4ea07f1f03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c24df0e6af4a545921ea783dc54d4ea07f1f03 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 12:24:30 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 08:24:30 -0400 Subject: [Git][ghc/ghc][master] FastString is a __Modified__ UTF-8 Message-ID: <661927fe91939_37df3cff661c135573@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - 3 changed files: - compiler/GHC/Data/FastString.hs - libraries/ghc-boot/GHC/Data/ShortText.hs - libraries/ghc-boot/GHC/Utils/Encoding/UTF8.hs Changes: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -198,8 +198,8 @@ mkFastZStringString str = FastZString (BSC.pack str) -- ----------------------------------------------------------------------------- -{-| A 'FastString' is a UTF-8 encoded string together with a unique ID. All -'FastString's are stored in a global hashtable to support fast O(1) +{-| A 'FastString' is a Modified UTF-8 encoded string together with a unique ID. +All 'FastString's are stored in a global hashtable to support fast O(1) comparison. It is also associated with a lazy reference to the Z-encoding ===================================== libraries/ghc-boot/GHC/Data/ShortText.hs ===================================== @@ -24,6 +24,10 @@ -- Very similar to FastString, but not hash-consed and with some extra instances and -- functions for serialisation and I/O. Should be imported qualified. +-- +-- /Note:/ This string is stored in Modified UTF8 format, +-- thus it's not byte-compatible with @ShortText@ type in @text-short@ +-- package. module GHC.Data.ShortText ( -- * ShortText ===================================== libraries/ghc-boot/GHC/Utils/Encoding/UTF8.hs ===================================== @@ -7,7 +7,7 @@ -- of the package database (needed in both ghc and in ghc-pkg) lives in -- `ghc-boot` and uses ShortText, which in turn depends on this module. --- | Simple, non-streaming UTF-8 codecs. +-- | Simple, non-streaming Modified UTF-8 codecs. -- -- This is one of several UTF-8 implementations provided by GHC; see Note -- [GHC's many UTF-8 implementations] in "GHC.Encoding.UTF8" for an View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0255d03c302c1b83367edae169fee0b4a4306965 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0255d03c302c1b83367edae169fee0b4a4306965 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 13:38:09 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 12 Apr 2024 09:38:09 -0400 Subject: [Git][ghc/ghc][wip/T24651] wip Message-ID: <661939418788e_37df3c1b0c5ec139310@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: 26f934db by Teo Camarasu at 2024-04-12T14:21:21+01:00 wip - - - - - 2 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -584,6 +584,7 @@ doc-tarball: exit 1 fi - rm -Rf docs + - rm -R libraries - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST - ls -lh - mv docs/*.tar.xz docs/index.html . ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,8 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +ls -alh +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26f934db1f5952bca70710e26ea055c1dfe05ed4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26f934db1f5952bca70710e26ea055c1dfe05ed4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 14:23:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 10:23:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: users-guide: Clarify language extension documentation Message-ID: <661943f8bce7b_15979f1ac3907135a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - ef2217e3 by Matthew Pickering at 2024-04-12T10:23:37-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 58bfbeb7 by Simon Peyton Jones at 2024-04-12T10:23:38-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/exts/applicative_do.rst - docs/users_guide/exts/arrows.rst - docs/users_guide/exts/binary_literals.rst - docs/users_guide/exts/constrained_class_methods.rst - docs/users_guide/exts/constraint_kind.rst - docs/users_guide/exts/data_kinds.rst - docs/users_guide/exts/default_signatures.rst - docs/users_guide/exts/derive_any_class.rst - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/deriving_strategies.rst - docs/users_guide/exts/deriving_via.rst - docs/users_guide/exts/disambiguate_record_fields.rst - docs/users_guide/exts/empty_case.rst - docs/users_guide/exts/existential_quantification.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/field_selectors.rst - docs/users_guide/exts/functional_dependencies.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/gadt_syntax.rst - docs/users_guide/exts/generalised_list_comprehensions.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9811d9e02c922046b6c7395aa643109f0ca2ebc...58bfbeb7ccdc9d485c3c4d722f03fe0af742b841 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9811d9e02c922046b6c7395aa643109f0ca2ebc...58bfbeb7ccdc9d485c3c4d722f03fe0af742b841 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 14:52:24 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 12 Apr 2024 10:52:24 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Add bogus import to (attempt to) evade #24436 Message-ID: <66194aa838c40_15979f59648880156@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 8bfd4ae4 by Simon Peyton Jones at 2024-04-12T15:51:54+01:00 Add bogus import to (attempt to) evade #24436 - - - - - 1 changed file: - libraries/base/src/GHC/IO/Encoding/Iconv.hs Changes: ===================================== libraries/base/src/GHC/IO/Encoding/Iconv.hs ===================================== @@ -24,6 +24,8 @@ module GHC.IO.Encoding.Iconv import GHC.Internal.IO.Encoding.Iconv +import GHC.Types () -- Bogus import to attempt to avoid #24436 + #else ( ) where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bfd4ae4e616c374fe4981a5a61bfb9f9a51621f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bfd4ae4e616c374fe4981a5a61bfb9f9a51621f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 15:18:16 2024 From: gitlab at gitlab.haskell.org (Torsten Schmits (@torsten.schmits)) Date: Fri, 12 Apr 2024 11:18:16 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/torsten.schmits/modlocation-ospath Message-ID: <661950b8b88a4_15979f8e84b08817d@gitlab.mail> Torsten Schmits pushed new branch wip/torsten.schmits/modlocation-ospath at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/torsten.schmits/modlocation-ospath You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 16:33:51 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 12:33:51 -0400 Subject: [Git][ghc/ghc][wip/T24528] 2 commits: Bump terminfo submodule to current master Message-ID: <6619626fc4777_15979f118311097624@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: 9d5b60db by Ben Gamari at 2024-04-12T12:01:13-04:00 Bump terminfo submodule to current master - - - - - 252e53d2 by Ben Gamari at 2024-04-12T12:01:34-04:00 Bump parsec submodule - - - - - 2 changed files: - libraries/parsec - libraries/terminfo Changes: ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit cc1b149fecfa145a5e3fba292927c5c572fb38ce View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bae9951543fa5a3aa7f338dacb257626e38e6a14...252e53d258d359534e3a6c034a931eebdb918de6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bae9951543fa5a3aa7f338dacb257626e38e6a14...252e53d258d359534e3a6c034a931eebdb918de6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 16:34:17 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 12:34:17 -0400 Subject: [Git][ghc/ghc][wip/bump-time] Bump time submodule to 1.12.1 Message-ID: <6619628948fee_15979f1219d0498126@gitlab.mail> Ben Gamari pushed to branch wip/bump-time at Glasgow Haskell Compiler / GHC Commits: ef516c80 by Ben Gamari at 2024-04-12T12:32:52-04:00 Bump time submodule to 1.12.1 - - - - - 6 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -66,7 +66,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.12, binary == 0.8.*, - time >= 1.4 && < 1.12, + time >= 1.4 && < 1.13, containers >= 0.6.2.1 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -68,7 +68,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.12 + time >= 1.8 && < 1.13 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit d638e33dbc056048b393964286c7fe394b2730d7 +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit adb8b4d67356c4eca92f62fd1b7c1ac8add4241c +Subproject commit f0da64307959fcd2225c01f97df851ff45285e68 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 3648cd63d10e301f3f596efdcb1427a6a6a96cf9 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit df292e1a74c6a87c2c1c889679074dd46ad39461 +Subproject commit caa9ecb3a79cf4d952d9c357ed5aa428aa4adb26 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef516c80c500df1c026363e5fa30be95df3e6a48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef516c80c500df1c026363e5fa30be95df3e6a48 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 16:35:33 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Fri, 12 Apr 2024 12:35:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/newline-after-error Message-ID: <661962d588bec_15979f127fbf4983cc@gitlab.mail> Jade pushed new branch wip/newline-after-error at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/newline-after-error You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 16:37:22 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 12:37:22 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 4 commits: Bump parsec submodule to upstream master Message-ID: <661963423ca91_15979f13619f098717@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 2d1c6074 by Ben Gamari at 2024-04-12T10:27:25-04:00 Bump parsec submodule to upstream master - - - - - 6efe55ef by Ben Gamari at 2024-04-12T10:27:27-04:00 testsuite: More aggressive normalisation of process004 output It turns out that this test uses `execvp`, not `exec` on CentOS 7. Normalise this spurious difference away. - - - - - 702ff84e by Ben Gamari at 2024-04-12T11:35:06-04:00 Bump array, binary, stm submodules - - - - - 51fe02fd by Ben Gamari at 2024-04-12T12:33:35-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 12 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/array - libraries/binary - libraries/directory - libraries/hpc - libraries/parsec - libraries/stm - libraries/time - testsuite/tests/process/all.T Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -30,6 +30,7 @@ extra_dependencies = ,dep (containers, "Data.Set.Internal") th_internal ,dep (containers, "Data.Sequence.Internal") th_internal ,dep (containers, "Data.Graph") th_internal + ,dep (time, "Data.Time.Clock.Internal.UniversalTime") th_internal ])) ] ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit 510456786715d96dfc9e9bc4cead9aace1ce2db6 +Subproject commit a65f8a5e7c26fe9b8012b90cbbff8866f8d39113 ===================================== libraries/binary ===================================== @@ -1 +1 @@ -Subproject commit b30971d569e934cd54d08c45c7e906cfe8af3709 +Subproject commit a501955f7ab48da81d732958c8834caaa3e470b6 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 0736c51d0b39a9852cd39259af4cfaf6cafe36a3 +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit b77afda28b60f526ebb4be436240afd6ca956673 +Subproject commit ff8f8ceeceb14ac59accd53dd82a5d32c7e08626 ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f ===================================== testsuite/tests/process/all.T ===================================== @@ -1,6 +1,10 @@ -# some platforms use spawnp instead of exec in some cases, resulting +# some platforms use spawnp or execvp instead of exec in some cases, resulting # in spurious error output changes. -normalise_exec = normalise_fun(lambda s: s.replace('posix_spawnp', 'exec')) +normalise_exec = normalise_fun( + lambda s: s.replace('posix_spawnp', 'exec'), + lambda s: s.replace('execvp', 'exec'), + lambda s: s.replace('execvpe', 'exec'), +) test('process001', [req_process], compile_and_run, ['']) test('process002', [fragile_for(16547, concurrent_ways), req_process], compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4cf82155ab7ed13249681a2fdf5a88dc93bf1e0b...51fe02fd96f9ca4da959fc3294ea1fc4e7baaff9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4cf82155ab7ed13249681a2fdf5a88dc93bf1e0b...51fe02fd96f9ca4da959fc3294ea1fc4e7baaff9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 16:56:48 2024 From: gitlab at gitlab.haskell.org (Torsten Schmits (@torsten.schmits)) Date: Fri, 12 Apr 2024 12:56:48 -0400 Subject: [Git][ghc/ghc][wip/torsten.schmits/modlocation-ospath] use OsPath in ModLocation Message-ID: <661967d050762_15979f17bcb1c10060@gitlab.mail> Torsten Schmits pushed to branch wip/torsten.schmits/modlocation-ospath at Glasgow Haskell Compiler / GHC Commits: bba242d9 by Torsten Schmits at 2024-04-12T18:56:30+02:00 use OsPath in ModLocation submodule change: haddock - - - - - 17 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/Location.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Utils/Misc.hs - ghc/GHCi/UI.hs - ghc/GHCi/UI/Info.hs - utils/haddock Changes: ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -771,7 +771,7 @@ summariseRequirement pn mod_name = do let fopts = initFinderOpts dflags let PackageName pn_fs = pn - let location = mkHomeModLocation2 fopts mod_name + location <- liftIO $ mkHomeModLocation2 fopts mod_name (unpackFS pn_fs moduleNameSlashes mod_name) "hsig" env <- getBkpEnv @@ -854,7 +854,7 @@ hsModuleToModSummary home_keys pn hsc_src modname -- To add insult to injury, we don't even actually use -- these filenames to figure out where the hi files go. -- A travesty! - let location0 = mkHomeModLocation2 fopts modname + location0 <- liftIO $ mkHomeModLocation2 fopts modname (unpackFS unit_fs moduleNameSlashes modname) (case hsc_src of ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -279,6 +279,8 @@ import Control.Monad import Data.IORef import System.FilePath as FilePath import System.Directory +import qualified System.Directory.OsPath as OsPath +import qualified System.OsPath as OsPath import qualified Data.Map as M import Data.Map (Map) import qualified Data.Set as S @@ -611,7 +613,7 @@ extract_renamed_stuff mod_summary tc_result = do -- I assume this fromJust is safe because `-fwrite-hie-file` -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) - let out_file = ml_hie_file $ ms_location mod_summary + out_file <- liftIO $ msHieFilePath mod_summary liftIO $ writeHieFile out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) @@ -937,7 +939,9 @@ checkObjects dflags mb_old_linkable summary = do Just old_linkable | isObjectLinkable old_linkable, linkableTime old_linkable == obj_date -> return $ UpToDateItem old_linkable - _ -> UpToDateItem <$> findObjectLinkable this_mod obj_fn obj_date + _ -> do + file <- OsPath.decodeFS obj_fn + UpToDateItem <$> findObjectLinkable this_mod file obj_date _ -> return $ outOfDateItemBecause MissingObjectFile Nothing -- | Check to see if we can reuse the old linkable, by this point we will @@ -1202,12 +1206,13 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do write_iface dflags' iface = let !iface_name = if dynamicNow dflags' then ml_dyn_hi_file mod_location else ml_hi_file mod_location profile = targetProfile dflags' - in - {-# SCC "writeIface" #-} - withTiming logger - (text "WriteIface"<+>brackets (text iface_name)) - (const ()) - (writeIface logger profile iface_name iface) + in do + path <- OsPath.decodeFS iface_name + {-# SCC "writeIface" #-} + withTiming logger + (text "WriteIface"<+>brackets (text path)) + (const ()) + (writeIface logger profile path iface) if (write_interface || force_write_interface) then do @@ -1262,8 +1267,9 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do -- existence just in case, so that we don't accidentally create empty -- .hie files. let hie_file = ml_hie_file mod_location - whenM (doesFileExist hie_file) $ - GHC.Utils.Touch.touch hie_file + whenM (OsPath.doesFileExist hie_file) $ do + path <- OsPath.decodeFS hie_file + GHC.Utils.Touch.touch path else -- See Note [Strictness in ModIface] forceModIface iface ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -123,6 +123,7 @@ import Data.List (sortOn) import Data.Bifunctor (first) import System.Directory import System.FilePath +import qualified System.OsPath as OsPath import System.IO ( fixIO ) import GHC.Conc ( getNumProcessors, getNumCapabilities, setNumCapabilities ) @@ -1830,7 +1831,9 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = tn <- newTempName logger tmpfs (tmpDir dflags) staticLife suf let dyn_tn = tn -<.> dynsuf addFilesToClean tmpfs dynLife [dyn_tn] - return (tn, dyn_tn) + tn_os <- OsPath.encodeFS tn + dyn_tn_os <- OsPath.encodeFS dyn_tn + return (tn_os, dyn_tn_os) -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in -- the ModSummary with temporary files. @@ -2037,7 +2040,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf let fopts = initFinderOpts (hsc_dflags hsc_env) -- Make a ModLocation for this file - let location = mkHomeModLocation fopts pi_mod_name src_fn + location <- liftIO (mkHomeModLocation fopts pi_mod_name src_fn) -- Tell the Finder cache where it is, so that subsequent calls -- to findModule will find it, even if it's not on any search path ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -223,10 +223,10 @@ processDeps dflags _ _ _ _ (AcyclicSCC (InstantiationNode _uid node)) processDeps _dflags _ _ _ _ (AcyclicSCC (LinkNode {})) = return () processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode _ node)) - = do { let extra_suffixes = depSuffixes dflags + = do { obj_file <- msObjFilePath node + ; let extra_suffixes = depSuffixes dflags include_pkg_deps = depIncludePkgDeps dflags src_file = msHsFilePath node - obj_file = msObjFilePath node obj_files = insertSuffixes obj_file extra_suffixes do_imp loc is_boot pkg_qual imp_mod @@ -251,8 +251,8 @@ processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode _ node)) -- add dependency between objects and their corresponding .hi-boot -- files if the module has a corresponding .hs-boot file (#14482) ; when (isBootSummary node == IsBoot) $ do - let hi_boot = msHiFilePath node - let obj = removeBootSuffix (msObjFilePath node) + hi_boot <- msHiFilePath node + let obj = removeBootSuffix obj_file forM_ extra_suffixes $ \suff -> do let way_obj = insertSuffixes obj [suff] let way_hi_boot = insertSuffixes hi_boot [suff] @@ -297,7 +297,9 @@ findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do Found loc _ -- Home package: just depend on the .hi or hi-boot file | isJust (ml_hs_file loc) || include_pkg_deps - -> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc))) + -> do + hi_file <- mlHiFilePath loc + return (Just (addBootSuffix_maybe is_boot hi_file)) -- Not in this package: we don't need a dependency | otherwise ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -229,12 +229,12 @@ compileOne' mHscMessage debugTraceMsg logger 2 (text "compile: input file" <+> text input_fnpp) - unless (gopt Opt_KeepHiFiles lcl_dflags) $ - addFilesToClean tmpfs TFL_CurrentModule $ - [ml_hi_file $ ms_location summary] - unless (gopt Opt_KeepOFiles lcl_dflags) $ - addFilesToClean tmpfs TFL_GhcSession $ - [ml_obj_file $ ms_location summary] + unless (gopt Opt_KeepHiFiles lcl_dflags) $ do + file <- msHiFilePath summary + addFilesToClean tmpfs TFL_CurrentModule [file] + unless (gopt Opt_KeepOFiles lcl_dflags) $ do + file <- msObjFilePath summary + addFilesToClean tmpfs TFL_GhcSession [file] -- Initialise plugins here for any plugins enabled locally for a module. plugin_hsc_env <- initializePlugins hsc_env ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -48,6 +48,7 @@ import GHC.SysTools import GHC.SysTools.Cpp import System.Directory import System.FilePath +import qualified System.OsPath as OsPath import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Unit.Info @@ -526,8 +527,8 @@ runHscBackendPhase :: PipeEnv runHscBackendPhase pipe_env hsc_env mod_name src_flavour location result = do let dflags = hsc_dflags hsc_env logger = hsc_logger hsc_env - o_file = if dynamicNow dflags then ml_dyn_obj_file location else ml_obj_file location -- The real object file next_phase = hscPostBackendPhase src_flavour (backend dflags) + o_file <- if dynamicNow dflags then mlDynObjFilePath location else mlObjFilePath location -- The real object file case result of HscUpdate iface -> if | not (backendGeneratesCode (backend dflags)) -> @@ -759,7 +760,7 @@ mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO Mod mkOneShotModLocation pipe_env dflags src_flavour mod_name = do let PipeEnv{ src_basename=basename, src_suffix=suff } = pipe_env - let location1 = mkHomeModLocation2 fopts mod_name basename suff + location1 <- mkHomeModLocation2 fopts mod_name basename suff -- Boot-ify it if necessary let location2 @@ -770,12 +771,12 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- Take -ohi into account if present -- This can't be done in mkHomeModuleLocation because -- it only applies to the module being compiles - let ohi = outputHi dflags - location3 | Just fn <- ohi = location2{ ml_hi_file = fn } + ohi <- traverse OsPath.encodeFS (outputHi dflags) + let location3 | Just fn <- ohi = location2{ ml_hi_file = fn } | otherwise = location2 - let dynohi = dynOutputHi dflags - location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } + dynohi <- traverse OsPath.encodeFS (dynOutputHi dflags) + let location4 | Just fn <- dynohi = location3{ ml_dyn_hi_file = fn } | otherwise = location3 -- Take -o into account if present @@ -784,10 +785,11 @@ mkOneShotModLocation pipe_env dflags src_flavour mod_name = do -- the object file for one module.) -- Note the nasty duplication with the same computation in compileFile -- above - let expl_o_file = outputFile_ dflags - expl_dyn_o_file = dynOutputFile_ dflags - location5 | Just ofile <- expl_o_file - , let dyn_ofile = fromMaybe (ofile -<.> dynObjectSuf_ dflags) expl_dyn_o_file + expl_o_file <- traverse OsPath.encodeFS (outputFile_ dflags) + expl_dyn_o_file <- traverse OsPath.encodeFS (dynOutputFile_ dflags) + o_suf <- OsPath.encodeFS (dynObjectSuf_ dflags) + let location5 | Just ofile <- expl_o_file + , let dyn_ofile = fromMaybe (ofile OsPath.-<.> o_suf) expl_dyn_o_file , isNoLink (ghcLink dflags) = location4 { ml_obj_file = ofile , ml_dyn_obj_file = dyn_ofile } @@ -867,8 +869,8 @@ getOutputFilename logger tmpfs stop_phase output basename dflags next_phase mayb -- 1. If we are generating object files for a .hs file, then return the odir as the ModLocation -- will have been modified to point to the accurate locations | StopLn <- next_phase, Just loc <- maybe_location = - return $ if dynamicNow dflags then ml_dyn_obj_file loc - else ml_obj_file loc + OsPath.decodeFS $ if dynamicNow dflags then ml_dyn_obj_file loc + else ml_obj_file loc -- 2. If output style is persistent then | is_last_phase, Persistent <- output = persistent_fn -- 3. Specific file is only set when outputFile is set by -o ===================================== compiler/GHC/Iface/Errors/Ppr.hs ===================================== @@ -351,8 +351,8 @@ hiModuleNameMismatchWarn requested_mod read_mod dynamicHashMismatchError :: Module -> ModLocation -> SDoc dynamicHashMismatchError wanted_mod loc = vcat [ text "Dynamic hash doesn't match for" <+> quotes (ppr wanted_mod) - , text "Normal interface file from" <+> text (ml_hi_file loc) - , text "Dynamic interface file from" <+> text (ml_dyn_hi_file loc) + , text "Normal interface file from" <+> text (mlHiFilePathLenient loc) + , text "Dynamic interface file from" <+> text (mlDynHiFilePathLenient loc) , text "You probably need to recompile" <+> quotes (ppr wanted_mod) ] homeModError :: InstalledModule -> ModLocation -> SDoc ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -114,6 +114,7 @@ import Control.Monad import Data.Map ( toList ) import System.FilePath import System.Directory +import qualified System.OsPath as OsPath import GHC.Driver.Env.KnotVars import GHC.Iface.Errors.Types @@ -893,7 +894,8 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do , not (isOneShot (ghcMode dflags)) -> return (Failed (HomeModError mod loc)) _ -> do - r <- read_file logger name_cache unit_state dflags wanted_mod (ml_hi_file loc) + file <- OsPath.decodeFS (ml_hi_file loc) + r <- read_file logger name_cache unit_state dflags wanted_mod file case r of Failed err -> return (Failed $ BadIfaceFile err) @@ -928,7 +930,8 @@ load_dynamic_too :: Logger -> NameCache -> UnitState -> DynFlags -> Module -> ModIface -> ModLocation -> IO (MaybeErr MissingInterfaceError ()) load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc = do - read_file logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case + file <- OsPath.decodeFS (ml_dyn_hi_file loc) + read_file logger name_cache unit_state dflags wanted_mod file >>= \case Succeeded (dynIface, _) | mi_mod_hash (mi_final_exts iface) == mi_mod_hash (mi_final_exts dynIface) -> return (Succeeded ()) ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -287,7 +287,7 @@ check_old_iface hsc_env mod_summary maybe_iface trace_if logger (text "We already have the old interface for" <+> ppr (ms_mod mod_summary)) return maybe_iface - Nothing -> loadIface dflags (msHiFilePath mod_summary) + Nothing -> loadIface dflags =<< liftIO (msHiFilePath mod_summary) loadIface read_dflags iface_path = do let ncu = hsc_NC hsc_env @@ -312,7 +312,8 @@ check_old_iface hsc_env mod_summary maybe_iface res <- recomp_check case res of UpToDateItem _ -> do - maybe_dyn_iface <- liftIO $ loadIface (setDynamicNow dflags) (msDynHiFilePath mod_summary) + path <- liftIO $ msDynHiFilePath mod_summary + maybe_dyn_iface <- liftIO $ loadIface (setDynamicNow dflags) path case maybe_dyn_iface of Nothing -> return $ outOfDateItemBecause MissingDynHiFile Nothing Just dyn_iface | mi_iface_hash (mi_final_exts dyn_iface) ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -60,19 +60,22 @@ import GHC.Linker.Types import GHC.Types.PkgQual import GHC.Fingerprint -import Data.IORef -import System.Directory -import System.FilePath -import Control.Monad -import Data.Time -import qualified Data.Map as M import GHC.Driver.Env ( hsc_home_unit_maybe, HscEnv(hsc_FC, hsc_dflags, hsc_unit_env) ) import GHC.Driver.Config.Finder + +import Control.Monad +import Data.IORef +import qualified Data.Map as M import qualified Data.Set as Set +import Data.Time +import Data.Traversable (for) +import System.FilePath +import qualified System.Directory.OsPath as OsPath +import System.OsPath (OsPath) +import qualified System.OsPath as OsPath type FileExt = String -- Filename extension -type BaseName = String -- Basename of file -- ----------------------------------------------------------------------------- -- The Finder @@ -390,7 +393,6 @@ findHomePackageModule fc fopts home_unit mod_name = do fr_suggestions = [] } - -- | Implements the search for a module name in the home package only. Calling -- this function directly is usually *not* what you want; currently, it's used -- as a building block for the following operations: @@ -408,55 +410,56 @@ findHomePackageModule fc fopts home_unit mod_name = do -- 4. Some special-case code in GHCi (ToDo: Figure out why that needs to -- call this.) findInstalledHomeModule :: FinderCache -> FinderOpts -> UnitId -> ModuleName -> IO InstalledFindResult -findInstalledHomeModule fc fopts home_unit mod_name = do - homeSearchCache fc home_unit mod_name $ - let - maybe_working_dir = finder_workingDirectory fopts - home_path = case maybe_working_dir of - Nothing -> finder_importPaths fopts - Just fp -> augmentImports fp (finder_importPaths fopts) - hi_dir_path = - case finder_hiDir fopts of - Just hiDir -> case maybe_working_dir of - Nothing -> [hiDir] - Just fp -> [fp hiDir] +findInstalledHomeModule fc fopts home_unit mod_name = + homeSearchCache fc home_unit mod_name $ do + maybe_working_dir <- traverse OsPath.encodeFS (finder_workingDirectory fopts) + import_paths <- traverse OsPath.encodeFS (finder_importPaths fopts) + let + home_path = case maybe_working_dir of + Nothing -> import_paths + Just fp -> augmentImports fp import_paths + hiDir <- traverse OsPath.encodeFS (finder_hiDir fopts) + hisuf <- OsPath.encodeFS (finder_hiSuf fopts) + let + hi_dir_path = case hiDir of + Just hd -> case maybe_working_dir of + Nothing -> [hd] + Just fp -> [fp OsPath. hd] Nothing -> home_path - hisuf = finder_hiSuf fopts - mod = mkModule home_unit mod_name - - source_exts = - [ ("hs", mkHomeModLocationSearched fopts mod_name "hs") - , ("lhs", mkHomeModLocationSearched fopts mod_name "lhs") - , ("hsig", mkHomeModLocationSearched fopts mod_name "hsig") - , ("lhsig", mkHomeModLocationSearched fopts mod_name "lhsig") - ] - - -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that - -- when hiDir field is set in dflags, we know to look there (see #16500) - hi_exts = [ (hisuf, mkHomeModHiOnlyLocation fopts mod_name) - , (addBootSuffix hisuf, mkHomeModHiOnlyLocation fopts mod_name) - ] - - -- In compilation manager modes, we look for source files in the home - -- package because we can compile these automatically. In one-shot - -- compilation mode we look for .hi and .hi-boot files only. - (search_dirs, exts) - | finder_lookupHomeInterfaces fopts = (hi_dir_path, hi_exts) - | otherwise = (home_path, source_exts) - in - - -- special case for GHC.Prim; we won't find it in the filesystem. - -- This is important only when compiling the base package (where GHC.Prim - -- is a home module). - if mod `installedModuleEq` gHC_PRIM - then return (InstalledFound (error "GHC.Prim ModLocation") mod) - else searchPathExts search_dirs mod exts + + source_exts <- for ["hs", "lhs", "hsig", "lhsig"] $ \ ext -> do + ext' <- OsPath.encodeFS ext + pure (ext', mkHomeModLocationSearched fopts mod_name ext) + + let + mod = mkModule home_unit mod_name + + -- we use mkHomeModHiOnlyLocation instead of mkHiOnlyModLocation so that + -- when hiDir field is set in dflags, we know to look there (see #16500) + hi_exts = + [ (hisuf, mkHomeModHiOnlyLocation fopts mod_name) + , (addBootSuffixOsPath hisuf, mkHomeModHiOnlyLocation fopts mod_name) + ] + + -- In compilation manager modes, we look for source files in the home + -- package because we can compile these automatically. In one-shot + -- compilation mode we look for .hi and .hi-boot files only. + (search_dirs, exts) + | finder_lookupHomeInterfaces fopts = (hi_dir_path, hi_exts) + | otherwise = (home_path, source_exts) + + -- special case for GHC.Prim; we won't find it in the filesystem. + -- This is important only when compiling the base package (where GHC.Prim + -- is a home module). + if mod `installedModuleEq` gHC_PRIM + then return (InstalledFound (error "GHC.Prim ModLocation") mod) + else searchPathExts search_dirs mod exts -- | Prepend the working directory to the search path. -augmentImports :: FilePath -> [FilePath] -> [FilePath] +augmentImports :: OsPath -> [OsPath] -> [OsPath] augmentImports _work_dir [] = [] -augmentImports work_dir (fp:fps) | isAbsolute fp = fp : augmentImports work_dir fps - | otherwise = (work_dir fp) : augmentImports work_dir fps +augmentImports work_dir (fp:fps) | OsPath.isAbsolute fp = fp : augmentImports work_dir fps + | otherwise = (work_dir OsPath. fp) : augmentImports work_dir fps -- | Search for a module in external packages only. findPackageModule :: FinderCache -> UnitState -> FinderOpts -> InstalledModule -> IO InstalledFindResult @@ -482,70 +485,75 @@ findPackageModule_ fc fopts mod pkg_conf = do -- special case for GHC.Prim; we won't find it in the filesystem. if mod `installedModuleEq` gHC_PRIM then return (InstalledFound (error "GHC.Prim ModLocation") mod) - else + else do let tag = waysBuildTag (finder_ways fopts) -- hi-suffix for packages depends on the build tag. - package_hisuf | null tag = "hi" - | otherwise = tag ++ "_hi" - - package_dynhisuf = waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + package_hisuf <- OsPath.encodeFS $ if null tag then "hi" else tag ++ "_hi" + package_dynhisuf <- OsPath.encodeFS $ + waysBuildTag (addWay WayDyn (finder_ways fopts)) ++ "_hi" + let mk_hi_loc = mkHiOnlyModLocation fopts package_hisuf package_dynhisuf - - import_dirs = map ST.unpack $ unitImportDirs pkg_conf -- we never look for a .hi-boot file in an external package; -- .hi-boot files only make sense for the home package. - in + import_dirs <- traverse (OsPath.encodeFS . ST.unpack) $ unitImportDirs pkg_conf case import_dirs of - [one] | finder_bypassHiFileCheck fopts -> + [one] | finder_bypassHiFileCheck fopts -> do -- there's only one place that this .hi file can be, so -- don't bother looking for it. - let basename = moduleNameSlashes (moduleName mod) - loc = mk_hi_loc one basename - in return $ InstalledFound loc mod + basename <- OsPath.encodeFS (moduleNameSlashes (moduleName mod)) + loc <- mk_hi_loc one basename + return $ InstalledFound loc mod _otherwise -> searchPathExts import_dirs mod [(package_hisuf, mk_hi_loc)] -- ----------------------------------------------------------------------------- -- General path searching -searchPathExts :: [FilePath] -- paths to search +searchPathExts :: [OsPath] -- paths to search -> InstalledModule -- module name -> [ ( - FileExt, -- suffix - FilePath -> BaseName -> ModLocation -- action + OsPath, -- suffix + OsPath -> OsPath -> IO ModLocation -- action ) ] -> IO InstalledFindResult -searchPathExts paths mod exts = search to_search - where - basename = moduleNameSlashes (moduleName mod) - - to_search :: [(FilePath, ModLocation)] +searchPathExts paths mod exts = do + basename <- OsPath.encodeFS (moduleNameSlashes (moduleName mod)) + dot <- OsPath.encodeFS "." + let + to_search :: [(OsPath, IO ModLocation)] to_search = [ (file, fn path basename) | path <- paths, (ext,fn) <- exts, - let base | path == "." = basename - | otherwise = path basename - file = base <.> ext + let base | path == dot = basename + | otherwise = path OsPath. basename + file = base OsPath.<.> ext ] - search [] = return (InstalledNotFound (map fst to_search) (Just (moduleUnit mod))) + search [] = do + fps <- traverse (OsPath.decodeFS . fst) to_search + return (InstalledNotFound fps (Just (moduleUnit mod))) - search ((file, loc) : rest) = do - b <- doesFileExist file + search ((file, getLoc) : rest) = do + b <- OsPath.doesFileExist file if b - then return $ InstalledFound loc mod + then do + loc <- getLoc + return $ InstalledFound loc mod else search rest + search to_search + where + mkHomeModLocationSearched :: FinderOpts -> ModuleName -> FileExt - -> FilePath -> BaseName -> ModLocation -mkHomeModLocationSearched fopts mod suff path basename = - mkHomeModLocation2 fopts mod (path basename) suff + -> OsPath -> OsPath -> IO ModLocation +mkHomeModLocationSearched fopts mod ext path basename = do + mkHomeModLocationOsPath fopts mod (path OsPath. basename) ext -- ----------------------------------------------------------------------------- @@ -581,7 +589,7 @@ mkHomeModLocationSearched fopts mod suff path basename = -- ext -- The filename extension of the source file (usually "hs" or "lhs"). -mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> ModLocation +mkHomeModLocation :: FinderOpts -> ModuleName -> FilePath -> IO ModLocation mkHomeModLocation dflags mod src_filename = let (basename,extension) = splitExtension src_filename in mkHomeModLocation2 dflags mod basename extension @@ -590,129 +598,108 @@ mkHomeModLocation2 :: FinderOpts -> ModuleName -> FilePath -- Of source module, without suffix -> String -- Suffix - -> ModLocation -mkHomeModLocation2 fopts mod src_basename ext = - let mod_basename = moduleNameSlashes mod - - obj_fn = mkObjPath fopts src_basename mod_basename - dyn_obj_fn = mkDynObjPath fopts src_basename mod_basename - hi_fn = mkHiPath fopts src_basename mod_basename - dyn_hi_fn = mkDynHiPath fopts src_basename mod_basename - hie_fn = mkHiePath fopts src_basename mod_basename - - in (ModLocation{ ml_hs_file = Just (src_basename <.> ext), - ml_hi_file = hi_fn, - ml_dyn_hi_file = dyn_hi_fn, - ml_obj_file = obj_fn, - ml_dyn_obj_file = dyn_obj_fn, - ml_hie_file = hie_fn }) + -> IO ModLocation +mkHomeModLocation2 fopts mod src_basename ext = do + src_basename_os <- OsPath.encodeFS src_basename + mkHomeModLocationOsPath fopts mod src_basename_os ext + +mkHomeModLocationOsPath :: FinderOpts + -> ModuleName + -> OsPath -- Of source module, without suffix + -> FileExt + -> IO ModLocation +mkHomeModLocationOsPath fopts mod src_basename ext = do + mod_basename <- OsPath.encodeFS (moduleNameSlashes mod) + obj_fn <- mkObjPath fopts src_basename mod_basename + dyn_obj_fn <- mkDynObjPath fopts src_basename mod_basename + hi_fn <- mkHiPath fopts src_basename mod_basename + dyn_hi_fn <- mkDynHiPath fopts src_basename mod_basename + hie_fn <- mkHiePath fopts src_basename mod_basename + original <- OsPath.decodeFS src_basename + pure ModLocation { + ml_hs_file = Just (original <.> ext), + ml_hi_file = hi_fn, + ml_dyn_hi_file = dyn_hi_fn, + ml_obj_file = obj_fn, + ml_dyn_obj_file = dyn_obj_fn, + ml_hie_file = hie_fn + } mkHomeModHiOnlyLocation :: FinderOpts -> ModuleName - -> FilePath - -> BaseName - -> ModLocation -mkHomeModHiOnlyLocation fopts mod path basename = - let loc = mkHomeModLocation2 fopts mod (path basename) "" - in loc { ml_hs_file = Nothing } + -> OsPath + -> OsPath + -> IO ModLocation +mkHomeModHiOnlyLocation fopts mod path basename = do + loc <- mkHomeModLocationOsPath fopts mod (path OsPath. basename) "" + pure loc { ml_hs_file = Nothing } -- This function is used to make a ModLocation for a package module. Hence why -- we explicitly pass in the interface file suffixes. -mkHiOnlyModLocation :: FinderOpts -> Suffix -> Suffix -> FilePath -> String - -> ModLocation -mkHiOnlyModLocation fopts hisuf dynhisuf path basename - = let full_basename = path basename - obj_fn = mkObjPath fopts full_basename basename - dyn_obj_fn = mkDynObjPath fopts full_basename basename - hie_fn = mkHiePath fopts full_basename basename - in ModLocation{ ml_hs_file = Nothing, - ml_hi_file = full_basename <.> hisuf, - -- Remove the .hi-boot suffix from - -- hi_file, if it had one. We always - -- want the name of the real .hi file - -- in the ml_hi_file field. - ml_dyn_obj_file = dyn_obj_fn, - -- MP: TODO - ml_dyn_hi_file = full_basename <.> dynhisuf, - ml_obj_file = obj_fn, - ml_hie_file = hie_fn - } +mkHiOnlyModLocation :: FinderOpts -> OsPath -> OsPath -> OsPath -> OsPath + -> IO ModLocation +mkHiOnlyModLocation fopts hisuf dynhisuf path basename = do + let full_basename = path OsPath. basename + obj_fn <- mkObjPath fopts full_basename basename + dyn_obj_fn <- mkDynObjPath fopts full_basename basename + hie_fn <- mkHiePath fopts full_basename basename + pure ModLocation { + ml_hs_file = Nothing, + ml_hi_file = full_basename OsPath.<.> hisuf, + -- Remove the .hi-boot suffix from + -- hi_file, if it had one. We always + -- want the name of the real .hi file + -- in the ml_hi_file field. + ml_dyn_obj_file = dyn_obj_fn, + -- MP: TODO + ml_dyn_hi_file = full_basename OsPath.<.> dynhisuf, + ml_obj_file = obj_fn, + ml_hie_file = hie_fn + } + +mk_path + :: (FinderOpts -> Maybe FilePath) + -> (FinderOpts -> FilePath) + -> FinderOpts + -> OsPath -- the filename of the source file, minus the extension + -> OsPath -- the module name with dots replaced by slashes + -> IO OsPath +mk_path get_suf_dir get_suf fopts basename mod_basename = do + suf <- OsPath.encodeFS (get_suf fopts) + suf_dir <- traverse OsPath.encodeFS (get_suf_dir fopts) + let + obj_basename + | Just dir <- suf_dir + = dir OsPath. mod_basename + | otherwise + = basename + pure (obj_basename OsPath.<.> suf) -- | Constructs the filename of a .o file for a given source file. -- Does /not/ check whether the .o file exists -mkObjPath - :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkObjPath fopts basename mod_basename = obj_basename <.> osuf - where - odir = finder_objectDir fopts - osuf = finder_objectSuf fopts - - obj_basename | Just dir <- odir = dir mod_basename - | otherwise = basename +mkObjPath :: FinderOpts -> OsPath -> OsPath -> IO OsPath +mkObjPath = mk_path finder_objectDir finder_objectSuf -- | Constructs the filename of a .dyn_o file for a given source file. -- Does /not/ check whether the .dyn_o file exists -mkDynObjPath - :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkDynObjPath fopts basename mod_basename = obj_basename <.> dynosuf - where - odir = finder_objectDir fopts - dynosuf = finder_dynObjectSuf fopts - - obj_basename | Just dir <- odir = dir mod_basename - | otherwise = basename +mkDynObjPath :: FinderOpts -> OsPath -> OsPath -> IO OsPath +mkDynObjPath = mk_path finder_objectDir finder_dynObjectSuf -- | Constructs the filename of a .hi file for a given source file. -- Does /not/ check whether the .hi file exists -mkHiPath - :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkHiPath fopts basename mod_basename = hi_basename <.> hisuf - where - hidir = finder_hiDir fopts - hisuf = finder_hiSuf fopts - - hi_basename | Just dir <- hidir = dir mod_basename - | otherwise = basename +mkHiPath :: FinderOpts -> OsPath -> OsPath -> IO OsPath +mkHiPath = mk_path finder_hiDir finder_hiSuf -- | Constructs the filename of a .dyn_hi file for a given source file. -- Does /not/ check whether the .dyn_hi file exists -mkDynHiPath - :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkDynHiPath fopts basename mod_basename = hi_basename <.> dynhisuf - where - hidir = finder_hiDir fopts - dynhisuf = finder_dynHiSuf fopts - - hi_basename | Just dir <- hidir = dir mod_basename - | otherwise = basename +mkDynHiPath :: FinderOpts -> OsPath -> OsPath -> IO OsPath +mkDynHiPath = mk_path finder_hiDir finder_dynHiSuf -- | Constructs the filename of a .hie file for a given source file. -- Does /not/ check whether the .hie file exists -mkHiePath - :: FinderOpts - -> FilePath -- the filename of the source file, minus the extension - -> String -- the module name with dots replaced by slashes - -> FilePath -mkHiePath fopts basename mod_basename = hie_basename <.> hiesuf - where - hiedir = finder_hieDir fopts - hiesuf = finder_hieSuf fopts - - hie_basename | Just dir <- hiedir = dir mod_basename - | otherwise = basename +mkHiePath :: FinderOpts -> OsPath -> OsPath -> IO OsPath +mkHiePath = mk_path finder_hieDir finder_hieSuf @@ -750,11 +737,13 @@ mkStubPaths fopts mod location findObjectLinkableMaybe :: Module -> ModLocation -> IO (Maybe Linkable) findObjectLinkableMaybe mod locn - = do let obj_fn = ml_obj_file locn - maybe_obj_time <- modificationTimeIfExists obj_fn + = do let obj_op = ml_obj_file locn + maybe_obj_time <- modificationTimeIfExists obj_op case maybe_obj_time of Nothing -> return Nothing - Just obj_time -> liftM Just (findObjectLinkable mod obj_fn obj_time) + Just obj_time -> do + obj_fn <- OsPath.decodeFS obj_op + liftM Just (findObjectLinkable mod obj_fn obj_time) -- Make an object linkable when we know the object file exists, and we know -- its modification time. ===================================== compiler/GHC/Unit/Module/Graph.hs ===================================== @@ -284,8 +284,8 @@ showModMsg dflags recomp (ModuleNode _ mod_summary) = op = normalise mod_str = moduleNameString (moduleName (ms_mod mod_summary)) ++ hscSourceString (ms_hsc_src mod_summary) - dyn_file = op $ msDynObjFilePath mod_summary - obj_file = op $ msObjFilePath mod_summary + dyn_file = op $ msDynObjFilePathLenient mod_summary + obj_file = op $ msObjFilePathLenient mod_summary files = [ obj_file ] ++ [ dyn_file | gopt Opt_BuildDynamicToo dflags ] ++ [ "interpreted" | gopt Opt_ByteCodeAndObjectCode dflags ] ===================================== compiler/GHC/Unit/Module/Location.hs ===================================== @@ -2,17 +2,32 @@ module GHC.Unit.Module.Location ( ModLocation(..) , addBootSuffix + , addBootSuffixOsPath , addBootSuffix_maybe , addBootSuffixLocn_maybe , addBootSuffixLocn , addBootSuffixLocnOut , removeBootSuffix + , mlHiFilePath + , mlDynHiFilePath + , mlObjFilePath + , mlDynObjFilePath + , mlHieFilePath + , mlHiFilePathLenient + , mlDynHiFilePathLenient + , mlObjFilePathLenient + , mlDynObjFilePathLenient + , mlHieFilePathLenient ) where +import GHC.Data.Maybe (expectJust) import GHC.Prelude import GHC.Unit.Types import GHC.Utils.Outputable +import System.OsPath (OsPath) +import qualified System.OsPath as OsPath +import qualified Data.Semigroup as Semigroup -- | Module Location -- @@ -43,26 +58,26 @@ data ModLocation -- ^ The source file, if we have one. Package modules -- probably don't have source files. - ml_hi_file :: FilePath, + ml_hi_file :: OsPath, -- ^ Where the .hi file is, whether or not it exists -- yet. Always of form foo.hi, even if there is an -- hi-boot file (we add the -boot suffix later) - ml_dyn_hi_file :: FilePath, + ml_dyn_hi_file :: OsPath, -- ^ Where the .dyn_hi file is, whether or not it exists -- yet. - ml_obj_file :: FilePath, + ml_obj_file :: OsPath, -- ^ Where the .o file is, whether or not it exists yet. -- (might not exist either because the module hasn't -- been compiled yet, or because it is part of a -- unit with a .a file) - ml_dyn_obj_file :: FilePath, + ml_dyn_obj_file :: OsPath, -- ^ Where the .dy file is, whether or not it exists -- yet. - ml_hie_file :: FilePath + ml_hie_file :: OsPath -- ^ Where the .hie file is, whether or not it exists -- yet. } deriving Show @@ -74,6 +89,13 @@ instance Outputable ModLocation where addBootSuffix :: FilePath -> FilePath addBootSuffix path = path ++ "-boot" +bootSuffixOsPath :: OsPath +bootSuffixOsPath = expectJust "bootSuffixOsPath" (OsPath.encodeUtf "-boot") +{-# noinline bootSuffixOsPath #-} + +addBootSuffixOsPath :: OsPath -> OsPath +addBootSuffixOsPath path = path Semigroup.<> bootSuffixOsPath + -- | Remove the @-boot@ suffix to .hs, .hi and .o files removeBootSuffix :: FilePath -> FilePath removeBootSuffix "-boot" = [] @@ -96,21 +118,38 @@ addBootSuffixLocn_maybe is_boot locn = case is_boot of addBootSuffixLocn :: ModLocation -> ModLocation addBootSuffixLocn locn = locn { ml_hs_file = fmap addBootSuffix (ml_hs_file locn) - , ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) } + , ml_hi_file = addBootSuffixOsPath (ml_hi_file locn) + , ml_dyn_hi_file = addBootSuffixOsPath (ml_dyn_hi_file locn) + , ml_obj_file = addBootSuffixOsPath (ml_obj_file locn) + , ml_dyn_obj_file = addBootSuffixOsPath (ml_dyn_obj_file locn) + , ml_hie_file = addBootSuffixOsPath (ml_hie_file locn) } -- | Add the @-boot@ suffix to all output file paths associated with the -- module, not including the input file itself addBootSuffixLocnOut :: ModLocation -> ModLocation addBootSuffixLocnOut locn - = locn { ml_hi_file = addBootSuffix (ml_hi_file locn) - , ml_dyn_hi_file = addBootSuffix (ml_dyn_hi_file locn) - , ml_obj_file = addBootSuffix (ml_obj_file locn) - , ml_dyn_obj_file = addBootSuffix (ml_dyn_obj_file locn) - , ml_hie_file = addBootSuffix (ml_hie_file locn) + = locn { ml_hi_file = addBootSuffixOsPath (ml_hi_file locn) + , ml_dyn_hi_file = addBootSuffixOsPath (ml_dyn_hi_file locn) + , ml_obj_file = addBootSuffixOsPath (ml_obj_file locn) + , ml_dyn_obj_file = addBootSuffixOsPath (ml_dyn_obj_file locn) + , ml_hie_file = addBootSuffixOsPath (ml_hie_file locn) } - +toFilePathLenient :: OsPath -> FilePath +toFilePathLenient = fmap OsPath.toChar . OsPath.unpack + +mlHiFilePath, mlDynHiFilePath, mlObjFilePath, mlDynObjFilePath, + mlHieFilePath :: ModLocation -> IO FilePath +mlHiFilePath ml = OsPath.decodeFS (ml_hi_file ml) +mlDynHiFilePath ml = OsPath.decodeFS (ml_dyn_hi_file ml) +mlObjFilePath ml = OsPath.decodeFS (ml_obj_file ml) +mlDynObjFilePath ml = OsPath.decodeFS (ml_dyn_obj_file ml) +mlHieFilePath ml = OsPath.decodeFS (ml_hie_file ml) + +mlHiFilePathLenient, mlDynHiFilePathLenient, mlObjFilePathLenient, + mlDynObjFilePathLenient, mlHieFilePathLenient :: ModLocation -> FilePath +mlHiFilePathLenient ml = toFilePathLenient (ml_hi_file ml) +mlDynHiFilePathLenient ml = toFilePathLenient (ml_dyn_hi_file ml) +mlObjFilePathLenient ml = toFilePathLenient (ml_obj_file ml) +mlDynObjFilePathLenient ml = toFilePathLenient (ml_dyn_obj_file ml) +mlHieFilePathLenient ml = toFilePathLenient (ml_hie_file ml) ===================================== compiler/GHC/Unit/Module/ModSummary.hs ===================================== @@ -17,6 +17,12 @@ module GHC.Unit.Module.ModSummary , msHsFilePath , msObjFilePath , msDynObjFilePath + , msHieFilePath + , msHiFilePathLenient + , msDynHiFilePathLenient + , msObjFilePathLenient + , msDynObjFilePathLenient + , msHieFilePathLenient , msDeps , isBootSummary , findTarget @@ -139,12 +145,24 @@ ms_home_imps = home_imps . ms_imps -- The ModLocation is stable over successive up-sweeps in GHCi, wheres -- the ms_hs_hash and imports can, of course, change -msHsFilePath, msDynHiFilePath, msHiFilePath, msObjFilePath, msDynObjFilePath :: ModSummary -> FilePath -msHsFilePath ms = expectJust "msHsFilePath" (ml_hs_file (ms_location ms)) -msHiFilePath ms = ml_hi_file (ms_location ms) -msDynHiFilePath ms = ml_dyn_hi_file (ms_location ms) -msObjFilePath ms = ml_obj_file (ms_location ms) -msDynObjFilePath ms = ml_dyn_obj_file (ms_location ms) +msHsFilePath :: ModSummary -> FilePath +msHsFilePath ms = expectJust "msHsFilePath" (ml_hs_file (ms_location ms)) + +msHiFilePath, msDynHiFilePath, msObjFilePath, msDynObjFilePath, + msHieFilePath :: ModSummary -> IO FilePath +msHiFilePath ms = mlHiFilePath (ms_location ms) +msDynHiFilePath ms = mlDynHiFilePath (ms_location ms) +msObjFilePath ms = mlObjFilePath (ms_location ms) +msDynObjFilePath ms = mlDynObjFilePath (ms_location ms) +msHieFilePath ms = mlHieFilePath (ms_location ms) + +msHiFilePathLenient, msDynHiFilePathLenient, msObjFilePathLenient, + msDynObjFilePathLenient, msHieFilePathLenient :: ModSummary -> FilePath +msHiFilePathLenient ms = mlHiFilePathLenient (ms_location ms) +msDynHiFilePathLenient ms = mlDynHiFilePathLenient (ms_location ms) +msObjFilePathLenient ms = mlObjFilePathLenient (ms_location ms) +msDynObjFilePathLenient ms = mlDynObjFilePathLenient (ms_location ms) +msHieFilePathLenient ms = mlHieFilePathLenient (ms_location ms) -- | Did this 'ModSummary' originate from a hs-boot file? isBootSummary :: ModSummary -> IsBootInterface ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -134,6 +134,8 @@ import Control.Monad.IO.Class ( MonadIO, liftIO ) import System.IO.Error as IO ( isDoesNotExistError ) import System.Directory ( doesDirectoryExist, getModificationTime, renameFile ) import System.FilePath +import System.OsPath (OsPath) +import qualified System.Directory.OsPath as OsPath import Data.Bifunctor ( first, second ) import Data.Char ( isUpper, isAlphaNum, isSpace, chr, ord, isDigit, toUpper @@ -1230,9 +1232,9 @@ getModificationUTCTime = getModificationTime -- -------------------------------------------------------------- -- check existence & modification time at the same time -modificationTimeIfExists :: FilePath -> IO (Maybe UTCTime) +modificationTimeIfExists :: OsPath -> IO (Maybe UTCTime) modificationTimeIfExists f = - (do t <- getModificationUTCTime f; return (Just t)) + (do t <- OsPath.getModificationTime f; return (Just t)) `catchIO` \e -> if isDoesNotExistError e then return Nothing else ioError e ===================================== ghc/GHCi/UI.hs ===================================== @@ -2334,7 +2334,7 @@ modulesLoadedMsg ok mods load_type = do pure $ if is_interpreted then ppr (GHC.ms_mod mod) else ppr (GHC.ms_mod mod) - <+> parens (text $ normalise $ msObjFilePath mod) + <+> parens (text $ normalise $ msObjFilePathLenient mod) -- Fix #9887 -- | Run an 'ExceptT' wrapped 'GhcMonad' while handling source errors ===================================== ghc/GHCi/UI/Info.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Utils.Outputable import GHC.Types.SrcLoc import GHC.Types.Var import qualified GHC.Data.Strict as Strict +import GHC.Unit.Module.ModSummary (msObjFilePath) -- | Info about a module. This information is generated every time a -- module is loaded. @@ -288,8 +289,8 @@ collectInfo ms loaded = do cacheInvalid name = case M.lookup name ms of Nothing -> return True Just mi -> do - let fp = srcFilePath (modinfoSummary mi) - last' = modinfoLastUpdate mi + let last' = modinfoLastUpdate mi + fp <- srcFilePath (modinfoSummary mi) current <- getModificationTime fp exists <- doesFileExist fp if exists @@ -299,12 +300,13 @@ collectInfo ms loaded = do -- | Get the source file path from a ModSummary. -- If the .hs file is missing, and the .o file exists, -- we return the .o file path. -srcFilePath :: ModSummary -> FilePath -srcFilePath modSum = fromMaybe obj_fp src_fp - where - src_fp = ml_hs_file ms_loc - obj_fp = ml_obj_file ms_loc - ms_loc = ms_location modSum +srcFilePath :: ModSummary -> IO FilePath +srcFilePath modSum = do + obj_fp <- msObjFilePath modSum + pure (fromMaybe obj_fp src_fp) + where + src_fp = ml_hs_file ms_loc + ms_loc = ms_location modSum -- | Get info about the module: summary, types, etc. getModInfo :: (GhcMonad m) => ModuleName -> m ModInfo @@ -319,7 +321,7 @@ getModInfo name = do -- NB: this has already been deeply forced; no need to do that again. -- See test case T15369 and Note [Forcing GREInfo] in GHC.Types.GREInfo. Nothing -> Strict.Nothing - ts <- liftIO $ getModificationTime $ srcFilePath m + ts <- liftIO $ getModificationTime =<< srcFilePath m return $ ModInfo { modinfoSummary = m ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit cd2f4bbb194dca5dd0246e771c999f22b6f0cdf1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bba242d983714edb20e4c70b494ec4dd82ff4129 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bba242d983714edb20e4c70b494ec4dd82ff4129 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 17:14:13 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 13:14:13 -0400 Subject: [Git][ghc/ghc][master] rts: Improve tracing message when nursery is resized Message-ID: <66196be5ad86c_15979f1be8380105772@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 1 changed file: - rts/sm/Storage.c Changes: ===================================== rts/sm/Storage.c ===================================== @@ -881,8 +881,8 @@ resizeNurseriesEach (W_ blocks) node = capNoToNumaNode(i); if (nursery_blocks < blocks) { - debugTrace(DEBUG_gc, "increasing size of nursery to %d blocks", - blocks); + debugTrace(DEBUG_gc, "increasing size of nursery from %d to %d blocks", + nursery_blocks, blocks); nursery->blocks = allocNursery(node, nursery->blocks, blocks-nursery_blocks); } @@ -890,8 +890,8 @@ resizeNurseriesEach (W_ blocks) { bdescr *next_bd; - debugTrace(DEBUG_gc, "decreasing size of nursery to %d blocks", - blocks); + debugTrace(DEBUG_gc, "decreasing size of nursery from %d to %d blocks", + nursery_blocks, blocks); bd = nursery->blocks; while (nursery_blocks > blocks) { @@ -905,6 +905,8 @@ resizeNurseriesEach (W_ blocks) // might have gone just under, by freeing a large block, so make // up the difference. if (nursery_blocks < blocks) { + debugTrace(DEBUG_gc, "reincreasing size of nursery from %d to %d blocks", + nursery_blocks, blocks); nursery->blocks = allocNursery(node, nursery->blocks, blocks-nursery_blocks); } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c34895470fad6b1aa29fce53d54c76cf413225f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c34895470fad6b1aa29fce53d54c76cf413225f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 17:14:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 12 Apr 2024 13:14:52 -0400 Subject: [Git][ghc/ghc][master] Don't generate wrappers for `type data` constructors with StrictData Message-ID: <66196c0bd2a09_15979f1daaeac1107cb@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 5 changed files: - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/type-data/should_run/T24620.hs - testsuite/tests/type-data/should_run/all.T Changes: ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -645,8 +645,11 @@ getImplicitBinds tc = cls_binds ++ getTyConImplicitBinds tc getTyConImplicitBinds :: TyCon -> [CoreBind] getTyConImplicitBinds tc - | isNewTyCon tc = [] -- See Note [Compulsory newtype unfolding] in GHC.Types.Id.Make - | otherwise = map get_defn (mapMaybe dataConWrapId_maybe (tyConDataCons tc)) + | isDataTyCon tc = map get_defn (mapMaybe dataConWrapId_maybe (tyConDataCons tc)) + | otherwise = [] + -- The 'otherwise' includes family TyCons of course, but also (less obviously) + -- * Newtypes: see Note [Compulsory newtype unfolding] in GHC.Types.Id.Make + -- * type data: we don't want any code for type-only stuff (#24620) getClassImplicitBinds :: Class -> [CoreBind] getClassImplicitBinds cls ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1972,6 +1972,8 @@ Wrinkles: is never used (invariant (I1)), so it barely makes sense to talk about the worker. A `type data` constructor only shows up in types, where it appears as a TyCon, specifically a PromotedDataCon -- no Id in sight. + See #24620 for an example of what happens if you accidentally include + a wrapper. See `wrapped_reqd` in GHC.Types.Id.Make.mkDataConRep` for the place where this check is implemented. ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -902,15 +902,25 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- needs a wrapper. This wrapper is injected into the program later in the -- CoreTidy pass. See Note [Injecting implicit bindings] in GHC.Iface.Tidy, -- along with the accompanying implementation in getTyConImplicitBinds. - wrapper_reqd = - (not new_tycon + wrapper_reqd + | isTypeDataTyCon tycon + -- `type data` declarations never have data-constructor wrappers + -- Their data constructors only live at the type level, in the + -- form of PromotedDataCon, and therefore do not need wrappers. + -- See wrinkle (W0) in Note [Type data declarations] in GHC.Rename.Module. + = False + + | otherwise + = (not new_tycon -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. -- See dataConUserTyVarsNeedWrapper below. && (any isBanged (ev_ibangs ++ arg_ibangs))) -- Some forcing/unboxing (includes eq_spec) + || isFamInstTyCon tycon -- Cast result - || (dataConUserTyVarsNeedWrapper data_con + + || dataConUserTyVarsNeedWrapper data_con -- If the data type was written with GADT syntax and -- orders the type variables differently from what the -- worker expects, it needs a data con wrapper to reorder @@ -919,19 +929,7 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- -- NB: All GADTs return true from this function, but there -- is one exception that we must check below. - && not (isTypeDataTyCon tycon)) - -- An exception to this rule is `type data` declarations. - -- Their data constructors only live at the type level and - -- therefore do not need wrappers. - -- See Note [Type data declarations] in GHC.Rename.Module. - -- - -- Note that the other checks in this definition will - -- return False for `type data` declarations, as: - -- - -- - They cannot be newtypes - -- - They cannot have strict fields - -- - They cannot be data family instances - -- - They cannot have datatype contexts + || not (null stupid_theta) -- If the data constructor has a datatype context, -- we need a wrapper in order to drop the stupid arguments. ===================================== testsuite/tests/type-data/should_run/T24620.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StrictData #-} +{-# LANGUAGE TypeData #-} + +module Main where + +type data Nat = Zero | Succ Nat + +main :: IO () +main = pure () ===================================== testsuite/tests/type-data/should_run/all.T ===================================== @@ -2,3 +2,4 @@ test('T22332a', exit_code(1), compile_and_run, ['']) test('T22315b', extra_files(['T22315b.hs']), ghci_script, ['T22315b.script']) test('T22500', normal, compile_and_run, ['']) test('T22948a', normal, compile_and_run, ['']) +test('T24620', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e4f4ba835fd24135759ee7a2d0d5c636a8a1505 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e4f4ba835fd24135759ee7a2d0d5c636a8a1505 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 18:33:10 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 14:33:10 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 2 commits: hadrian: Refactor treatment of extra dependencies Message-ID: <66197e6648947_1ac4bb3967c8583a3@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: b460c774 by Ben Gamari at 2024-04-12T14:32:16-04:00 hadrian: Refactor treatment of extra dependencies The previous implementation was both hard to follow and repeated itself, making changes quite error-prone. Refactor this to be a bit more easier to reason about. - - - - - 2eae9155 by Ben Gamari at 2024-04-12T14:32:44-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -20,26 +20,42 @@ import qualified Data.Set as S import qualified Text.Parsec as Parsec + +data PkgMod = PkgMod { pkg :: Package, mod :: String } + +extraDepsList :: [(PkgMod, PkgMod)] +extraDepsList = + [ (containers, "Data.IntSet.Internal") --> th_internal + , (containers, "Data.Set.Internal") --> th_internal + , (containers, "Data.Sequence.Internal") --> th_internal + , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal + ] + where + (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) + th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") + -- These modules use DeriveLift which needs Language.Haskell.TH.Lib.Internal but -- the dependency is implicit. ghc -M should emit this additional dependency but -- until it does we need to add this dependency ourselves. -extra_dependencies :: M.Map Package (Stage -> Action [(FilePath, FilePath)]) -extra_dependencies = - M.fromList [(containers, fmap (fmap concat . sequence) (sequence - [dep (containers, "Data.IntSet.Internal") th_internal - ,dep (containers, "Data.Set.Internal") th_internal - ,dep (containers, "Data.Sequence.Internal") th_internal - ,dep (containers, "Data.Graph") th_internal - ])) - ] - +extraDependenciesFor :: Stage -> Package -> Action [(FilePath, FilePath)] +extraDependenciesFor stage srcPkg + | Just deps <- M.lookup srcPkg byPackage = concat <$> traverse dep deps + | otherwise = return [] where - th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do - let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") + byPackage :: M.Map Package [(PkgMod, PkgMod)] + byPackage = M.fromListWith (++) [ (pkg x, [(x,y)]) | (x,y) <- extraDepsList ] + + -- @dep ((p1, m1), (p2, m2))@ is an extra dependency from + -- module m1 of package p1 to module m2 of package p2. + dep :: (PkgMod, PkgMod) -> Action [(FilePath, FilePath)] + dep (PkgMod p1 m1, PkgMod p2 m2) = do + let context = Context stage p1 (error "extra_dependencies: way not set") (error "extra_dependencies: inplace not set") ways <- interpretInContext context getLibraryWays - mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) - path stage way p m = + mapM (\way -> (,) <$> path way p1 m1 <*> path way p2 m2) (S.toList ways) + + path :: Way -> Package -> String -> Action FilePath + path way p m = let context = Context stage p way Inplace in objectPath context . moduleSource $ m @@ -53,7 +69,7 @@ buildPackageDependencies rs = do DepMkFile stage pkgpath <- getDepMkFile root mk let pkg = unsafeFindPackageByPath pkgpath context = Context stage pkg vanilla Inplace - extra <- maybe (return []) ($ stage) $ M.lookup pkg extra_dependencies + extra <- extraDependenciesFor stage pkg srcs <- hsSources context gens <- interpretInContext context generatedDependencies need (srcs ++ gens) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51fe02fd96f9ca4da959fc3294ea1fc4e7baaff9...2eae9155ad239569c264921bbf502e1f37b364fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51fe02fd96f9ca4da959fc3294ea1fc4e7baaff9...2eae9155ad239569c264921bbf502e1f37b364fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 18:36:37 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 14:36:37 -0400 Subject: [Git][ghc/ghc][wip/T24528] 13 commits: Prefer packed representation for CompiledByteCode Message-ID: <66197f35c60b6_1ac4bb4d40e05891a@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - bbdd17a7 by Ben Gamari at 2024-04-12T14:35:46-04:00 hadrian: Refactor treatment of extra dependencies The previous implementation was both hard to follow and repeated itself, making changes quite error-prone. Refactor this to be a bit more easier to reason about. - - - - - ce233246 by Ben Gamari at 2024-04-12T14:36:16-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 588c2feb by Ben Gamari at 2024-04-12T14:36:17-04:00 Bump terminfo submodule to current master - - - - - c432bfda by Ben Gamari at 2024-04-12T14:36:17-04:00 Bump parsec submodule - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/MacOS.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Binds.hs - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/ghci/GHCi/Message.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/252e53d258d359534e3a6c034a931eebdb918de6...c432bfda3ed1c7a1954fb6972465bbe013626207 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/252e53d258d359534e3a6c034a931eebdb918de6...c432bfda3ed1c7a1954fb6972465bbe013626207 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 19:49:27 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 15:49:27 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 2 commits: hadrian: Refactor treatment of extra dependencies Message-ID: <661990479982a_1ac4bbdc88f4620c8@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 3a18d9e7 by Ben Gamari at 2024-04-12T15:49:07-04:00 hadrian: Refactor treatment of extra dependencies The previous implementation was both hard to follow and repeated itself, making changes quite error-prone. Refactor this to be a bit more easier to reason about. - - - - - 25fd87fe by Ben Gamari at 2024-04-12T15:49:07-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -20,26 +20,42 @@ import qualified Data.Set as S import qualified Text.Parsec as Parsec + +data PkgMod = PkgMod { pkg :: Package, _mod :: String } + +extraDepsList :: [(PkgMod, PkgMod)] +extraDepsList = + [ (containers, "Data.IntSet.Internal") --> th_internal + , (containers, "Data.Set.Internal") --> th_internal + , (containers, "Data.Sequence.Internal") --> th_internal + , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal + ] + where + (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) + th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") + -- These modules use DeriveLift which needs Language.Haskell.TH.Lib.Internal but -- the dependency is implicit. ghc -M should emit this additional dependency but -- until it does we need to add this dependency ourselves. -extra_dependencies :: M.Map Package (Stage -> Action [(FilePath, FilePath)]) -extra_dependencies = - M.fromList [(containers, fmap (fmap concat . sequence) (sequence - [dep (containers, "Data.IntSet.Internal") th_internal - ,dep (containers, "Data.Set.Internal") th_internal - ,dep (containers, "Data.Sequence.Internal") th_internal - ,dep (containers, "Data.Graph") th_internal - ])) - ] - +extraDependenciesFor :: Stage -> Package -> Action [(FilePath, FilePath)] +extraDependenciesFor stage srcPkg + | Just deps <- M.lookup srcPkg byPackage = concat <$> traverse dep deps + | otherwise = return [] where - th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do - let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") + byPackage :: M.Map Package [(PkgMod, PkgMod)] + byPackage = M.fromListWith (++) [ (pkg x, [(x,y)]) | (x,y) <- extraDepsList ] + + -- @dep ((p1, m1), (p2, m2))@ is an extra dependency from + -- module m1 of package p1 to module m2 of package p2. + dep :: (PkgMod, PkgMod) -> Action [(FilePath, FilePath)] + dep (PkgMod p1 m1, PkgMod p2 m2) = do + let context = Context stage p1 (error "extra_dependencies: way not set") (error "extra_dependencies: inplace not set") ways <- interpretInContext context getLibraryWays - mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) - path stage way p m = + mapM (\way -> (,) <$> path way p1 m1 <*> path way p2 m2) (S.toList ways) + + path :: Way -> Package -> String -> Action FilePath + path way p m = let context = Context stage p way Inplace in objectPath context . moduleSource $ m @@ -53,7 +69,7 @@ buildPackageDependencies rs = do DepMkFile stage pkgpath <- getDepMkFile root mk let pkg = unsafeFindPackageByPath pkgpath context = Context stage pkg vanilla Inplace - extra <- maybe (return []) ($ stage) $ M.lookup pkg extra_dependencies + extra <- extraDependenciesFor stage pkg srcs <- hsSources context gens <- interpretInContext context generatedDependencies need (srcs ++ gens) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2eae9155ad239569c264921bbf502e1f37b364fc...25fd87fe53c7efbc03b54e26c330b1c51cdc1f93 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2eae9155ad239569c264921bbf502e1f37b364fc...25fd87fe53c7efbc03b54e26c330b1c51cdc1f93 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 19:51:09 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 15:51:09 -0400 Subject: [Git][ghc/ghc][wip/T24528] 4 commits: hadrian: Refactor treatment of extra dependencies Message-ID: <661990ad768b3_1ac4bbebbef0622c0@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: dd85ae94 by Ben Gamari at 2024-04-12T15:51:03-04:00 hadrian: Refactor treatment of extra dependencies The previous implementation was both hard to follow and repeated itself, making changes quite error-prone. Refactor this to be a bit more easier to reason about. - - - - - f8475607 by Ben Gamari at 2024-04-12T15:51:03-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 858505a4 by Ben Gamari at 2024-04-12T15:51:03-04:00 Bump terminfo submodule to current master - - - - - d2e0139e by Ben Gamari at 2024-04-12T15:51:03-04:00 Bump parsec submodule - - - - - 9 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/parsec - libraries/terminfo - libraries/time - libraries/unix Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.11 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -20,26 +20,44 @@ import qualified Data.Set as S import qualified Text.Parsec as Parsec --- These modules use DeriveLift which needs Language.Haskell.TH.Lib.Internal but + +data PkgMod = PkgMod { pkg :: Package, _mod :: String } + +-- | These modules use DeriveLift which needs Language.Haskell.TH.Lib.Internal but -- the dependency is implicit. ghc -M should emit this additional dependency but -- until it does we need to add this dependency ourselves. -extra_dependencies :: M.Map Package (Stage -> Action [(FilePath, FilePath)]) -extra_dependencies = - M.fromList [(containers, fmap (fmap concat . sequence) (sequence - [dep (containers, "Data.IntSet.Internal") th_internal - ,dep (containers, "Data.Set.Internal") th_internal - ,dep (containers, "Data.Sequence.Internal") th_internal - ,dep (containers, "Data.Graph") th_internal - ])) +-- +-- This should be dropped when #22229 is fixed. +extraDepsList :: [(PkgMod, PkgMod)] +extraDepsList = + [ (containers, "Data.IntSet.Internal") --> th_internal + , (containers, "Data.Set.Internal") --> th_internal + , (containers, "Data.Sequence.Internal") --> th_internal + , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] - where + (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do - let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") + +extraDependenciesFor :: Stage -> Package -> Action [(FilePath, FilePath)] +extraDependenciesFor stage srcPkg + | Just deps <- M.lookup srcPkg byPackage = concat <$> traverse dep deps + | otherwise = return [] + where + byPackage :: M.Map Package [(PkgMod, PkgMod)] + byPackage = M.fromListWith (++) [ (pkg x, [(x,y)]) | (x,y) <- extraDepsList ] + + -- @dep ((p1, m1), (p2, m2))@ is an extra dependency from + -- module m1 of package p1 to module m2 of package p2. + dep :: (PkgMod, PkgMod) -> Action [(FilePath, FilePath)] + dep (PkgMod p1 m1, PkgMod p2 m2) = do + let context = Context stage p1 (error "extra_dependencies: way not set") (error "extra_dependencies: inplace not set") ways <- interpretInContext context getLibraryWays - mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) - path stage way p m = + mapM (\way -> (,) <$> path way p1 m1 <*> path way p2 m2) (S.toList ways) + + path :: Way -> Package -> String -> Action FilePath + path way p m = let context = Context stage p way Inplace in objectPath context . moduleSource $ m @@ -53,7 +71,7 @@ buildPackageDependencies rs = do DepMkFile stage pkgpath <- getDepMkFile root mk let pkg = unsafeFindPackageByPath pkgpath context = Context stage pkg vanilla Inplace - extra <- maybe (return []) ($ stage) $ M.lookup pkg extra_dependencies + extra <- extraDependenciesFor stage pkg srcs <- hsSources context gens <- interpretInContext context generatedDependencies need (srcs ++ gens) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit fb3f4d47d261f7401e4ea717ffab31af5d5470fb +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit cc1b149fecfa145a5e3fba292927c5c572fb38ce ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c432bfda3ed1c7a1954fb6972465bbe013626207...d2e0139e5667298bdb5514dc19dd8b5aa4783994 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c432bfda3ed1c7a1954fb6972465bbe013626207...d2e0139e5667298bdb5514dc19dd8b5aa4783994 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 21:51:38 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 17:51:38 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] Bump time submodule to 1.14 Message-ID: <6619acea35485_3cc825c1785c188c7@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 2ed72644 by Ben Gamari at 2024-04-12T17:51:15-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -29,6 +29,18 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal + , (time, "Data.Time.Calendar.Days") --> th_internal + , (time, "Data.Time.Calendar.Month") --> th_internal + , (time, "Data.Time.Calendar.Quarter") --> th_internal + , (time, "Data.Time.Calendar.Week") --> th_internal + , (time, "Data.Time.Calendar.WeekDate") --> th_internal + , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal + , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ed7264434a2edee97ab441c9ccbdf675e0d7896 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ed7264434a2edee97ab441c9ccbdf675e0d7896 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 21:52:07 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 17:52:07 -0400 Subject: [Git][ghc/ghc][wip/T24528] 3 commits: Bump time submodule to 1.14 Message-ID: <6619ad07c4711_3cc825cb20641966@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: 8bd1504d by Ben Gamari at 2024-04-12T17:52:01-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - b74e5dd5 by Ben Gamari at 2024-04-12T17:52:01-04:00 Bump terminfo submodule to current master - - - - - ff6a00df by Ben Gamari at 2024-04-12T17:52:01-04:00 Bump parsec submodule - - - - - 9 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/parsec - libraries/terminfo - libraries/time - libraries/unix Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.11 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -34,6 +34,18 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal + , (time, "Data.Time.Calendar.Days") --> th_internal + , (time, "Data.Time.Calendar.Month") --> th_internal + , (time, "Data.Time.Calendar.Quarter") --> th_internal + , (time, "Data.Time.Calendar.Week") --> th_internal + , (time, "Data.Time.Calendar.WeekDate") --> th_internal + , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal + , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit fb3f4d47d261f7401e4ea717ffab31af5d5470fb +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit cc1b149fecfa145a5e3fba292927c5c572fb38ce ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d2e0139e5667298bdb5514dc19dd8b5aa4783994...ff6a00dfb2803e1c365be4230ad9c4863608bc6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d2e0139e5667298bdb5514dc19dd8b5aa4783994...ff6a00dfb2803e1c365be4230ad9c4863608bc6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 22:21:16 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 18:21:16 -0400 Subject: [Git][ghc/ghc][wip/T24528] 3 commits: Bump time submodule to 1.14 Message-ID: <6619b3dc35365_2302f2137928664d6@gitlab.mail> Ben Gamari pushed to branch wip/T24528 at Glasgow Haskell Compiler / GHC Commits: 7547c961 by Ben Gamari at 2024-04-12T18:21:02-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 432de97b by Ben Gamari at 2024-04-12T18:21:02-04:00 Bump terminfo submodule to current master - - - - - 2595fb50 by Ben Gamari at 2024-04-12T18:21:02-04:00 Bump parsec submodule - - - - - 10 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/parsec - libraries/terminfo - libraries/time - libraries/unix Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.11 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.13, + time >= 1.4 && < 1.15, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.13 + time >= 1.8 && < 1.15 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -34,6 +34,18 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal + , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal + , (time, "Data.Time.Calendar.Days") --> th_internal + , (time, "Data.Time.Calendar.Month") --> th_internal + , (time, "Data.Time.Calendar.Quarter") --> th_internal + , (time, "Data.Time.Calendar.Week") --> th_internal + , (time, "Data.Time.Calendar.WeekDate") --> th_internal + , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal + , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal + , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal + , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit fb3f4d47d261f7401e4ea717ffab31af5d5470fb +Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit cc1b149fecfa145a5e3fba292927c5c572fb38ce ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 +Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 930a8289f96c5353d120af4fd155446c574709f2 +Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff6a00dfb2803e1c365be4230ad9c4863608bc6e...2595fb50cc2a4450aa1f27e1652ffb361e4098d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff6a00dfb2803e1c365be4230ad9c4863608bc6e...2595fb50cc2a4450aa1f27e1652ffb361e4098d1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 12 22:40:03 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 18:40:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24610 Message-ID: <6619b8431c0a_2302f2348a1466958@gitlab.mail> Ben Gamari pushed new branch wip/T24610 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24610 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 13 00:36:38 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 12 Apr 2024 20:36:38 -0400 Subject: [Git][ghc/ghc][ghc-9.10] 20 commits: EPA: Remove unnecessary XRec in CompleteMatchSig Message-ID: <6619d39614dbf_9162f2b5110377f5@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 8212c3c6 by Alan Zimmerman at 2024-04-11T09:32:07-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. (cherry picked from commit 1b1a92bd25c3f7249cf922c5dbf4415d2de44a36) - - - - - 6b480460 by Sebastian Graf at 2024-04-11T09:32:18-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 (cherry picked from commit 3e0b2b1f14e5e82eaa1dc6fbf8dceb5f539f5aa3) - - - - - ca9bb80e by Rodrigo Mesquita at 2024-04-11T09:32:41-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 (cherry picked from commit 817e89362e74b5177c02deee31f16cec862052cc) - - - - - a13e9b69 by Matthew Pickering at 2024-04-11T09:32:49-04:00 Fix off by one error in seekBinNoExpand and seekBin (cherry picked from commit 28009fbc26e4aca7a3b05cedb60c5c9baa31223d) - - - - - 770dcce2 by Andrei Borzenkov at 2024-04-11T09:33:40-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot (cherry picked from commit 36a75b80ebe592f582f3f349e8c73b8293d49ed1) - - - - - 03bfe160 by Alan Zimmerman at 2024-04-11T09:33:53-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 (cherry picked from commit be3bdddebdf119007d753bebe32709a1ce726cc0) - - - - - eca47e5b by Alan Zimmerman at 2024-04-11T09:34:02-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. (cherry picked from commit 3b7b0c1c1337fe4cf470987d891f1f3944840688) - - - - - 6ce42495 by Sylvain Henry at 2024-04-11T14:06:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). (cherry picked from commit b36ee57bfbecc628b7f0919e1e59b7066495034f) - - - - - cc690f6e by Sylvain Henry at 2024-04-11T14:06:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 (cherry picked from commit 527616e950fd8942c182be903d176f4b9890ee5a) - - - - - 656395ec by Luite Stegeman at 2024-04-11T14:06:46-04:00 Update correct counter in bumpTickyAllocd (cherry picked from commit 0c4a96862081f03e2946a2ed7e80c108f06205a1) - - - - - fb7dfdf0 by Ben Gamari at 2024-04-11T14:06:46-04:00 testsuite: Fix T24598 with unregisterised compiler (cherry picked from commit 9b9e031b67dbc812c156a4773c0c9d293451fefa) - - - - - 0dd8f0bc by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint (cherry picked from commit 1324b8626aeb4dc2d6a04f7605d307ef13d1e0e9) - - - - - 9745a63e by Simon Peyton Jones at 2024-04-11T14:06:46-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 (cherry picked from commit faa30b41a6f941627ddeeba805815b2742d312d1) - - - - - ed927271 by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. (cherry picked from commit 19883a23b8bc704118fa663d8bab00a503b5a527) - - - - - 220cda2c by Alan Zimmerman at 2024-04-11T14:06:46-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. (cherry picked from commit 12b997df559365e6188824fb10f5f61c2e9075e4) - - - - - 2d1c6074 by Ben Gamari at 2024-04-12T10:27:25-04:00 Bump parsec submodule to upstream master - - - - - 6efe55ef by Ben Gamari at 2024-04-12T10:27:27-04:00 testsuite: More aggressive normalisation of process004 output It turns out that this test uses `execvp`, not `exec` on CentOS 7. Normalise this spurious difference away. - - - - - 702ff84e by Ben Gamari at 2024-04-12T11:35:06-04:00 Bump array, binary, stm submodules - - - - - 3a18d9e7 by Ben Gamari at 2024-04-12T15:49:07-04:00 hadrian: Refactor treatment of extra dependencies The previous implementation was both hard to follow and repeated itself, making changes quite error-prone. Refactor this to be a bit more easier to reason about. - - - - - 2ed72644 by Ben Gamari at 2024-04-12T17:51:15-04:00 Bump time submodule to 1.14 As requested in #24528. - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/StgToJS/Apply.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa5b34e1643df9c44eaebea38cb58dafaf60cb4b...2ed7264434a2edee97ab441c9ccbdf675e0d7896 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa5b34e1643df9c44eaebea38cb58dafaf60cb4b...2ed7264434a2edee97ab441c9ccbdf675e0d7896 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 13 13:07:19 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 13 Apr 2024 09:07:19 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] Revert "Bump time submodule to 1.14" Message-ID: <661a8387590a9_73cd623eb0a0896e7@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 457300cf by Ben Gamari at 2024-04-13T09:06:56-04:00 Revert "Bump time submodule to 1.14" This reverts commit 2ed7264434a2edee97ab441c9ccbdf675e0d7896. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.15, + time >= 1.4 && < 1.13, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.15 + time >= 1.8 && < 1.13 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -29,18 +29,6 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal - , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal - , (time, "Data.Time.Calendar.Days") --> th_internal - , (time, "Data.Time.Calendar.Month") --> th_internal - , (time, "Data.Time.Calendar.Quarter") --> th_internal - , (time, "Data.Time.Calendar.Week") --> th_internal - , (time, "Data.Time.Calendar.WeekDate") --> th_internal - , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal - , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 +Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b +Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f +Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/457300cfa84ad0d319cf61b6c2bf5d7b1d6cb67a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/457300cfa84ad0d319cf61b6c2bf5d7b1d6cb67a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 13 13:11:01 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 13 Apr 2024 09:11:01 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] Revert "Bump time submodule to 1.14" Message-ID: <661a8465bba51_73cd624bbe448988a@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 3b63186d by Ben Gamari at 2024-04-13T09:07:57-04:00 Revert "Bump time submodule to 1.14" Unfortunately the `Lift` instances introduced in 1.14 trigger #22229. While it's unlikely that an end-user will observe this breakage, we cannot to ship a release with the CI breakage that this implies (as multi-component support would have no validation). Consequently, we have no choice but to try to fix #22229 and bump again in 9.12. This reverts commit 2ed7264434a2edee97ab441c9ccbdf675e0d7896. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.15, + time >= 1.4 && < 1.13, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.15 + time >= 1.8 && < 1.13 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -29,18 +29,6 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal - , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal - , (time, "Data.Time.Calendar.Days") --> th_internal - , (time, "Data.Time.Calendar.Month") --> th_internal - , (time, "Data.Time.Calendar.Quarter") --> th_internal - , (time, "Data.Time.Calendar.Week") --> th_internal - , (time, "Data.Time.Calendar.WeekDate") --> th_internal - , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal - , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 +Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b +Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f +Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b63186da9de818963c40ecb27848d3eb4722513 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b63186da9de818963c40ecb27848d3eb4722513 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 13 16:38:42 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sat, 13 Apr 2024 12:38:42 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-hsmodule-ann-cs Message-ID: <661ab51215832_73cd63df2c2899526@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-hsmodule-ann-cs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-hsmodule-ann-cs You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 14 19:14:55 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 14 Apr 2024 15:14:55 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/ghc-9.10-backports-1 Message-ID: <661c2b2fe8195_317d454610d88443ea@gitlab.mail> Alan Zimmerman pushed new branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/ghc-9.10-backports-1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 00:25:36 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 14 Apr 2024 20:25:36 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.10 Message-ID: <661c740035898_3f81791247f9c1069bc@gitlab.mail> Ben Gamari deleted branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 00:25:38 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 14 Apr 2024 20:25:38 -0400 Subject: [Git][ghc/ghc][ghc-9.10] Revert "Bump time submodule to 1.14" Message-ID: <661c7402c8a31_3f81791220f8c10719@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 3b63186d by Ben Gamari at 2024-04-13T09:07:57-04:00 Revert "Bump time submodule to 1.14" Unfortunately the `Lift` instances introduced in 1.14 trigger #22229. While it's unlikely that an end-user will observe this breakage, we cannot to ship a release with the CI breakage that this implies (as multi-component support would have no validation). Consequently, we have no choice but to try to fix #22229 and bump again in 9.12. This reverts commit 2ed7264434a2edee97ab441c9ccbdf675e0d7896. - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.15, + time >= 1.4 && < 1.13, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.15 + time >= 1.8 && < 1.13 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -29,18 +29,6 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal - , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal - , (time, "Data.Time.Calendar.Days") --> th_internal - , (time, "Data.Time.Calendar.Month") --> th_internal - , (time, "Data.Time.Calendar.Quarter") --> th_internal - , (time, "Data.Time.Calendar.Week") --> th_internal - , (time, "Data.Time.Calendar.WeekDate") --> th_internal - , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal - , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 +Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b +Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f +Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b63186da9de818963c40ecb27848d3eb4722513 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b63186da9de818963c40ecb27848d3eb4722513 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 04:59:49 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 00:59:49 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] 4 commits: Bump filepath submodule to 1.4.300.1 Message-ID: <661cb445d1a9f_3bde3f15b4fb873136@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: 13b967a1 by Zubin Duggal at 2024-04-15T10:29:39+05:30 Bump filepath submodule to 1.4.300.1 Bump directory submodule to 1.3.8.4 Bump process submodule to 1.6.18.0 - - - - - 9319795e by Zubin Duggal at 2024-04-15T10:29:39+05:30 Bump process submodule to 1.6.19.0 - - - - - 53efb385 by Zubin Duggal at 2024-04-15T10:29:39+05:30 Prepare release 9.6.5 - - - - - 04495d6c by Zubin Duggal at 2024-04-15T10:29:39+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - 12 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Session.hs - configure.ac - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/using-optimisation.rst - libraries/base/base.cabal - libraries/base/changelog.md - libraries/directory - libraries/filepath - libraries/process Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -66,7 +66,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3363,7 +3363,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, @@ -4002,7 +4003,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are ===================================== docs/users_guide/9.6.5-notes.rst ===================================== @@ -0,0 +1,110 @@ +.. _release-9.6.5: + +Version 9.6.5 +============== + +The significant changes to the various parts of the compiler are listed below. +See the `migration guide +`_ on the GHC Wiki +for specific guidance on migrating programs to this release. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +11, 12, 13, 14 or 15. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Disable ``-fasm-shortcutting`` with ``-O2`` as it leads to unsound optimisations + (:ghc-ticket:`24462). +- Fix a typechecker bug resulting in ``TYPE`` and ``CONSTRAINT`` being apart + (:ghc-ticket:`24279`). +- Fix a bug resulting in incorrect runtime results due to a botched simplifier + pass (:ghc-ticket:`24295`). +- Assign correct source spans to nested documentation comments in the AST (:ghc-ticket:`24378`). +- Fix a bug causing suboptimal error messages for certain invalid cyclic + module graphs with hs-boot files (:ghc-ticket:`24196`, :ghc-ticket:`24275`). +- Fix a bug resulting in infix ``(~)`` and ``(@)`` operators not being usable in + TH quotes (:ghc-ticket:`23748`). +- Fix a bug arising from incorrect parsing of paths containing spaces in the + settings file (:ghc-ticket:`24265`). +- Allow special pragmas to desugar correctly in a few more cases (:ghc-ticket:`24370`). + +Runtime system +-------------- + +- Fix an off-by-one while writing eventlogs (:ghc-ticket:`24287`). +- Avoid segfaults with using ``-Dn`` with the non-moving collector (:ghc-ticket:`24393`). + +Build system and packaging +-------------------------- + +- Fix a bug resulting in the distributed ``hsc2hs`` wrapper using flags from the + compiler build environment (:ghc-ticket:`24050`). +- Better compatibility for newer alex versions in the configure script (:ghc-ticket:`24302`). +- Handle autotools adding the ``-std`` flag to the ``CC``/``CXX`` variables (:ghc-ticket:`24324`). +- Fix a typo in the configure script resulting in the target for the linker being set incorrectly + when configuring a cross-compiler (:ghc-ticket:`24414`). +- Do not override existing linker flags in ``FP_LD_NO_FIXUP_CHAINS``. +- Ensure the ``genapply`` program is built with the write constants when cross compiling (:ghc-ticket:`24347`). +- Ensure we take ``LDFLAGS`` into account when configuring a linker (:ghc-ticket:`24565`). +- Fix a segfault with the non-moving GC (:ghc-ticket:`24492`). + +Core libraries +-------------- + +- Bump ``base`` to 4.18.2.1 +- Bump ``filepath`` to 1.4.300.1 +- Bump ``directory`` to 1.3.8.3 +- Bump ``process`` to 1.6.19.0 +- Bump ``libffi-tarballs`` to 3.4.6 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/bugs.rst ===================================== @@ -697,6 +697,9 @@ Bugs in GHC - ``-Wincomplete-record-updates`` does not warn about record updates for records with partial record fields since GHC 9.6.1. See :ghc-ticket:`23520` for more details. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/release-notes.rst ===================================== @@ -8,3 +8,4 @@ Release notes 9.6.2-notes 9.6.3-notes 9.6.4-notes + 9.6.5-notes ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ by saying ``-fno-wombat``. generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ by saying ``-fno-wombat``. these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. :type: dynamic ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.18.2.0 +version: 4.18.2.1 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause ===================================== libraries/base/changelog.md ===================================== @@ -1,5 +1,8 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.18.2.1 *April 2024* + * Various documentation improvements + ## 4.18.2.0 *January 2024* * Update to [Unicode 15.1.0](https://www.unicode.org/versions/Unicode15.1.0/). * Improve String & IsString documentation. ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 3ae36d84e44737fa9800d74d55ae1e30b75628cf +Subproject commit a97a8a8f30d652f972192122fd5f459a147c13e5 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit cdb5171f7774569b1a8028a78392cfa79f732b5c +Subproject commit c8be0a5f17a0e33a3856566c2ebd6c1e2829ed76 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit e60ab049b92238b0111654589f17b6ee68249f01 +Subproject commit eee87f2838356431930e1fe8f8527db609e3252b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29418a1aae93f79ff296d8a2634070cb14cda86f...04495d6c217833a7bafc16922b8e89dea154a2ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29418a1aae93f79ff296d8a2634070cb14cda86f...04495d6c217833a7bafc16922b8e89dea154a2ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 05:03:11 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 01:03:11 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] 3 commits: Prepare release 9.6.5 Message-ID: <661cb50fb0b47_3bde3f168c42c749f@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: 87326ae9 by Zubin Duggal at 2024-04-15T10:32:22+05:30 Prepare release 9.6.5 - - - - - 7a728210 by Zubin Duggal at 2024-04-15T10:32:22+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - 3a1d8bb2 by Zubin Duggal at 2024-04-15T10:32:22+05:30 Bump Cabal submodule to 3.10.3.0 - - - - - 10 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Session.hs - configure.ac - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/using-optimisation.rst - libraries/Cabal - libraries/base/base.cabal - libraries/base/changelog.md Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -66,7 +66,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3363,7 +3363,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, @@ -4002,7 +4003,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are ===================================== docs/users_guide/9.6.5-notes.rst ===================================== @@ -0,0 +1,111 @@ +.. _release-9.6.5: + +Version 9.6.5 +============== + +The significant changes to the various parts of the compiler are listed below. +See the `migration guide +`_ on the GHC Wiki +for specific guidance on migrating programs to this release. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +11, 12, 13, 14 or 15. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Disable ``-fasm-shortcutting`` with ``-O2`` as it leads to unsound optimisations + (:ghc-ticket:`24462). +- Fix a typechecker bug resulting in ``TYPE`` and ``CONSTRAINT`` being apart + (:ghc-ticket:`24279`). +- Fix a bug resulting in incorrect runtime results due to a botched simplifier + pass (:ghc-ticket:`24295`). +- Assign correct source spans to nested documentation comments in the AST (:ghc-ticket:`24378`). +- Fix a bug causing suboptimal error messages for certain invalid cyclic + module graphs with hs-boot files (:ghc-ticket:`24196`, :ghc-ticket:`24275`). +- Fix a bug resulting in infix ``(~)`` and ``(@)`` operators not being usable in + TH quotes (:ghc-ticket:`23748`). +- Fix a bug arising from incorrect parsing of paths containing spaces in the + settings file (:ghc-ticket:`24265`). +- Allow special pragmas to desugar correctly in a few more cases (:ghc-ticket:`24370`). + +Runtime system +-------------- + +- Fix an off-by-one while writing eventlogs (:ghc-ticket:`24287`). +- Avoid segfaults with using ``-Dn`` with the non-moving collector (:ghc-ticket:`24393`). + +Build system and packaging +-------------------------- + +- Fix a bug resulting in the distributed ``hsc2hs`` wrapper using flags from the + compiler build environment (:ghc-ticket:`24050`). +- Better compatibility for newer alex versions in the configure script (:ghc-ticket:`24302`). +- Handle autotools adding the ``-std`` flag to the ``CC``/``CXX`` variables (:ghc-ticket:`24324`). +- Fix a typo in the configure script resulting in the target for the linker being set incorrectly + when configuring a cross-compiler (:ghc-ticket:`24414`). +- Do not override existing linker flags in ``FP_LD_NO_FIXUP_CHAINS``. +- Ensure the ``genapply`` program is built with the write constants when cross compiling (:ghc-ticket:`24347`). +- Ensure we take ``LDFLAGS`` into account when configuring a linker (:ghc-ticket:`24565`). +- Fix a segfault with the non-moving GC (:ghc-ticket:`24492`). + +Core libraries +-------------- + +- Bump ``base`` to 4.18.2.1 +- Bump ``filepath`` to 1.4.300.1 +- Bump ``directory`` to 1.3.8.4 +- Bump ``Cabal`` to 3.10.3.0 +- Bump ``process`` to 1.6.19.0 +- Bump ``libffi-tarballs`` to 3.4.6 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/bugs.rst ===================================== @@ -697,6 +697,9 @@ Bugs in GHC - ``-Wincomplete-record-updates`` does not warn about record updates for records with partial record fields since GHC 9.6.1. See :ghc-ticket:`23520` for more details. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/release-notes.rst ===================================== @@ -8,3 +8,4 @@ Release notes 9.6.2-notes 9.6.3-notes 9.6.4-notes + 9.6.5-notes ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ by saying ``-fno-wombat``. generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ by saying ``-fno-wombat``. these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. :type: dynamic ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 6c95f3fee3cdee859704b6476646cefd4628a850 +Subproject commit 256f85d735310196d437ede86046f2a86efedc6d ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.18.2.0 +version: 4.18.2.1 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause ===================================== libraries/base/changelog.md ===================================== @@ -1,5 +1,8 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.18.2.1 *April 2024* + * Various documentation improvements + ## 4.18.2.0 *January 2024* * Update to [Unicode 15.1.0](https://www.unicode.org/versions/Unicode15.1.0/). * Improve String & IsString documentation. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04495d6c217833a7bafc16922b8e89dea154a2ee...3a1d8bb2a1ddf4f692e2bcdd1b84060fa8a3a0de -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04495d6c217833a7bafc16922b8e89dea154a2ee...3a1d8bb2a1ddf4f692e2bcdd1b84060fa8a3a0de You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 07:01:37 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 03:01:37 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] 14 commits: Escape multiple arguments in the settings file Message-ID: <661cd0d1e17f6_3bde3f261ba2882585@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: d74ffbbb by Fendor at 2024-04-15T12:31:20+05:30 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. (cherry picked from commit 31bf85ee49fe2ca0b17eaee0774e395f017a9373) - - - - - a5a7a0ce by Florian Weimer at 2024-04-15T12:31:20+05:30 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> (cherry picked from commit 1f534c2e7388273e70534680212c1357614c11ed) - - - - - af368514 by Rodrigo Mesquita at 2024-04-15T12:31:20+05:30 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. (cherry picked from commit 32a8103f3b3e22907fdd67b69c919c5251d8cc20) - - - - - 7ca2ca58 by Cheng Shao at 2024-04-15T12:31:21+05:30 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. (cherry picked from commit 810660b780e1111b36c91326bcd0041e1f62706b) - - - - - 291db356 by Cheng Shao at 2024-04-15T12:31:21+05:30 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. (cherry picked from commit 7db8c9927fae3369fc4ecff68f80c4cb32eea757) - - - - - 014e9ad9 by Cheng Shao at 2024-04-15T12:31:21+05:30 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. (cherry picked from commit ce580426ce3052e3b3d2847d0312652ea9087994) - - - - - cd3a199f by Jade at 2024-04-15T12:31:21+05:30 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid (cherry picked from commit fa4e5913251786f2b535b31abd3fad39da8b3602) - - - - - b895d534 by Simon Peyton Jones at 2024-04-15T12:31:21+05:30 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ (cherry picked from commit ca2e919ecca35db412e772d7eadd6a7c4fb20e4b) - - - - - 49c2986e by Teo Camarasu at 2024-04-15T12:31:21+05:30 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 (cherry picked from commit 74b24a9b0084459b8aa426a502956bd332b4d0fb) - - - - - 3a2dfe28 by Zubin Duggal at 2024-04-15T12:31:21+05:30 Bump filepath submodule to 1.4.300.1 Bump directory submodule to 1.3.8.4 Bump process submodule to 1.6.18.0 - - - - - 753131c5 by Zubin Duggal at 2024-04-15T12:31:21+05:30 Bump process submodule to 1.6.19.0 - - - - - 940fda51 by Zubin Duggal at 2024-04-15T12:31:28+05:30 Prepare release 9.6.5 - - - - - 11d09a10 by Zubin Duggal at 2024-04-15T12:31:28+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - 3ead9102 by Zubin Duggal at 2024-04-15T12:31:28+05:30 Bump Cabal submodule to 3.10.3.0 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Foreign/C.hs - compiler/GHC/Settings/IO.hs - configure.ac - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/using-optimisation.rst - hadrian/src/Rules/Generate.hs - libffi-tarballs - libraries/Cabal - libraries/base/Data/Monoid.hs - libraries/base/Data/Semigroup.hs - libraries/base/Data/Semigroup/Internal.hs - libraries/base/GHC/Base.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/IO/all.T - libraries/base/tests/System/all.T - libraries/base/tests/all.T - libraries/directory - libraries/filepath - libraries/process - m4/fp_cc_linker_flag_try.m4 - rts/ARMOutlineAtomicsSymbols.h - rts/sm/NonMovingMark.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a1d8bb2a1ddf4f692e2bcdd1b84060fa8a3a0de...3ead91020194ab36ad5c0658fbd2ae8e5797b8bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a1d8bb2a1ddf4f692e2bcdd1b84060fa8a3a0de...3ead91020194ab36ad5c0658fbd2ae8e5797b8bf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 07:44:26 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 03:44:26 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] Cherry pick Message-ID: <661cdadaa321a_200a3f387b1058041@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: 21ab2c1f by Zubin Duggal at 2024-04-15T13:13:21+05:30 Cherry pick * Fix some primitives defined in GHC.JS.Prim from Base/JS: GHC.JS.Foreign.Callback module (issue 23126) (cherry picked from commit 27d2978e5412f2bef4448e208182a03137dd5ee8) - - - - - 1 changed file: - libraries/base/GHC/JS/Prim.hs Changes: ===================================== libraries/base/GHC/JS/Prim.hs ===================================== @@ -277,13 +277,13 @@ foreign import javascript unsafe "(($1) => { return ($1 === null); })" foreign import javascript unsafe "(($1) => { return ($1 === undefined); })" js_isUndefined :: JSVal -> Bool -foreign import javascript unsafe "(($1) => { return ($r = typeof($1) === 'number' ? ($1|0) : 0;); })" +foreign import javascript unsafe "(($1) => { return (typeof($1) === 'number' ? ($1|0) : 0); })" js_fromJSInt :: JSVal -> Int -foreign import javascript unsafe "(($1) => { return ($r = $1;); })" +foreign import javascript unsafe "(($1) => { return $1; })" js_toJSInt :: Int -> JSVal -foreign import javascript unsafe "$r = null;" +foreign import javascript unsafe "(() => { return null; })" js_null :: JSVal foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })" @@ -307,7 +307,6 @@ foreign import javascript unsafe "(($1,$2_1,$2_2) => { return $1[h$decodeUtf8z($ foreign import javascript unsafe "(($1_1,$1_2) => { return h$decodeUtf8z($1_1, $1_2); })" js_unpackJSStringUtf8## :: Addr# -> State# s -> (# State# s, JSVal# #) - foreign import javascript unsafe "(($1_1, $1_2) => { return h$decodeUtf8z($1_1,$1_2); })" js_unsafeUnpackJSStringUtf8## :: Addr# -> JSVal# View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21ab2c1f09d20b03d9d6feb4ab526adda0a53bc1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21ab2c1f09d20b03d9d6feb4ab526adda0a53bc1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 09:05:47 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 05:05:47 -0400 Subject: [Git][ghc/ghc][wip/9.6.5-backports] 4 commits: Disable `-fasm-shortcutting` on -O2 and warn about its usage. Message-ID: <661cedebdc977_200a3fdb243c608ef@gitlab.mail> Zubin pushed to branch wip/9.6.5-backports at Glasgow Haskell Compiler / GHC Commits: dd41d36f by Zubin Duggal at 2024-04-15T14:33:41+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - ea08f128 by Zubin Duggal at 2024-04-15T14:33:41+05:30 Bump Cabal submodule to 3.10.3.0 - - - - - 252188bb by Zubin Duggal at 2024-04-15T14:33:41+05:30 Cherry pick * Fix some primitives defined in GHC.JS.Prim from Base/JS: GHC.JS.Foreign.Callback module (issue 23126) (cherry picked from commit 27d2978e5412f2bef4448e208182a03137dd5ee8) - - - - - 650c34ab by Zubin Duggal at 2024-04-15T14:35:36+05:30 Prepare release 9.6.5 Metric Increase: MultiLayerModulesTH_Make Metric Decrease: MultiLayerModulesTH_Make - - - - - 15 changed files: - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Session.hs - configure.ac - docs/users_guide/9.6.3-notes.rst - docs/users_guide/9.6.4-notes.rst - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/using-optimisation.rst - libraries/Cabal - libraries/base/GHC/JS/Prim.hs - libraries/base/base.cabal - libraries/base/changelog.md - testsuite/tests/backpack/cabal/bkpcabal02/bkpcabal02.stdout - testsuite/tests/cabal/t18567/T18567.stderr Changes: ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -66,7 +66,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3 , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags - , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + -- Disabled due to https://gitlab.haskell.org/ghc/ghc/-/issues/24507 + , ncgEnableShortcutting = False -- gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3363,7 +3363,8 @@ fFlagsDeps = [ -- See Note [Updating flag description in the User's Guide] -- See Note [Supporting CLI completion] -- Please keep the list of flags below sorted alphabetically - flagSpec "asm-shortcutting" Opt_AsmShortcutting, + depFlagSpec "asm-shortcutting" Opt_AsmShortcutting + "this flag is disabled on this ghc version due to unsoundness concerns (https://gitlab.haskell.org/ghc/ghc/-/issues/24507)", flagGhciSpec "break-on-error" Opt_BreakOnError, flagGhciSpec "break-on-exception" Opt_BreakOnException, flagSpec "building-cabal-package" Opt_BuildingCabalPackage, @@ -4002,7 +4003,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CaseMerge) , ([1,2], Opt_CaseFolding) , ([1,2], Opt_CmmElimCommonBlocks) - , ([2], Opt_AsmShortcutting) + -- Disabled due to #24507 + -- , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.6.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are ===================================== docs/users_guide/9.6.3-notes.rst ===================================== @@ -149,42 +149,3 @@ Included libraries The package database provided with this distribution also contains a number of packages other than GHC itself. See the changelogs provided with these packages for further change information. - -.. ghc-package-list:: - - libraries/array/array.cabal: Dependency of ``ghc`` library - libraries/base/base.cabal: Core library - libraries/binary/binary.cabal: Dependency of ``ghc`` library - libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library - libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility - libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility - libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library - libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library - libraries/directory/directory.cabal: Dependency of ``ghc`` library - libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library - libraries/filepath/filepath.cabal: Dependency of ``ghc`` library - compiler/ghc.cabal: The compiler itself - libraries/ghci/ghci.cabal: The REPL interface - libraries/ghc-boot/ghc-boot.cabal: Internal compiler library - libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library - libraries/ghc-compact/ghc-compact.cabal: Core library - libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library - libraries/ghc-prim/ghc-prim.cabal: Core library - libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable - libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable - libraries/integer-gmp/integer-gmp.cabal: Core library - libraries/libiserv/libiserv.cabal: Internal compiler library - libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library - libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library - libraries/pretty/pretty.cabal: Dependency of ``ghc`` library - libraries/process/process.cabal: Dependency of ``ghc`` library - libraries/stm/stm.cabal: Dependency of ``haskeline`` library - libraries/template-haskell/template-haskell.cabal: Core library - libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library - libraries/text/text.cabal: Dependency of ``Cabal`` library - libraries/time/time.cabal: Dependency of ``ghc`` library - libraries/transformers/transformers.cabal: Dependency of ``ghc`` library - libraries/unix/unix.cabal: Dependency of ``ghc`` library - libraries/Win32/Win32.cabal: Dependency of ``ghc`` library - libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable - ===================================== docs/users_guide/9.6.4-notes.rst ===================================== @@ -87,42 +87,3 @@ Included libraries The package database provided with this distribution also contains a number of packages other than GHC itself. See the changelogs provided with these packages for further change information. - -.. ghc-package-list:: - - libraries/array/array.cabal: Dependency of ``ghc`` library - libraries/base/base.cabal: Core library - libraries/binary/binary.cabal: Dependency of ``ghc`` library - libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library - libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility - libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility - libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library - libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library - libraries/directory/directory.cabal: Dependency of ``ghc`` library - libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library - libraries/filepath/filepath.cabal: Dependency of ``ghc`` library - compiler/ghc.cabal: The compiler itself - libraries/ghci/ghci.cabal: The REPL interface - libraries/ghc-boot/ghc-boot.cabal: Internal compiler library - libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library - libraries/ghc-compact/ghc-compact.cabal: Core library - libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library - libraries/ghc-prim/ghc-prim.cabal: Core library - libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable - libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable - libraries/integer-gmp/integer-gmp.cabal: Core library - libraries/libiserv/libiserv.cabal: Internal compiler library - libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library - libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library - libraries/pretty/pretty.cabal: Dependency of ``ghc`` library - libraries/process/process.cabal: Dependency of ``ghc`` library - libraries/stm/stm.cabal: Dependency of ``haskeline`` library - libraries/template-haskell/template-haskell.cabal: Core library - libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library - libraries/text/text.cabal: Dependency of ``Cabal`` library - libraries/time/time.cabal: Dependency of ``ghc`` library - libraries/transformers/transformers.cabal: Dependency of ``ghc`` library - libraries/unix/unix.cabal: Dependency of ``ghc`` library - libraries/Win32/Win32.cabal: Dependency of ``ghc`` library - libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable - ===================================== docs/users_guide/9.6.5-notes.rst ===================================== @@ -0,0 +1,111 @@ +.. _release-9.6.5: + +Version 9.6.5 +============== + +The significant changes to the various parts of the compiler are listed below. +See the `migration guide +`_ on the GHC Wiki +for specific guidance on migrating programs to this release. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +11, 12, 13, 14 or 15. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Disable ``-fasm-shortcutting`` with ``-O2`` as it leads to unsound optimisations + (:ghc-ticket:`24462). +- Fix a typechecker bug resulting in ``TYPE`` and ``CONSTRAINT`` being apart + (:ghc-ticket:`24279`). +- Fix a bug resulting in incorrect runtime results due to a botched simplifier + pass (:ghc-ticket:`24295`). +- Assign correct source spans to nested documentation comments in the AST (:ghc-ticket:`24378`). +- Fix a bug causing suboptimal error messages for certain invalid cyclic + module graphs with hs-boot files (:ghc-ticket:`24196`, :ghc-ticket:`24275`). +- Fix a bug resulting in infix ``(~)`` and ``(@)`` operators not being usable in + TH quotes (:ghc-ticket:`23748`). +- Fix a bug arising from incorrect parsing of paths containing spaces in the + settings file (:ghc-ticket:`24265`). +- Allow special pragmas to desugar correctly in a few more cases (:ghc-ticket:`24370`). + +Runtime system +-------------- + +- Fix an off-by-one while writing eventlogs (:ghc-ticket:`24287`). +- Avoid segfaults with using ``-Dn`` with the non-moving collector (:ghc-ticket:`24393`). + +Build system and packaging +-------------------------- + +- Fix a bug resulting in the distributed ``hsc2hs`` wrapper using flags from the + compiler build environment (:ghc-ticket:`24050`). +- Better compatibility for newer alex versions in the configure script (:ghc-ticket:`24302`). +- Handle autotools adding the ``-std`` flag to the ``CC``/``CXX`` variables (:ghc-ticket:`24324`). +- Fix a typo in the configure script resulting in the target for the linker being set incorrectly + when configuring a cross-compiler (:ghc-ticket:`24414`). +- Do not override existing linker flags in ``FP_LD_NO_FIXUP_CHAINS``. +- Ensure the ``genapply`` program is built with the write constants when cross compiling (:ghc-ticket:`24347`). +- Ensure we take ``LDFLAGS`` into account when configuring a linker (:ghc-ticket:`24565`). +- Fix a segfault with the non-moving GC (:ghc-ticket:`24492`). + +Core libraries +-------------- + +- Bump ``base`` to 4.18.2.1 +- Bump ``filepath`` to 1.4.300.1 +- Bump ``directory`` to 1.3.8.4 +- Bump ``Cabal`` to 3.10.3.0 +- Bump ``process`` to 1.6.19.0 +- Bump ``libffi-tarballs`` to 3.4.6 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/bugs.rst ===================================== @@ -697,6 +697,9 @@ Bugs in GHC - ``-Wincomplete-record-updates`` does not warn about record updates for records with partial record fields since GHC 9.6.1. See :ghc-ticket:`23520` for more details. +- ``-fasm-shortcutting`` may result in unsound optimisations and result in incorrect + runtime results. See :ghc-ticket:`24507` for more details. + .. _bugs-ghci: Bugs in GHCi (the interactive GHC) ===================================== docs/users_guide/release-notes.rst ===================================== @@ -8,3 +8,4 @@ Release notes 9.6.2-notes 9.6.3-notes 9.6.4-notes + 9.6.5-notes ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -250,7 +250,7 @@ by saying ``-fno-wombat``. generator, merging basic blocks and avoiding jumps right after jumps. .. ghc-flag:: -fasm-shortcutting - :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. + :shortdesc: Enable shortcutting on assembly. :type: dynamic :reverse: -fno-asm-shortcutting :category: @@ -267,6 +267,9 @@ by saying ``-fno-wombat``. these. Note that due to platform limitations (:ghc-ticket:`21972`) this flag does nothing on macOS. + This flag is known to result in unsoundness in this version of GHC + (:ghc-ticket:`24507`). + .. ghc-flag:: -fblock-layout-cfg :shortdesc: Use the new cfg based block layout algorithm. :type: dynamic ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 6c95f3fee3cdee859704b6476646cefd4628a850 +Subproject commit 256f85d735310196d437ede86046f2a86efedc6d ===================================== libraries/base/GHC/JS/Prim.hs ===================================== @@ -277,13 +277,13 @@ foreign import javascript unsafe "(($1) => { return ($1 === null); })" foreign import javascript unsafe "(($1) => { return ($1 === undefined); })" js_isUndefined :: JSVal -> Bool -foreign import javascript unsafe "(($1) => { return ($r = typeof($1) === 'number' ? ($1|0) : 0;); })" +foreign import javascript unsafe "(($1) => { return (typeof($1) === 'number' ? ($1|0) : 0); })" js_fromJSInt :: JSVal -> Int -foreign import javascript unsafe "(($1) => { return ($r = $1;); })" +foreign import javascript unsafe "(($1) => { return $1; })" js_toJSInt :: Int -> JSVal -foreign import javascript unsafe "$r = null;" +foreign import javascript unsafe "(() => { return null; })" js_null :: JSVal foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })" @@ -307,7 +307,6 @@ foreign import javascript unsafe "(($1,$2_1,$2_2) => { return $1[h$decodeUtf8z($ foreign import javascript unsafe "(($1_1,$1_2) => { return h$decodeUtf8z($1_1, $1_2); })" js_unpackJSStringUtf8## :: Addr# -> State# s -> (# State# s, JSVal# #) - foreign import javascript unsafe "(($1_1, $1_2) => { return h$decodeUtf8z($1_1,$1_2); })" js_unsafeUnpackJSStringUtf8## :: Addr# -> JSVal# ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.18.2.0 +version: 4.18.2.1 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause ===================================== libraries/base/changelog.md ===================================== @@ -1,5 +1,8 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.18.2.1 *April 2024* + * Various documentation improvements + ## 4.18.2.0 *January 2024* * Update to [Unicode 15.1.0](https://www.unicode.org/versions/Unicode15.1.0/). * Improve String & IsString documentation. ===================================== testsuite/tests/backpack/cabal/bkpcabal02/bkpcabal02.stdout ===================================== @@ -4,4 +4,4 @@ for bkpcabal01-0.1.0.0.. Preprocessing library 'q' for bkpcabal01-0.1.0.0.. Building library 'q' instantiated with H = for bkpcabal01-0.1.0.0.. -[2 of 2] Instantiating bkpcabal01-0.1.0.0-1lAnZxoLksL6JibM6aQmCb-p +[2 of 2] Instantiating bkpcabal01-0.1.0.0-KBjRdbt55q65bC24wEhN1Q-p ===================================== testsuite/tests/cabal/t18567/T18567.stderr ===================================== @@ -2,4 +2,4 @@ : warning: [GHC-42258] [-Wunused-packages] The following packages were specified via -package or -package-id flags, but were not needed for compilation: - - internal-lib-0.1.0.0 (exposed by flag -package-id internal-lib-0.1.0.0-7jHSByQDwC214cJdttV4hN-sublib-unused) + - internal-lib-0.1.0.0 (exposed by flag -package-id internal-lib-0.1.0.0-85MtRTf8HPX4Uo1lkUlkVq-sublib-unused) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21ab2c1f09d20b03d9d6feb4ab526adda0a53bc1...650c34ab4e1cefb521209b143ecd75367ec03ee1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21ab2c1f09d20b03d9d6feb4ab526adda0a53bc1...650c34ab4e1cefb521209b143ecd75367ec03ee1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 09:17:03 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 05:17:03 -0400 Subject: [Git][ghc/ghc][wip/T24651] wip Message-ID: <661cf08f52815_200a3ff9daa8615a9@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: 24f860c6 by Teo Camarasu at 2024-04-15T10:16:52+01:00 wip - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,14 +557,15 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz - - haddock/* + - docs/haddock/ - libraries.html.tar.xz - - libraries/* + - docs/libraries/ - users_guide.html.tar.xz - - users_guide/* - - index.html + - docs/users_guide/ + - docs/index.html - "*.pdf" script: - | @@ -584,10 +585,8 @@ doc-tarball: exit 1 fi - rm -Rf docs - - rm -R libraries - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST - - ls -lh - - mv docs/*.tar.xz docs/index.html . + - mv docs/*.tar.xz . hackage-doc-tarball: stage: packaging View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24f860c6d19c0469b284d8b491f4340b16b82643 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24f860c6d19c0469b284d8b491f4340b16b82643 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 09:18:17 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 05:18:17 -0400 Subject: [Git][ghc/ghc][wip/T24651] wip Message-ID: <661cf0d9d39ef_200a3f10334cc6225b@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: a80009e9 by Teo Camarasu at 2024-04-15T10:18:09+01:00 wip - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -566,7 +566,6 @@ doc-tarball: - users_guide.html.tar.xz - docs/users_guide/ - docs/index.html - - "*.pdf" script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a80009e9b9d8f45244d5e3b01c4f28d2bd09730f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a80009e9b9d8f45244d5e3b01c4f28d2bd09730f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 09:58:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 15 Apr 2024 05:58:30 -0400 Subject: [Git][ghc/ghc][wip/fendor/iface-sharing] 6 commits: Add deduplication table for `IfaceType` Message-ID: <661cfa46f1036_200a3f1552d2c6983d@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/iface-sharing at Glasgow Haskell Compiler / GHC Commits: 03084bcc by Matthew Pickering at 2024-04-15T11:52:42+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - d64cfe21 by Matthew Pickering at 2024-04-15T11:54:14+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 5610aa86 by Matthew Pickering at 2024-04-15T11:54:14+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 2a19c5c5 by Fendor at 2024-04-15T11:54:15+02:00 WIP: CI results for Data.Map deduplication - - - - - 292f6f81 by Matthew Pickering at 2024-04-15T11:54:15+02:00 Only share IfaceTyConApp - - - - - c5077818 by Fendor at 2024-04-15T11:56:54+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingFastString.hs - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f44fa5e4f8e7d98f8192c164a6dc4f24b3f19cdf...c5077818d5893f5ab5e58bd06306faa59b54c1c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f44fa5e4f8e7d98f8192c164a6dc4f24b3f19cdf...c5077818d5893f5ab5e58bd06306faa59b54c1c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 10:01:24 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 15 Apr 2024 06:01:24 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-delay-serialisation] 8 commits: Add deduplication table for `IfaceType` Message-ID: <661cfaf4b2185_200a3f15cd9c8700e9@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-delay-serialisation at Glasgow Haskell Compiler / GHC Commits: 03084bcc by Matthew Pickering at 2024-04-15T11:52:42+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - d64cfe21 by Matthew Pickering at 2024-04-15T11:54:14+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 5610aa86 by Matthew Pickering at 2024-04-15T11:54:14+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 2a19c5c5 by Fendor at 2024-04-15T11:54:15+02:00 WIP: CI results for Data.Map deduplication - - - - - 292f6f81 by Matthew Pickering at 2024-04-15T11:54:15+02:00 Only share IfaceTyConApp - - - - - c5077818 by Fendor at 2024-04-15T11:56:54+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 003ac7de by Matthew Pickering at 2024-04-15T12:01:15+02:00 Delay deserialisation of `IfaceType` until needed Introduces `IfaceSerialisationType` which holds onto a ByteString in-memory. All `IfaceType`'s are first deserialised to `IfaceSerialisationType`, so no actual deserialisation happens until the value is requested. Then, we decode `IfaceSerialisationType` into the real `IfaceType` value. - - - - - 939a1c74 by Matthew Pickering at 2024-04-15T12:01:17+02:00 MP fixes - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingFastString.hs - + testsuite/tests/iface/IfaceSharingIfaceType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2076ed5d2193fef27ec89fb56da506d37921bca3...939a1c746f49bab04821ae7615bccb8005020519 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2076ed5d2193fef27ec89fb56da506d37921bca3...939a1c746f49bab04821ae7615bccb8005020519 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 10:04:14 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 15 Apr 2024 06:04:14 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 5 commits: Add deduplication table for `IfaceType` Message-ID: <661cfb9e896ce_200a3f163d96c702f7@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 03084bcc by Matthew Pickering at 2024-04-15T11:52:42+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. On the agda code base, we reduce the size from 28 MB to 16 MB. When `-fwrite-simplified-core` is enabled, we reduce the size from 112 MB to 22 MB. We have to add an `Ord` instance to `IfaceType` in order to store it efficiently for look up operations. This is mostly straightforward, we change occurrences of `FastString` with `LexicalFastString` and add a newtype definition for `IfLclName = LexicalFastString`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule for `IfLclName` newtype changes. - - - - - a3ee7d75 by Matthew Pickering at 2024-04-15T12:03:56+02:00 Add some tests to check for size of interface files when serialising various types - - - - - ceb6affc by Matthew Pickering at 2024-04-15T12:03:56+02:00 WIP: TrieMap for IfaceType Bump haddock submodule - - - - - 3433bfa7 by Fendor at 2024-04-15T12:03:56+02:00 WIP: CI results for Data.Map deduplication - - - - - 2cb923aa by Matthew Pickering at 2024-04-15T12:03:56+02:00 Only share IfaceTyConApp - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingFastString.hs - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/829f88c9c22a96d48e121b4769924c7a6ef63e28...2cb923aaa581cee627fe6c2fd351142bbe6c82bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/829f88c9c22a96d48e121b4769924c7a6ef63e28...2cb923aaa581cee627fe6c2fd351142bbe6c82bb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:46:24 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:46:24 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/22022-mark-T21336a-fragile Message-ID: <661d13902f3bd_200a3f2558a3c101187@gitlab.mail> Bryan R deleted branch wip/22022-mark-T21336a-fragile at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:00 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:00 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/b/T21336a-skip-wasm Message-ID: <661d164815a1c_200a3f26f2398104970@gitlab.mail> Bryan R deleted branch wip/b/T21336a-skip-wasm at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:10 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:10 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/b/fragile Message-ID: <661d1652b4cfa_200a3f271042410535a@gitlab.mail> Bryan R deleted branch wip/b/fragile at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:08 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:08 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/b/cabal-reinstall-job Message-ID: <661d165022070_200a3f271097410512a@gitlab.mail> Bryan R deleted branch wip/b/cabal-reinstall-job at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:13 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:13 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/b/missing-prototypes Message-ID: <661d165526c44_200a3f272a144105581@gitlab.mail> Bryan R deleted branch wip/b/missing-prototypes at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:16 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:16 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/git-fetch-failure Message-ID: <661d16585f8e8_200a3f2749fe4105761@gitlab.mail> Bryan R deleted branch wip/git-fetch-failure at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:18 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:18 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/no-libghc-pvp Message-ID: <661d165ac71fd_200a3f2766824106152@gitlab.mail> Bryan R deleted branch wip/no-libghc-pvp at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 11:58:18 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 07:58:18 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/mark-fragile-tests Message-ID: <661d165a4c163_200a3f274afac105910@gitlab.mail> Bryan R deleted branch wip/mark-fragile-tests at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 12:02:58 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 08:02:58 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/b/freebsd Message-ID: <661d177295c2d_200a3f28292fc107185@gitlab.mail> Bryan R pushed new branch wip/b/freebsd at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/b/freebsd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 12:10:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 15 Apr 2024 08:10:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: rts: Improve tracing message when nursery is resized Message-ID: <661d19454b43e_200a3f2913d481084b9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 251077e2 by Andreas Klebinger at 2024-04-15T08:10:23-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 0eab8caa by Alan Zimmerman at 2024-04-15T08:10:24-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 30 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Hs.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Module.hs - compiler/GHC/Types/Id/Make.hs - rts/sm/Storage.c - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58bfbeb7ccdc9d485c3c4d722f03fe0af742b841...0eab8caa6bff55364c528f8b58c009ab9e1bd0e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58bfbeb7ccdc9d485c3c4d722f03fe0af742b841...0eab8caa6bff55364c528f8b58c009ab9e1bd0e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 12:18:24 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 15 Apr 2024 08:18:24 -0400 Subject: [Git][ghc/ghc][ghc-9.6] 41 commits: rts: Various warnings fixes Message-ID: <661d1b102c5d2_200a3f2b89f781176ef@gitlab.mail> Zubin pushed to branch ghc-9.6 at Glasgow Haskell Compiler / GHC Commits: 27bfad83 by Ben Gamari at 2024-03-26T14:09:03+05:30 rts: Various warnings fixes (cherry picked from commit 1e48c43483693398001bfb0ae644a3558bf6a9f3) - - - - - 04ca575c by Cheng Shao at 2024-04-02T15:06:39+05:30 compiler: fix eager blackhole symbol in wasm32 NCG (cherry picked from commit fe50eb3510ca730c4d2fc57778d380fdc493abd8) - - - - - b89427db by Cheng Shao at 2024-04-02T15:07:17+05:30 testsuite: fix optasm tests for wasm32 (cherry picked from commit af77114815ad9052261898c830171e49fbed5160) - - - - - 8bfaa7a4 by Matthew Pickering at 2024-04-02T15:08:07+05:30 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. (cherry picked from commit 1b90735c99f1179328f6dd67dbcc81f964901a19) - - - - - 69b6dcb7 by PHO at 2024-04-02T15:09:07+05:30 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. (cherry picked from commit 52c0fc691e6501e99a96693ec1fc02e3c93a4fbc) - - - - - 2fb2272b by mmzk1526 at 2024-04-02T15:09:26+05:30 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". (cherry picked from commit c7be0c680d96ba6209c86e509ab2682e5041a53d) - - - - - db500aef by Matthew Craven at 2024-04-02T15:11:32+05:30 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. (cherry picked from commit ae9cc1a84c9f470b77d98423400e6dfa95b2449b) - - - - - 7a0b40b5 by Simon Peyton Jones at 2024-04-02T15:12:18+05:30 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. (cherry picked from commit af6932d6c068361c6ae300d52e72fbe13f8e1f18) - - - - - 16243c32 by Matthew Pickering at 2024-04-02T15:12:33+05:30 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 (cherry picked from commit 5776008c7a5581193c3e72e59451ad49abac9d81) - - - - - dea31f2c by Jade at 2024-04-02T15:14:31+05:30 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 (cherry picked from commit ab47a43d64f6b7d4fc181645171c31ba2db1eebe) - - - - - 0632a1f1 by Hécate Moonlight at 2024-04-02T15:15:10+05:30 Clarification for newtype constructors when using `coerce` (cherry picked from commit 699da01bbbf3e42c7d38b9cfe443dd0e8e256342) - - - - - 111d1613 by Patrick at 2024-04-02T15:16:13+05:30 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. (cherry picked from commit 8eeadfad3a0035f8c5b339782676ff23572e0e5e) - - - - - 9f893fe9 by Teo Camarasu at 2024-04-02T15:16:46+05:30 doc: Add -Dn flag to user guide Resolves #24394 (cherry picked from commit 94ce031ddc84ee702c12a11793028ef21e65fa00) - - - - - 7a9555f5 by Rodrigo Mesquita at 2024-04-02T15:17:03+05:30 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 (cherry picked from commit cdddeb0f1280b40cc194028bbaef36e127175c4c) - - - - - 1ad632d2 by Zubin Duggal at 2024-04-02T15:17:15+05:30 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 (cherry picked from commit 532993c8160d960f848e7abd401774b6879e3ee8) - - - - - c821fd7c by Matthew Pickering at 2024-04-02T15:17:30+05:30 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 (cherry picked from commit d309f4e7e37f3795c6d6b150c407d5a9b332854e) - - - - - 7c78d930 by Matthew Craven at 2024-04-02T15:25:17+05:30 Add @since annotation to Data.Data.mkConstrTag (cherry picked from commit 249caf0d2345ac2e6046847522bb8f2fff7f8835) - - - - - ae4e8004 by Jade at 2024-04-02T15:26:07+05:30 Enhance documentation of Data.Complex (cherry picked from commit cdd939e77f2bb20f80310280400b3426598b4eca) - - - - - afabec98 by Rodrigo Mesquita at 2024-04-02T15:26:35+05:30 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS (cherry picked from commit 9460d5044b8c7239fb7a6ce875d084617f159c7f) - - - - - 2ca013d7 by Teo Camarasu at 2024-04-02T15:26:51+05:30 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 (cherry picked from commit 84357d1143fe4f9076253160f78fac6c2acc8e5b) - - - - - 622d76d6 by j at 2024-04-02T15:31:35+05:30 Disable several ignore-warning flags in genapply. (cherry picked from commit faea4bcdf4e71120a5480530fb1879e4439ed512) - - - - - a1bf252e by Cheng Shao at 2024-04-02T15:33:24+05:30 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. (cherry picked from commit dd4af0e5a4a3af208bdf57e8237d85261eef24f7) - - - - - a4767444 by Ben Gamari at 2024-04-02T16:45:26+05:30 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. (cherry picked from commit efcbad2dfd242d0bc2c91da5390fe8456a536cc3) (cherry picked from commit 2eca9c7afedda0b08316b16b0bfd31c60c201ce6) - - - - - b3c2901c by Matthew Pickering at 2024-04-02T16:45:26+05:30 ci: Show --info for installed compiler (cherry picked from commit c540559cf188625bec668fa6cd94d4f94413d730) (cherry picked from commit d5246e19ebf9a9ddb8dcf04f513e3d365f9d453d) - - - - - f5eaaab5 by Hécate Moonlight at 2024-04-02T16:45:26+05:30 Improve the synopsis and description of base (cherry picked from commit 0eb2265d816f733094506034ba6285a447ebd3a5) - - - - - 7d95c980 by Vladislav Zavialov at 2024-04-02T16:45:26+05:30 Fix (~) and (@) infix operators in TH splices (#23748) 8168b42a "Whitespace-sensitive bang patterns" allows GHC to accept the following infix operators: a ~ b = () a @ b = () But not if TH is used to generate those declarations: $([d| a ~ b = () a @ b = () |]) -- Test.hs:5:2: error: [GHC-55017] -- Illegal variable name: ‘~’ -- When splicing a TH declaration: (~_0) a_1 b_2 = GHC.Tuple.Prim.() This is easily fixed by modifying `reservedOps` in GHC.Utils.Lexeme (cherry picked from commit 46fd8ced0cc031f2e50a1a4b348738fd39b4a741) - - - - - d74ffbbb by Fendor at 2024-04-15T12:31:20+05:30 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. (cherry picked from commit 31bf85ee49fe2ca0b17eaee0774e395f017a9373) - - - - - a5a7a0ce by Florian Weimer at 2024-04-15T12:31:20+05:30 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> (cherry picked from commit 1f534c2e7388273e70534680212c1357614c11ed) - - - - - af368514 by Rodrigo Mesquita at 2024-04-15T12:31:20+05:30 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. (cherry picked from commit 32a8103f3b3e22907fdd67b69c919c5251d8cc20) - - - - - 7ca2ca58 by Cheng Shao at 2024-04-15T12:31:21+05:30 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. (cherry picked from commit 810660b780e1111b36c91326bcd0041e1f62706b) - - - - - 291db356 by Cheng Shao at 2024-04-15T12:31:21+05:30 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. (cherry picked from commit 7db8c9927fae3369fc4ecff68f80c4cb32eea757) - - - - - 014e9ad9 by Cheng Shao at 2024-04-15T12:31:21+05:30 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. (cherry picked from commit ce580426ce3052e3b3d2847d0312652ea9087994) - - - - - cd3a199f by Jade at 2024-04-15T12:31:21+05:30 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid (cherry picked from commit fa4e5913251786f2b535b31abd3fad39da8b3602) - - - - - b895d534 by Simon Peyton Jones at 2024-04-15T12:31:21+05:30 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ (cherry picked from commit ca2e919ecca35db412e772d7eadd6a7c4fb20e4b) - - - - - 49c2986e by Teo Camarasu at 2024-04-15T12:31:21+05:30 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 (cherry picked from commit 74b24a9b0084459b8aa426a502956bd332b4d0fb) - - - - - 3a2dfe28 by Zubin Duggal at 2024-04-15T12:31:21+05:30 Bump filepath submodule to 1.4.300.1 Bump directory submodule to 1.3.8.4 Bump process submodule to 1.6.18.0 - - - - - 753131c5 by Zubin Duggal at 2024-04-15T12:31:21+05:30 Bump process submodule to 1.6.19.0 - - - - - dd41d36f by Zubin Duggal at 2024-04-15T14:33:41+05:30 Disable `-fasm-shortcutting` on -O2 and warn about its usage. This flag is known to result in unsound optimisations potentially resulting in incorrect runtime behaviour (#24507). (cherry picked from commit 4ae8d89e376d79b4188c61e6469c7f01d8445768) - - - - - ea08f128 by Zubin Duggal at 2024-04-15T14:33:41+05:30 Bump Cabal submodule to 3.10.3.0 - - - - - 252188bb by Zubin Duggal at 2024-04-15T14:33:41+05:30 Cherry pick * Fix some primitives defined in GHC.JS.Prim from Base/JS: GHC.JS.Foreign.Callback module (issue 23126) (cherry picked from commit 27d2978e5412f2bef4448e208182a03137dd5ee8) - - - - - 650c34ab by Zubin Duggal at 2024-04-15T14:35:36+05:30 Prepare release 9.6.5 Metric Increase: MultiLayerModulesTH_Make Metric Decrease: MultiLayerModulesTH_Make - - - - - 30 changed files: - .gitlab/ci.sh - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Graph/Directed.hs - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Foreign/C.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Settings/IO.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Heap.hs - compiler/GHC/StgToCmm/Monad.hs - compiler/GHC/StgToCmm/Sequel.hs - compiler/GHC/Utils/Lexeme.hs - configure.ac - distrib/configure.ac.in - docs/users_guide/9.6.3-notes.rst - docs/users_guide/9.6.4-notes.rst - + docs/users_guide/9.6.5-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/release-notes.rst - docs/users_guide/runtime_control.rst - docs/users_guide/using-optimisation.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3187fc7644a41c182ec35292389b61bc0575e80b...650c34ab4e1cefb521209b143ecd75367ec03ee1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3187fc7644a41c182ec35292389b61bc0575e80b...650c34ab4e1cefb521209b143ecd75367ec03ee1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 12:42:31 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 15 Apr 2024 08:42:31 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23338 Message-ID: <661d20b75341_12e3fc2705d8569eb@gitlab.mail> Jade pushed new branch wip/T23338 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23338 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 12:43:17 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 15 Apr 2024 08:43:17 -0400 Subject: [Git][ghc/ghc][wip/b/freebsd] Remove unrunnable FreeBSD CI jobs Message-ID: <661d20e4e3670_12e3fc2b9e9057117@gitlab.mail> Bryan R pushed to branch wip/b/freebsd at Glasgow Haskell Compiler / GHC Commits: 2fb3ac57 by Bryan Richter at 2024-04-15T15:42:21+03:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 2 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -995,7 +995,6 @@ job_groups = , fastCI (standardBuildsWithConfig Amd64 Windows vanilla) , disableValidate (standardBuildsWithConfig Amd64 Windows nativeInt) , addValidateRule TestPrimops (standardBuilds Amd64 Darwin) - , allowFailureGroup (onlyRule FreeBSDLabel (validateBuilds Amd64 FreeBSD13 vanilla)) , fastCI (standardBuilds AArch64 Darwin) , fastCI (standardBuildsWithConfig AArch64 (Linux Debian10) (splitSectionsBroken vanilla)) , disableValidate (standardBuildsWithConfig AArch64 (Linux Debian11) (splitSectionsBroken vanilla)) ===================================== .gitlab/jobs.yaml ===================================== @@ -695,70 +695,6 @@ "ac_cv_func_utimensat": "no" } }, - "nightly-x86_64-freebsd13-validate": { - "after_script": [ - ".gitlab/ci.sh save_cache", - ".gitlab/ci.sh save_test_output", - ".gitlab/ci.sh clean", - "cat ci_timings" - ], - "allow_failure": true, - "artifacts": { - "expire_in": "8 weeks", - "paths": [ - "ghc-x86_64-freebsd13-validate.tar.xz", - "junit.xml", - "unexpected-test-output.tar.gz" - ], - "reports": { - "junit": "junit.xml" - }, - "when": "always" - }, - "cache": { - "key": "x86_64-freebsd13-$CACHE_REV", - "paths": [ - "cabal-cache", - "toolchain" - ] - }, - "dependencies": [], - "image": null, - "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } - ], - "rules": [ - { - "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", - "when": "on_success" - } - ], - "script": [ - ".gitlab/ci.sh setup", - ".gitlab/ci.sh configure", - ".gitlab/ci.sh build_hadrian", - ".gitlab/ci.sh test_hadrian" - ], - "stage": "full-build", - "tags": [ - "x86_64-freebsd13" - ], - "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate", - "BUILD_FLAVOUR": "validate", - "CABAL_INSTALL_VERSION": "3.10.2.0", - "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib --enable-strict-ghc-toolchain-check", - "GHC_VERSION": "9.6.4", - "HADRIAN_ARGS": "--docs=no-sphinx", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-freebsd13-validate", - "XZ_OPT": "-9" - } - }, "nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", @@ -4466,69 +4402,6 @@ "ac_cv_func_utimensat": "no" } }, - "x86_64-freebsd13-validate": { - "after_script": [ - ".gitlab/ci.sh save_cache", - ".gitlab/ci.sh save_test_output", - ".gitlab/ci.sh clean", - "cat ci_timings" - ], - "allow_failure": true, - "artifacts": { - "expire_in": "2 weeks", - "paths": [ - "ghc-x86_64-freebsd13-validate.tar.xz", - "junit.xml", - "unexpected-test-output.tar.gz" - ], - "reports": { - "junit": "junit.xml" - }, - "when": "always" - }, - "cache": { - "key": "x86_64-freebsd13-$CACHE_REV", - "paths": [ - "cabal-cache", - "toolchain" - ] - }, - "dependencies": [], - "image": null, - "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } - ], - "rules": [ - { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "on_success" - } - ], - "script": [ - ".gitlab/ci.sh setup", - ".gitlab/ci.sh configure", - ".gitlab/ci.sh build_hadrian", - ".gitlab/ci.sh test_hadrian" - ], - "stage": "full-build", - "tags": [ - "x86_64-freebsd13" - ], - "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate", - "BUILD_FLAVOUR": "validate", - "CABAL_INSTALL_VERSION": "3.10.2.0", - "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib --enable-strict-ghc-toolchain-check", - "GHC_VERSION": "9.6.4", - "HADRIAN_ARGS": "--docs=no-sphinx", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-freebsd13-validate" - } - }, "x86_64-linux-alpine3_12-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2fb3ac573d77b163d140b39d3b47cbeb85903636 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2fb3ac573d77b163d140b39d3b47cbeb85903636 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 13:18:54 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 15 Apr 2024 09:18:54 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 5 commits: Add Eq and Ord instance to IfaceType Message-ID: <661d293e133ce_12e3fc69474065273@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: f6d49535 by Fendor at 2024-04-15T14:56:52+02:00 Add Eq and Ord instance to IfaceType Bump haddock submodule for IfLclName changes - - - - - 5297584c by Fendor at 2024-04-15T15:03:22+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 783a7308 by Matthew Pickering at 2024-04-15T15:18:47+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. - - - - - c75e9e5d by Matthew Pickering at 2024-04-15T15:18:47+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 9eb585b9 by Fendor at 2024-04-15T15:18:47+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cb923aaa581cee627fe6c2fd351142bbe6c82bb...9eb585b99098a33058d645a1c63b9ed989708e55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cb923aaa581cee627fe6c2fd351142bbe6c82bb...9eb585b99098a33058d645a1c63b9ed989708e55 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 13:50:50 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Mon, 15 Apr 2024 09:50:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sand-witch/ty-pat-bidir Message-ID: <661d30ba44f3_12e3fcbad66468620@gitlab.mail> Andrei Borzenkov pushed new branch wip/sand-witch/ty-pat-bidir at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sand-witch/ty-pat-bidir You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 13:51:23 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 09:51:23 -0400 Subject: [Git][ghc/ghc][wip/T24651] Fix documentation preview from doc-tarball job Message-ID: <661d30dbbce2f_12e3fcc01520707eb@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: c7452da6 by Teo Camarasu at 2024-04-15T14:49:47+01:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 2 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,12 +557,15 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz + - docs/haddock/ - libraries.html.tar.xz + - docs/libraries/ - users_guide.html.tar.xz - - index.html - - "*.pdf" + - docs/users_guide/ + - docs/index.html script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ @@ -582,8 +585,8 @@ doc-tarball: fi - rm -Rf docs - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST - - ls -lh - - mv docs/*.tar.xz docs/index.html . + - mv docs/*.tar.xz docs/*.pdf . + - ls -al hackage-doc-tarball: stage: packaging ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,7 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7452da67da404aa9cc115d708141281a9eecfe0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7452da67da404aa9cc115d708141281a9eecfe0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 13:59:49 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 09:59:49 -0400 Subject: [Git][ghc/ghc][wip/T24651] Fix documentation preview from doc-tarball job Message-ID: <661d32d56526_12e3fce5abdc781e6@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: 7504406f by Teo Camarasu at 2024-04-15T14:59:20+01:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. - Fix GHC API URL in index.html. It was missing the "-inplace" suffix. Resolves #24651 - - - - - 3 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs - docs/index.html.in Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,12 +557,17 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz + - docs/haddock/ - libraries.html.tar.xz + - docs/libraries/ - users_guide.html.tar.xz - - index.html - - "*.pdf" + - docs/users_guide/ + - docs/index.html + - Haddock.pdf + - users_guide.pdf script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ @@ -582,8 +587,8 @@ doc-tarball: fi - rm -Rf docs - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST - - ls -lh - - mv docs/*.tar.xz docs/index.html . + - mv docs/*.tar.xz docs/*.pdf . + - ls -al hackage-doc-tarball: stage: packaging ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,7 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" ===================================== docs/index.html.in ===================================== @@ -39,7 +39,7 @@
  • - GHC API + GHC API

    Documentation for the GHC API. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7504406fd4523f6f9ee157f170dc90c208e17bb4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7504406fd4523f6f9ee157f170dc90c208e17bb4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 14:00:40 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 10:00:40 -0400 Subject: [Git][ghc/ghc][wip/T24651] Fix documentation preview from doc-tarball job Message-ID: <661d3308ce8c0_12e3fcf549c0786ee@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: b42b2e2a by Teo Camarasu at 2024-04-15T15:00:29+01:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. - Fix GHC API URL in index.html. It was missing the "-inplace" suffix. Resolves #24651 - - - - - 3 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs - docs/index.html.in Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,12 +557,17 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz + - docs/haddock/ - libraries.html.tar.xz + - docs/libraries/ - users_guide.html.tar.xz - - index.html - - "*.pdf" + - docs/users_guide/ + - docs/index.html + - Haddock.pdf + - users_guide.pdf script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ @@ -582,8 +587,8 @@ doc-tarball: fi - rm -Rf docs - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST + - mv docs/*.tar.xz docs/*.pdf . - ls -lh - - mv docs/*.tar.xz docs/index.html . hackage-doc-tarball: stage: packaging ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,7 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" ===================================== docs/index.html.in ===================================== @@ -39,7 +39,7 @@

  • - GHC API + GHC API

    Documentation for the GHC API. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b42b2e2a0439fd85e9eeff9a219b5841ccb0afac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b42b2e2a0439fd85e9eeff9a219b5841ccb0afac You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 14:54:36 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 15 Apr 2024 10:54:36 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] STM: Be more optimistic when validating in-flight transactions. Message-ID: <661d3fac49055_217f775048f816722@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: a90d1ba4 by Andreas Klebinger at 2024-04-15T16:39:31+02:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 8 changed files: - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T Changes: ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/STM.c ===================================== @@ -359,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -681,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -751,7 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } - // TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -941,17 +981,185 @@ void stmCondemnTransaction(Capability *cap, TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -// Check if a transaction is known to be invalid by this point. -// Currently we use this to: -// * Eagerly abort invalid transactions from the scheduler. -// * If an exception occured inside a transaction, decide weither or not to -// abort by checking if the transaction was valid. -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +To "validate" a transaction means to check that the transaction's log (Trec) is +consistent with the current state of memory; specifically, that any variable +observed (through reads AND writes) by the transaction has the same value in +memory as it did when the transaction read it. + +In some situations we can give ourself some leeway by allowing: +* False positives - The validation check claims the memory state is consistent when it isn't. +* False negatives - The validation check claims memory state is inconsistent when it + is in fact consistent. + +We validate a STM transaction for two purposes: + +(A) Post-run validation runs /after/ the transaction has completed, either during + commit or after an exception has occurred. + + This is done by validate_and_acquire_ownership. The commit process + /absolutely must/ be transactional: that is, it must read a consistent + snapshot of memory, compare with the log, and then atomically commit all the + writes in the log. We do this by locking the TVars. + + For post-run validation we must *never* allow false-positives for correctness + reasons. But we allow for false-negatives, trading occasional spurious retries + for performance in the average case. + + The implementation of performing this update atomically is mostly based on + the 2002 paper "A Practical Multi-Word Compare-and-Swap Operation" + +(B) In-flight validation runs /during/ the execution of the transaction. Suppose a transaction + is long-running, and memory has /already/ changed so that it is inconsistent with the + transaction's log. It is just conceivable that memory might change back again to be + consistent, but very unlikely. It is better to terminate and retry the transaction, + rather than let it run potentially forever as a zombie, and only retry when it attempts to commit. + + This is done by validate_trec_optimistic. Since in-flight validation at most results in early + termination of a transaction we may accept both + * a "false negative" (causing the transaction to retry unnecessarily), and + * a "false positive" (allowing the transaction to continue as a zombie). + + We want to run in-flight validation somewhat frequently to detect invalid + transactions early. We perform in-flight validation whenever a thread returns to + the scheduler, a convenient and regular opportunity. + +Note that in-flight validation is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +As noted above, post-run validation and commit /must/ be transactional, involving expensive locking. +But in-flight validation can accept false positives and false negatives. While we could lock TVars +during in-flight validation to rule out false positives, we don't have to: +it is much cheaper and very nearly as good simply to read them without locking allowing for +false-postive results. + +Moreover, locking during in-flight validation can cause lack of progress, or livelock (#24446) +through false-negative results. Suppose we have two long-running transactions, each doing successive +in-flight validation using locking. If the validation discovers a locked TVar it aborts and retries. +Now they can each abort the other, forever. +This *can* also happen with post-run validation. But since post-run validation occurs less +frequently it's incredibly unlikely to happen repeatedly compared to in-flight validation. + +Hence: locking during in-flight validation is + * Expensive + * Can lead to livelock-like conditions. + +Conclusion: + * don't use locking during in-flight validation. + * Use locking during post-run validation, where the risk of livelock is comparatively small + compared to the cost of ruling out live-lock completely. + +See below for other design alternatives. + +Design considerations about locking during in flight validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All else being equal we would always want to get a precise result for validation. +And indeed for the non-threaded runtime this is reasonably easy to achieve +(see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult, and ruling out false negatives/positives +would come at significant cost in the average case. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we use for post-run validation. +The trade off being that it can lead to false negatives during validation when multiple +threads perform validation in parallel. As long as the false-negative rate is +is reasonably low this is not problematic. + +However in-flight validation can happen multiple times per transaction. +So even a fairly low rate of spurious validation failures will result in a large +performance hit. In the worst case preventing progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve in-flight validation perf by allowing false positives. +This removes the need for tacking locks which means: + +Benefits +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. +The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. So we accept this behaviour. + +Design alternatives to improve in-flight false-postive rate: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + +A1: +Take locks for in-flight validation but don't fail if in-flight validation +encounters already locked tvars. +This would solve lock contention/false positives caused by concurrent in-flight validations. + +But it would still result in in-flight validation causing some false-negatives +during post-run validation by holding locks post-run validation is trying to take. + +It also doesn't *guaranteed* that we recognize looping transaction as invalid. +As the relevant tvars might be locked by other validations when we try to lock +them. So while this would improve over using regular lock tacking for in-flight +transactions it seems straight up worse than not taking locks to me in most +situations. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +locked tvars we encountered, as these are the only sources of false-positives. +This would give a hard upper bound on the number of false-positives while keeping +the impact on post-run validations lower. + +If the looping transaction issue turns out to be a real problem this might be worth +doing. + +A3: +When locking a tvar for a potential update keep the old value accessible. Then +in-flight validations should never return false-positives. However compared to A2 +this seems like it would come with a non-trivial overhead relative to the likelyhood +of these false-positives causing actual issues. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || @@ -960,8 +1168,13 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { t = trec; StgBool result = true; while (t != NO_TREC) { - // TODO: I don't think there is a need to lock any tvars here, all even less so. - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -972,7 +1185,6 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { ===================================== rts/STM.h ===================================== @@ -20,7 +20,7 @@ non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -84,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -110,7 +117,7 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in ===================================== rts/Schedule.c ===================================== @@ -1099,7 +1099,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,6 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [], compile_and_run, ['-threaded -with-rtsopts "-N2"']) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a90d1ba4341adc16c2a1804ebfea3fdd56298eb6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a90d1ba4341adc16c2a1804ebfea3fdd56298eb6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:00:34 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 15 Apr 2024 11:00:34 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/clyring/9.10.1-release-notes-cleanup Message-ID: <661d41127c83_217f776a252026217@gitlab.mail> Matthew Craven pushed new branch wip/clyring/9.10.1-release-notes-cleanup at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/clyring/9.10.1-release-notes-cleanup You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:16:13 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 11:16:13 -0400 Subject: [Git][ghc/ghc][wip/build-ordering] 173 commits: rts/CloneStack: Bounds check array write Message-ID: <661d44bd78734_217f778ba100372aa@gitlab.mail> Ben Gamari pushed to branch wip/build-ordering at Glasgow Haskell Compiler / GHC Commits: c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 32b5d544 by Ben Gamari at 2024-04-15T11:16:01-04:00 base: Ensure that ghc-bignum builds before GHC.IO.Encoding.Iconv On Windows `GHC.IO.Encoding.Iconv` is empty and has no dependencies. Consequently, we must add dummy build ordering imports to ensure that, e.g., `GHC.Types` and `GHC.BigNum.Nat` are built before `GHC.IO.Encoding.Iconv`. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/244a1c323e469f9b3b20ccebe6ceb58f4c6946d9...32b5d544e0f3b98621ce25887a7084aef1418b3f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/244a1c323e469f9b3b20ccebe6ceb58f4c6946d9...32b5d544e0f3b98621ce25887a7084aef1418b3f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:26:59 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 11:26:59 -0400 Subject: [Git][ghc/ghc][wip/build-ordering] base: Ensure that ghc-bignum builds before GHC.IO.Encoding.Iconv Message-ID: <661d4742ec688_217f77a8f3a44084b@gitlab.mail> Ben Gamari pushed to branch wip/build-ordering at Glasgow Haskell Compiler / GHC Commits: d10dbb24 by Ben Gamari at 2024-04-15T11:26:47-04:00 base: Ensure that ghc-bignum builds before GHC.IO.Encoding.Iconv On Windows `GHC.IO.Encoding.Iconv` is empty and has no dependencies. Consequently, we must add dummy build ordering imports to ensure that, e.g., `GHC.Types` and `GHC.BigNum.Nat` are built before `GHC.IO.Encoding.Iconv`. - - - - - 2 changed files: - libraries/base/src/GHC/IO/Encoding/Iconv.hs - libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Iconv.hs Changes: ===================================== libraries/base/src/GHC/IO/Encoding/Iconv.hs ===================================== @@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE Safe #-} +{-# LANGUAGE Trustworthy #-} {-# OPTIONS_HADDOCK not-home #-} -- | @@ -15,8 +15,8 @@ -- This module provides text encoding/decoding using iconv -- -module GHC.IO.Encoding.Iconv #if !defined(mingw32_HOST_OS) +module GHC.IO.Encoding.Iconv (iconvEncoding, mkIconvEncoding, localeEncodingName @@ -25,6 +25,8 @@ module GHC.IO.Encoding.Iconv import GHC.Internal.IO.Encoding.Iconv #else - ( ) where +module GHC.IO.Encoding.Iconv ( ) where + +import GHC.Internal.Base () -- For build ordering #endif ===================================== libraries/ghc-internal/src/GHC/Internal/IO/Encoding/Iconv.hs ===================================== @@ -1,4 +1,3 @@ -{-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation @@ -7,6 +6,9 @@ #-} {-# OPTIONS_HADDOCK not-home #-} +#if defined(mingw32_HOST_OS) +{-# LANGUAGE Trustworthy #-} + ----------------------------------------------------------------------------- -- | -- Module : GHC.Internal.IO.Encoding.Iconv @@ -20,24 +22,36 @@ -- This module provides text encoding/decoding using iconv -- ----------------------------------------------------------------------------- +module GHC.Internal.IO.Encoding.Iconv () where + +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base +import GHC.Types () + +#else + +{-# LANGUAGE Safe #-} +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Internal.IO.Encoding.Iconv +-- Copyright : (c) The University of Glasgow, 2008-2009 +-- License : see libraries/base/LICENSE +-- +-- Maintainer : libraries at haskell.org +-- Stability : internal +-- Portability : non-portable +-- +-- This module provides text encoding/decoding using iconv +-- +----------------------------------------------------------------------------- module GHC.Internal.IO.Encoding.Iconv ( -#if !defined(mingw32_HOST_OS) iconvEncoding, mkIconvEncoding, localeEncodingName -#endif ) where #include "MachDeps.h" #include "HsBaseConfig.h" -#if defined(mingw32_HOST_OS) - --- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base -import GHC.Types () - -#else - import GHC.Internal.Foreign.C.Types import GHC.Internal.Foreign.C.String (withCAString, peekCAString) import GHC.Internal.Foreign.C.String.Encoding View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d10dbb247a79e53ac14146dafe63526c0fc0fbaa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d10dbb247a79e53ac14146dafe63526c0fc0fbaa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:27:37 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 11:27:37 -0400 Subject: [Git][ghc/ghc][wip/T24651] Fix documentation preview from doc-tarball job Message-ID: <661d4769283ed_217f77b2beac41355@gitlab.mail> Teo Camarasu pushed to branch wip/T24651 at Glasgow Haskell Compiler / GHC Commits: 5df1ec29 by Teo Camarasu at 2024-04-15T16:17:55+01:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 2 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,12 +557,17 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz + - docs/haddock/ - libraries.html.tar.xz + - docs/libraries/ - users_guide.html.tar.xz - - index.html - - "*.pdf" + - docs/users_guide/ + - docs/index.html + - Haddock.pdf + - users_guide.pdf script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ @@ -582,8 +587,8 @@ doc-tarball: fi - rm -Rf docs - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST + - mv docs/*.tar.xz docs/*.pdf . - ls -lh - - mv docs/*.tar.xz docs/index.html . hackage-doc-tarball: stage: packaging ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,7 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5df1ec294c26182a890f670df8e27271b6b8b574 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5df1ec294c26182a890f670df8e27271b6b8b574 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:34:15 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 11:34:15 -0400 Subject: [Git][ghc/ghc][wip/release-fixes] 138 commits: Note mutability of array and address access primops Message-ID: <661d48f76dd09_217f77cad53c445d2@gitlab.mail> Ben Gamari pushed to branch wip/release-fixes at Glasgow Haskell Compiler / GHC Commits: 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 3ecb7512 by Ben Gamari at 2024-04-15T11:33:48-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 29 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC/OverloadedCalls.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/470331cd89b6184125f8876085c2aae073d3ea43...3ecb75124d5bcccedb5698240bda264ae49ecde2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/470331cd89b6184125f8876085c2aae073d3ea43...3ecb75124d5bcccedb5698240bda264ae49ecde2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:41:05 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 15 Apr 2024 11:41:05 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: NCG: Fix a bug where we errounously removed a required jump instruction. Message-ID: <661d4a91ba02a_217f77debb88500bd@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e7f9a8af by Andreas Klebinger at 2024-04-15T11:40:50-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 4695dc11 by Alan Zimmerman at 2024-04-15T11:40:51-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 30 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0eab8caa6bff55364c528f8b58c009ab9e1bd0e9...4695dc112984cd5b7ebfc6a3e30759e64264b4b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0eab8caa6bff55364c528f8b58c009ab9e1bd0e9...4695dc112984cd5b7ebfc6a3e30759e64264b4b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 15:56:56 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 15 Apr 2024 11:56:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24674 Message-ID: <661d4e4819722_217f771152b64626a6@gitlab.mail> Teo Camarasu pushed new branch wip/T24674 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24674 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 16:07:51 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 15 Apr 2024 12:07:51 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 3 commits: Add run-time configurability of .hi file compression Message-ID: <661d50d7d0f9f_217f77134b85865888@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 62e97d7d by Matthew Pickering at 2024-04-15T18:07:34+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. - - - - - 3893d390 by Matthew Pickering at 2024-04-15T18:07:34+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 50f756f4 by Fendor at 2024-04-15T18:07:34+02:00 Implement TrieMap for IfaceType - - - - - 21 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -207,6 +207,7 @@ data DynFlags = DynFlags { dmdUnboxWidth :: !Int, -- ^ Whether DmdAnal should optimistically put an -- Unboxed demand on returned products with at most -- this number of fields + ifCompression :: Int, specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types @@ -546,6 +547,7 @@ defaultDynFlags mySettings = maxPmCheckModels = 30, simplTickFactor = 100, dmdUnboxWidth = 3, -- Default: Assume an unboxed demand on function bodies returning a triple + ifCompression = 2, -- Default: Apply safe compressions specConstrThreshold = Just 2000, specConstrCount = Just 3, specConstrRecursive = 3, ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -163,7 +163,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -612,7 +612,7 @@ extract_renamed_stuff mod_summary tc_result = do -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) let out_file = ml_hie_file $ ms_location mod_summary - liftIO $ writeHieFile out_file hieFile + liftIO $ writeHieFile (flagsToIfCompression dflags) out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files @@ -1207,7 +1207,7 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do withTiming logger (text "WriteIface"<+>brackets (text iface_name)) (const ()) - (writeIface logger profile iface_name iface) + (writeIface logger profile (flagsToIfCompression dflags) iface_name iface) if (write_interface || force_write_interface) then do ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1664,6 +1664,9 @@ dynamic_flags_deps = [ , make_ord_flag defFlag "fno-refinement-level-hole-fits" (noArg (\d -> d { refLevelHoleFits = Nothing })) + , make_ord_flag defFlag "fwrite-if-compression" + (intSuffix (\n d -> d { ifCompression = n })) + , make_dep_flag defGhcFlag "fllvm-pass-vectors-in-regs" (noArg id) "vectors registers are now passed in registers by default." ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -14,6 +14,7 @@ module GHC.Iface.Binary ( writeBinIface, readBinIface, readBinIfaceHeader, + CompressionIFace(..), getSymtabName, CheckHiWay(..), TraceBinIFace(..), @@ -48,7 +49,7 @@ import GHC.Types.SrcLoc import GHC.Platform import GHC.Settings.Constants import GHC.Utils.Fingerprint -import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import GHC.Iface.Type (IfaceType(..), getIfaceType, putIfaceType, ifaceTypeSharedByte) import Control.Monad import Data.Array @@ -72,6 +73,21 @@ data TraceBinIFace = TraceBinIFace (SDoc -> IO ()) | QuietBinIFace +data CompressionIFace + = NormalCompression + -- ^ Perform the normal compression operations, + -- such as deduplicating 'Name's and 'FastString's + | SafeExtraCompression + -- ^ Perform some extra compression steps that have minimal impact + -- on the run-time of 'ghc'. + -- + -- This reduces the size of '.hi' files significantly in some cases + -- and reduces overall memory usage in certain scenarios. + | MaximalCompression + -- ^ Try to compress as much as possible. + -- + -- Yields the smallest '.hi' files but at the cost of additional run-time. + -- | Read an interface file header, checking the magic number, version, and -- way. Returns the hash of the source file and a BinHandle which points at the -- start of the rest of the interface file data. @@ -197,8 +213,8 @@ getTables name_cache bh = do -- | Write an interface file. -- -- See Note [Iface Binary Serialisation] for details. -writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () -writeBinIface profile traceBinIface hi_path mod_iface = do +writeBinIface :: Profile -> TraceBinIFace -> CompressionIFace -> FilePath -> ModIface -> IO () +writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do bh <- openBinMem initBinMemSize let platform = profilePlatform profile put_ bh (binaryInterfaceMagic platform) @@ -212,7 +228,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p - putWithUserData traceBinIface bh mod_iface + putWithUserData traceBinIface compressionLevel bh mod_iface extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p @@ -226,9 +242,9 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () -putWithUserData traceBinIface bh payload = do - (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) +putWithUserData :: Binary a => TraceBinIFace -> CompressionIFace -> WriteBinHandle -> a -> IO () +putWithUserData traceBinIface compressionLevel bh payload = do + (name_count, fs_count, _b) <- putWithTables compressionLevel bh (\bh' -> put bh' payload) case traceBinIface of QuietBinIFace -> return () @@ -251,11 +267,11 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Iface Binary Serialiser Order] -putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) -putWithTables bh' put_payload = do +putWithTables :: CompressionIFace -> WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables compressionLevel bh' put_payload = do (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initNameWriterTable - (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter @@ -410,15 +426,33 @@ initReadIfaceTypeTable ud = do , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) } -initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) -initWriteIfaceType = do +initWriteIfaceType :: CompressionIFace -> IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType compressionLevel = do sym_tab <- initGenericSymbolTable @(Map IfaceType) pure ( WriterTable { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) } - , mkWriter $ putGenericSymTab sym_tab + , mkWriter $ ifaceWriter sym_tab ) + where + ifaceWriter sym_tab = case compressionLevel of + NormalCompression -> literalIfaceTypeSerialiser + SafeExtraCompression -> ifaceTyConAppSerialiser sym_tab + MaximalCompression -> fullIfaceTypeSerialiser sym_tab + + ifaceTyConAppSerialiser sym_tab bh ty = case ty of + IfaceTyConApp {} -> do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + _ -> putIfaceType bh ty + + + fullIfaceTypeSerialiser sym_tab bh ty = do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + + literalIfaceTypeSerialiser = putIfaceType initNameReaderTable :: NameCache -> IO (ReaderTable Name) ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -43,7 +43,7 @@ import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types -import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable) +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable, CompressionIFace) import GHC.Iface.Type (IfaceType) import System.IO.Unsafe (unsafeInterleaveIO) import qualified GHC.Utils.Binary as Binary @@ -73,8 +73,8 @@ putBinLine bh xs = do -- | Write a `HieFile` to the given `FilePath`, with a proper header and -- symbol tables for `Name`s and `FastString`s -writeHieFile :: FilePath -> HieFile -> IO () -writeHieFile hie_file_path hiefile = do +writeHieFile :: CompressionIFace -> FilePath -> HieFile -> IO () +writeHieFile compression hie_file_path hiefile = do bh0 <- openBinMem initBinMemSize -- Write the header: hieHeader followed by the @@ -85,7 +85,7 @@ writeHieFile hie_file_path hiefile = do (fs_tbl, fs_w) <- initFastStringWriterTable (name_tbl, name_w) <- initWriteNameTable - (iface_tbl, iface_w) <- initWriteIfaceType + (iface_tbl, iface_w) <- initWriteIfaceType compression let bh = setWriterUserData bh0 $ mkWriterUserData [ mkSomeBinaryWriter @IfaceType iface_w ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Iface.Load ( loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, findAndReadIface, readIface, writeIface, + flagsToIfCompression, moduleFreeHolesPrecise, needWiredInHomeIface, loadWiredInHomeIface, @@ -965,11 +966,18 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do -- | Write interface file -writeIface :: Logger -> Profile -> FilePath -> ModIface -> IO () -writeIface logger profile hi_file_path new_iface +writeIface :: Logger -> Profile -> CompressionIFace -> FilePath -> ModIface -> IO () +writeIface logger profile compression_level hi_file_path new_iface = do createDirectoryIfMissing True (takeDirectory hi_file_path) let printer = TraceBinIFace (debugTraceMsg logger 3) - writeBinIface profile printer hi_file_path new_iface + writeBinIface profile printer compression_level hi_file_path new_iface + +flagsToIfCompression :: DynFlags -> CompressionIFace +flagsToIfCompression dflags = case ifCompression dflags of + 0 -> NormalCompression + 1 -> NormalCompression + 2 -> SafeExtraCompression + _ -> MaximalCompression -- | @readIface@ tries just the one file. -- ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Iface.Type ( ifTyConBinderVar, ifTyConBinderName, -- Binary utilities - putIfaceType, getIfaceType, + putIfaceType, getIfaceType, ifaceTypeSharedByte, -- Equality testing isIfaceLiftedTypeKind, @@ -92,12 +92,13 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Control.DeepSeq +import Data.Maybe (isJust) import Data.Proxy -import Control.Monad ((<$!>)) -import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe (isJust) +import Data.Word (Word8) +import Control.Arrow (first) +import Control.DeepSeq +import Control.Monad ((<$!>)) {- ************************************************************************ @@ -112,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName @@ -2194,12 +2199,34 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ bh tyCon = case findUserDataWriter Proxy bh of - tbl -> putEntry tbl bh tyCon + put_ bh ty = + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ty - get bh = case findUserDataReader Proxy bh of - tbl -> getEntry tbl bh + get bh = getIfaceTypeShared bh +-- | This is the byte tag we expect to read when the next +-- value is not an 'IfaceType' value, but an offset into a +-- lookup value. +-- +-- Must not overlap with any byte tag in 'getIfaceType'. +ifaceTypeSharedByte :: Word8 +ifaceTypeSharedByte = 99 + +-- | Like 'getIfaceType' but checks for a specific byte tag +-- that indicates that we won't be able to read a 'IfaceType' value +-- but rather an offset into a lookup table. Consequentially, +-- we look up the value for the 'IfaceType' in the look up table. +-- +-- See Note [Iface Binary Serialisation] for details. +getIfaceTypeShared :: ReadBinHandle -> IO IfaceType +getIfaceTypeShared bh = do + start <- tellBinReader bh + tag <- getByte bh + if ifaceTypeSharedByte == tag + then case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + else seekBinReader bh start >> getIfaceType bh putIfaceType :: WriteBinHandle -> IfaceType -> IO () putIfaceType _ (IfaceFreeTyVar tv) ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1777,3 +1777,12 @@ as such you shouldn't need to set any of them explicitly. A flag This flag sets the size (in bytes) threshold above which the second approach is used. You can disable the second approach entirely by setting the threshold to 0. + +.. ghc-flag:: -fwrite-if-compression=⟨n⟩ + :shortdesc: *default: 2.* Tweak the level of interface file compression. + :type: dynamic + :category: optimization + + :default: 2 + + TODO ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkInvisFunTy` wordTy `mkInvisFunTy` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkInvisFunTy` funTy `mkInvisFunTy` funTy `mkInvisFunTy` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9eb585b99098a33058d645a1c63b9ed989708e55...50f756f4a9c48c3bce6aac80d74e12311fc47261 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9eb585b99098a33058d645a1c63b9ed989708e55...50f756f4a9c48c3bce6aac80d74e12311fc47261 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 16:22:49 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 15 Apr 2024 12:22:49 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Use explicit recursion in mapTyCo Message-ID: <661d545965ea3_217f7715c229470999@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: e6cea91c by Simon Peyton Jones at 2024-04-15T17:22:35+01:00 Use explicit recursion in mapTyCo See Note [Use explicit recursion in mapTyCo] - - - - - 1 changed file: - compiler/GHC/Core/Type.hs Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -925,6 +925,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar , tcm_hole = cohole }) = (go_ty, go_tys, go_co, go_cos) where + -- See Note [Use explicit recursion in mapTyCo] go_tys !_ [] = return [] go_tys !env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys @@ -955,6 +956,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar ; inner' <- go_ty env' inner ; return $ ForAllTy (Bndr tv' vis) inner' } + -- See Note [Use explicit recursion in mapTyCo] go_cos !_ [] = return [] go_cos !env (co:cos) = (:) <$> go_co env co <*> go_cos env cos @@ -1001,15 +1003,28 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov !env (PhantomProv co) = PhantomProv <$> go_co env co go_prov !env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co - go_prov !env (PluginProv s cvs) = PluginProv s <$> strictFoldDVarSet (do_cv env) - (return emptyDVarSet) cvs - - do_cv :: env -> CoVar -> m DTyCoVarSet -> m DTyCoVarSet - do_cv env v mfvs = do { fvs <- mfvs - ; co <- covar env v - ; return (tyCoVarsOfCoDSet co `unionDVarSet` fvs) } - - + go_prov !env (PluginProv s cvs) = PluginProv s <$> go_fcvs env (dVarSetElems cvs) + + -- See Note [Use explicit recursion in mapTyCo] + go_fcvs :: env -> [CoVar] -> m DTyCoVarSet + go_fcvs env [] = return emptyDVarSet + go_fcvs env (cv:cvs) = do { co <- covar env cv + ; cvs' <- go_fcvs env cvs + ; return (tyCoVarsOfCoDSet co `unionDVarSet` cvs') } + +{- Note [Use explicit recursion in mapTyCo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We use explicit recursion in `mapTyCo`, rather than calling, say, `strictFoldDVarSet`, +for exactly the same reason as in Note [Use explicit recursion in foldTyCo] in +GHC.Core.TyCo.Rep. We are in a monadic context, and using too-clever higher order +functions makes the strictness analyser produce worse results. + +We could probably use `foldr`, since it is inlined bodily, fairly early; but +I'm doing the simple thing and inlining it by hand. + +See !12037 for performance glitches caused by using `strictFoldDVarSet` (which is +definitely not inlined bodily). +-} {- ********************************************************************* * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6cea91c42360fbd36366cd9f5e1081266109593 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6cea91c42360fbd36366cd9f5e1081266109593 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 18:46:31 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 15 Apr 2024 14:46:31 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] wibble Message-ID: <661d76077813c_3aba1993c448103612@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: df626244 by Simon Peyton Jones at 2024-04-15T19:46:20+01:00 wibble - - - - - 1 changed file: - compiler/GHC/Core/Type.hs Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1007,7 +1007,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar -- See Note [Use explicit recursion in mapTyCo] go_fcvs :: env -> [CoVar] -> m DTyCoVarSet - go_fcvs env [] = return emptyDVarSet + go_fcvs _ [] = return emptyDVarSet go_fcvs env (cv:cvs) = do { co <- covar env cv ; cvs' <- go_fcvs env cvs ; return (tyCoVarsOfCoDSet co `unionDVarSet` cvs') } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df626244ff1c081da196adce80f2393008985301 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df626244ff1c081da196adce80f2393008985301 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 18:47:53 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 15 Apr 2024 14:47:53 -0400 Subject: [Git][ghc/ghc][wip/T23338] wip Message-ID: <661d76595ce60_3aba199e72a8104432@gitlab.mail> Jade pushed to branch wip/T23338 at Glasgow Haskell Compiler / GHC Commits: dda3e849 by Jade at 2024-04-15T20:52:24+02:00 wip - - - - - 4 changed files: - ghc/GHCi/UI.hs - ghc/GHCi/UI/Exception.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs Changes: ===================================== ghc/GHCi/UI.hs ===================================== @@ -139,7 +139,7 @@ import Data.Version ( showVersion ) import qualified Data.Semigroup as S import Prelude hiding ((<>)) -import GHC.Utils.Exception as Exception hiding (catch, mask, handle, catches, Handler) +import GHC.Utils.Exception as Exception hiding (catch, mask, handle) import Foreign hiding (void) import GHC.Stack hiding (SrcLoc(..)) import GHC.Unit.Env @@ -172,13 +172,9 @@ import GHC.TopHandler ( topHandler ) import GHCi.Leak import qualified GHC.Unit.Module.Graph as GHC -import GHC.Types.Error.Codes ( constructorCode ) -import GHC.Utils.Ppr.Colour - -import Debug.Trace - ----------------------------------------------------------------------------- + data GhciSettings = GhciSettings { availableCommands :: [Command], shortHelpText :: String, @@ -316,13 +312,13 @@ showSDocForUserQualify doc = do pure $ showSDocForUser dflags unit_state alwaysQualify doc -keepGoing :: GhciMonad m => (String -> m ()) -> (String -> GhciInput m CmdExecOutcome) +keepGoing :: (String -> GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoing a str = keepGoing' (lift . a) str -keepGoingMulti :: GhciMonad m => (String -> m ()) -> (String -> GhciInput m CmdExecOutcome) +keepGoingMulti :: (String -> GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoingMulti a str = keepGoingMulti' (lift . a) str -keepGoing' :: GhciMonad m => (a -> GhciInput m ()) -> a -> GhciInput m CmdExecOutcome +keepGoing' :: GhciMonad m => (a -> m ()) -> a -> m CmdExecOutcome keepGoing' a str = do in_multi <- inMultiMode if in_multi @@ -331,17 +327,17 @@ keepGoing' a str = do return CmdSuccess -- For commands which are actually support in multi-mode, initially just :reload -keepGoingMulti' :: GhciMonad m => (String -> GhciInput m ()) -> String -> GhciInput m CmdExecOutcome +keepGoingMulti' :: GhciMonad m => (String -> m ()) -> String -> m CmdExecOutcome keepGoingMulti' a str = a str >> return CmdSuccess inMultiMode :: GhciMonad m => m Bool inMultiMode = multiMode <$> getGHCiState -keepGoingPaths :: GhciMonad m => ([FilePath] -> GhciInput m ()) -> (String -> GhciInput m CmdExecOutcome) +keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoingPaths a str = do case toArgsNoLoc str of - Left err -> reportError (GhciInvalidArgumentString err) >> pure CmdSuccess - Right args -> lift $ keepGoing' (lift . a) args + Left err -> reportError (GhciInvalidArgumentString err) >> return CmdSuccess + Right args -> keepGoing' a args defShortHelpText :: String defShortHelpText = "use :? for help." @@ -563,13 +559,7 @@ interactiveUI config srcs maybe_exprs = do let !in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 -- We force this to make sure we don't retain the hsc_env when reloading empty_cache <- liftIO newIfaceCache - - - -- JADE_TODO - let action = do - Left y <- runExceptT (runGHCi srcs maybe_exprs) - pure y - startGHCi action + startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, args = default_args, evalWrapper = eval_wrapper, @@ -634,7 +624,7 @@ specified at the command line. The ghci config file has not yet been processed. -} -resetLastErrorLocations :: GhciMonad m => ExceptGhciError m () +resetLastErrorLocations :: GhciMonad m => m () resetLastErrorLocations = do st <- getGHCiState liftIO $ writeIORef (lastErrorLocations st) [] @@ -675,7 +665,7 @@ getAppDataFile file = do False -> new_path Left _ -> new_path -runGHCi :: [(FilePath, Maybe UnitId, Maybe Phase)] -> Maybe [String] -> ExceptGhciError GHCi () +runGHCi :: [(FilePath, Maybe UnitId, Maybe Phase)] -> Maybe [String] -> GHCi () runGHCi paths maybe_exprs = do dflags <- getDynFlags let @@ -693,7 +683,7 @@ runGHCi paths maybe_exprs = do canonicalizePath' fp = liftM Just (canonicalizePath fp) `catchIO` \_ -> return Nothing - sourceConfigFile :: FilePath -> ExceptGhciError GHCi () + sourceConfigFile :: FilePath -> GHCi () sourceConfigFile file = do exists <- liftIO $ doesFileExist file when exists $ do @@ -705,7 +695,7 @@ runGHCi paths maybe_exprs = do -- This would be a good place for runFileInputT. Right hdl -> do runInputTWithPrefs defaultPrefs defaultSettings $ - runCommands $ (lift $ fileLoop hdl) + runCommands $ fileLoop hdl liftIO (hClose hdl `catchIO` \_ -> return ()) -- Don't print a message if this is really ghc -e (#11478). -- Also, let the user silence the message with -v0 @@ -793,18 +783,17 @@ runGHCi paths maybe_exprs = do liftIO $ withProgName (progname st) $ topHandler e -- this used to be topHandlerFastExit, see #2228 - -- JADE_TODO runInputTWithPrefs defaultPrefs defaultSettings $ do -- make `ghc -e` exit nonzero on failure, see #7962, #9916, #17560, #18441 _ <- runCommands' hdle - (Just $ hdle (toException $ ExitFailure 1) >> pure ()) - (pure Nothing) - pure () + (Just $ hdle (toException $ ExitFailure 1) >> return ()) + (return Nothing) + return () -- and finally, exit liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving GHCi." -runGHCiInput :: GhciInput Ghci a -> Ghci a +runGHCiInput :: InputT GHCi a -> GHCi a runGHCiInput f = do dflags <- getDynFlags let ghciHistory = gopt Opt_GhciHistory dflags @@ -816,20 +805,21 @@ runGHCiInput f = do (True, _) -> liftIO $ getAppDataFile "ghci_history" _ -> return Nothing - -- JADE_TODO - runInputT (setComplete (lift . ghciCompleteWord) $ defaultSettings {historyFile = histFile}) f + runInputT + (setComplete ghciCompleteWord $ defaultSettings {historyFile = histFile}) + f -- | How to get the next input line from the user -nextInputLine :: GhciMonad m => Bool -> Bool -> GhciInput m (Maybe String) +nextInputLine :: Bool -> Bool -> InputT GHCi (Maybe String) nextInputLine show_prompt is_tty | is_tty = do prmpt <- if show_prompt then lift mkPrompt else return "" r <- getInputLine prmpt - lift incrementLineNo + incrementLineNo return r | otherwise = do when show_prompt $ lift mkPrompt >>= liftIO . putStr - lift $ fileLoop stdin + fileLoop stdin -- NOTE: We only read .ghci files if they are owned by the current user, -- and aren't world writable (files owned by root are ok, see #9324). @@ -879,7 +869,7 @@ incrementLineNo = modifyGHCiState incLineNo where incLineNo st = st { line_number = line_number st + 1 } -fileLoop :: GhciMonad m => Handle -> ExceptGhciError m (Maybe String) +fileLoop :: GhciMonad m => Handle -> m (Maybe String) fileLoop hdl = do l <- liftIO $ tryIO $ hGetLine hdl case l of @@ -968,7 +958,7 @@ checkPromptStringForErrors :: String -> Maybe String checkPromptStringForErrors ('%':'c':'a':'l':'l':xs) = case parseCallEscape xs of Nothing -> Just ("Incorrect %call syntax. " ++ - "Should be %call(a command and arguments).") -- JADE_TODO + "Should be %call(a command and arguments).") Just (_, afterClosed) -> checkPromptStringForErrors afterClosed checkPromptStringForErrors ('%':'%':xs) = checkPromptStringForErrors xs checkPromptStringForErrors (_:xs) = checkPromptStringForErrors xs @@ -983,12 +973,12 @@ generatePromptFunctionFromString promptS modules_names line = | (x :rest) <- xs = carry_on (char x) rest | otherwise = pure empty - carry_on :: GhciMonad m => SDoc -> String -> ExceptGhciError m SDoc + carry_on :: GhciMonad m => SDoc -> String -> m SDoc carry_on doc rest = do next <- processString rest pure $ doc <> next - processPromptPattern :: GhciMonad m => String -> ExceptGhciError m (SDoc, String) + processPromptPattern :: GhciMonad m => String -> m (SDoc, String) processPromptPattern str | Just rest <- stripPrefix "call" str = do -- Input has just been validated by parseCallEscape @@ -1021,7 +1011,6 @@ generatePromptFunctionFromString promptS modules_names line = 'N' -> text' compilerName 'V' -> text' (showVersion compilerVersion) '%' -> pure $ char '%' - _ -> error "lol" -- JADE_TODO text' :: GhciMonad m => String -> m SDoc text' = pure . text @@ -1032,7 +1021,7 @@ generatePromptFunctionFromString promptS modules_names line = as_string :: GhciMonad m => IO String -> m SDoc as_string = liftIO . fmap text -mkPrompt :: ExceptGhciError GHCi String +mkPrompt :: GHCi String mkPrompt = do st <- getGHCiState dflags <- getDynFlags @@ -1052,7 +1041,7 @@ queryQueue = do return (Just c) -- Reconfigurable pretty-printing Ticket #5461 -installInteractivePrint :: GhciMonad m => Maybe String -> Bool -> ExceptGhciError m () +installInteractivePrint :: GhciMonad m => Maybe String -> Bool -> m () installInteractivePrint Nothing _ = return () installInteractivePrint (Just ipFun) exprmode = do ok <- trySuccess $ do @@ -1064,30 +1053,28 @@ installInteractivePrint (Just ipFun) exprmode = do when (failed ok && exprmode) $ liftIO (exitWith (ExitFailure 1)) -- | The main read-eval-print loop -runCommands :: GhciMonad m => GhciInput m (Maybe String) -> GhciInput m () +runCommands :: InputT GHCi (Maybe String) -> InputT GHCi () runCommands gCmd = runCommands' handler Nothing gCmd >> return () -runCommands' :: GhciMonad m - => (SomeException -> GhciInput m Bool) -- ^ Exception handler - -> Maybe (GhciInput m ()) -- ^ Source error handler - -> GhciInput m (Maybe String) - -> GhciInput m () +runCommands' :: (SomeException -> GHCi Bool) -- ^ Exception handler + -> Maybe (GHCi ()) -- ^ Source error handler + -> InputT GHCi (Maybe String) + -> InputT GHCi () runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do - b <- catches (unmask $ runOneCommand eh gCmd) - [ Handler $ \(ex :: GhcException) -> liftIO (print ex) >> pure Nothing -- TODO - , Handler $ \(ex :: SomeException) -> case fromException ex of - Just UserInterrupt -> pure $ Just False - _ -> liftIO $ Exception.throwIO ex - ] + b <- handle (\e -> case fromException e of + Just UserInterrupt -> return $ Just False + _ -> case fromException e of + Just ghce -> + do liftIO (print (ghce :: GhcException)) + return Nothing + _other -> + liftIO (Exception.throwIO e)) + (unmask $ runOneCommand eh gCmd) case b of - Nothing -> pure () + Nothing -> return () Just success -> do unless success $ maybe (return ()) lift sourceErrorHandler unmask $ runCommands' eh sourceErrorHandler gCmd - where - -{- JADE_TODO --} -- | Evaluate a single line of user input (either : or Haskell code). -- A result of Nothing means there was no more input to process. @@ -1095,18 +1082,18 @@ runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do -- this is relevant only to ghc -e, which will exit with status 1 -- if the command was unsuccessful. GHCi will continue in either case. -- TODO: replace Bool with CmdExecOutcome -runOneCommand :: GhciInput m => (SomeException -> GhciInput m Bool) -> GhciInput m (Maybe String) - -> GhciInput m (Maybe Bool) +runOneCommand :: (SomeException -> GHCi Bool) -> InputT GHCi (Maybe String) + -> InputT GHCi (Maybe Bool) runOneCommand eh gCmd = do -- run a previously queued command if there is one, otherwise get new -- input from user mb_cmd0 <- noSpace (lift queryQueue) - mb_cmd1 <- maybe (noSpace gCmd) (pure . Just) mb_cmd0 + mb_cmd1 <- maybe (noSpace gCmd) (return . Just) mb_cmd0 case mb_cmd1 of - Nothing -> pure Nothing + Nothing -> return Nothing Just c -> do st <- getGHCiState - ghciHandle (\e -> lift $ eh e >>= pure . Just) $ + ghciHandle (\e -> lift $ eh e >>= return . Just) $ handleSourceError printErrorAndFail $ cmd_wrapper st $ doCommand c -- source error's are handled by runStmt @@ -1152,7 +1139,7 @@ runOneCommand eh gCmd = do cmdOutcome CmdFailure = Just False -- | Handle a line of input - doCommand :: GhciMonad m => String -> GhciInput m CommandResult + doCommand :: String -> InputT GHCi CommandResult -- command doCommand stmt | stmt'@(':' : cmd) <- removeSpaces stmt = do @@ -1189,8 +1176,8 @@ runOneCommand eh gCmd = do return $ CommandComplete stmt' (Just . runSuccess <$> result) stats -- runStmt wrapper for temporarily overridden line-number - runStmtWithLineNum :: GhciMonad m => Int -> String -> SingleStep - -> GhciInput m (Maybe GHC.ExecResult) + runStmtWithLineNum :: Int -> String -> SingleStep + -> GHCi (Maybe GHC.ExecResult) runStmtWithLineNum lnum stmt step = do st0 <- getGHCiState setGHCiState st0 { line_number = lnum } @@ -1245,7 +1232,7 @@ checkInputForLayout stmt getStmt = do then Lexer.activeContext else Lexer.lexer False return >> goToEnd -enqueueCommands :: GhciMonad m => [String] -> ExceptGhciError m () +enqueueCommands :: GhciMonad m => [String] -> m () enqueueCommands cmds = do -- make sure we force any exceptions in the commands while we're -- still inside the exception handler, otherwise bad things will @@ -1255,7 +1242,7 @@ enqueueCommands cmds = do -- | Entry point to execute some haskell code from user. -- The return value True indicates success, as in `runOneCommand`. -runStmt :: GhciMonad m => String -> SingleStep -> ExceptGhciError m (Maybe GHC.ExecResult) +runStmt :: GhciMonad m => String -> SingleStep -> m (Maybe GHC.ExecResult) runStmt input step = do pflags <- initParserOpts <$> GHC.getInteractiveDynFlags -- In GHCi, we disable `-fdefer-type-errors`, as well as `-fdefer-type-holes` @@ -1308,7 +1295,7 @@ runStmt input step = do opts = unLoc <$> loc_opts in setOptions opts - run_stmt :: GhciMonad m => GhciLStmt GhcPs -> ExceptGhciError m (Maybe GHC.ExecResult) + run_stmt :: GhciMonad m => GhciLStmt GhcPs -> m (Maybe GHC.ExecResult) run_stmt stmt = do m_result <- GhciMonad.runStmt stmt input step case m_result of @@ -1329,7 +1316,7 @@ runStmt input step = do -- -- Instead of dealing with all these problems individually here we fix this -- mess by just treating `x = y` as `let x = y`. - run_decls :: GhciMonad m => [LHsDecl GhcPs] -> ExceptGhciError m (Maybe GHC.ExecResult) + run_decls :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe GHC.ExecResult) -- Only turn `FunBind` and `VarBind` into statements, other bindings -- (e.g. `PatBind`) need to stay as decls. run_decls [L l (ValD _ bind at FunBind{})] = run_stmt (mk_stmt (locA l) bind) @@ -1354,7 +1341,7 @@ runStmt input step = do la' = L (noAnnSrcSpan loc) in la (LetStmt noAnn (HsValBinds noAnn (ValBinds NoAnnSortKey (unitBag (la' bind)) []))) - setDumpFilePrefix :: GHC.GhcMonad m => InteractiveContext -> ExceptGhciError m () -- #17500 + setDumpFilePrefix :: GHC.GhcMonad m => InteractiveContext -> m () -- #17500 setDumpFilePrefix ic = do dflags <- GHC.getInteractiveDynFlags GHC.setInteractiveDynFlags dflags { dumpPrefix = modStr ++ "." } @@ -1363,7 +1350,7 @@ runStmt input step = do -- | Clean up the GHCi environment after a statement has run afterRunStmt :: GhciMonad m - => (SrcSpan -> Bool) -> GHC.ExecResult -> ExceptGhciError m GHC.ExecResult + => (SrcSpan -> Bool) -> GHC.ExecResult -> m GHC.ExecResult afterRunStmt step_here run_result = do resumes <- GHC.getResumeContext case run_result of @@ -1419,7 +1406,7 @@ toBreakIdAndLocation (Just inf) = do breakModule loc == md, breakTick loc == nm ] -printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [Name] -> ExceptGhciError m () +printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [Name] -> m () printStoppedAtBreakInfo res names = do printForUser $ pprStopped res -- printTypeOfNames session names @@ -1428,14 +1415,14 @@ printStoppedAtBreakInfo res names = do docs <- mapM pprTypeAndContents [i | AnId i <- tythings] printForUserPartWay $ vcat docs -printTypeOfNames :: GHC.GhcMonad m => [Name] -> ExceptGhciError m () +printTypeOfNames :: GHC.GhcMonad m => [Name] -> m () printTypeOfNames names = mapM_ (printTypeOfName ) $ sortBy compareNames names compareNames :: Name -> Name -> Ordering compareNames = on compare getOccString S.<> on SrcLoc.leftmost_smallest getSrcSpan -printTypeOfName :: GHC.GhcMonad m => Name -> ExceptGhciError m () +printTypeOfName :: GHC.GhcMonad m => Name -> m () printTypeOfName n = do maybe_tything <- GHC.lookupName n case maybe_tything of @@ -1446,7 +1433,7 @@ printTypeOfName n data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand -- | Entry point for execution a ':' input from user -specialCommand :: String -> GhciInput CmdExecOutcome +specialCommand :: String -> InputT GHCi CmdExecOutcome specialCommand ('!':str) = lift $ shellEscape (dropWhile isSpace str) specialCommand str = do let (cmd,rest) = break isSpace str @@ -1455,11 +1442,11 @@ specialCommand str = do case maybe_cmd of GotCommand cmd -> (cmdAction cmd) (dropWhile isSpace rest) BadCommand -> - do lift $ reportError (GhciUnknownCommand cmd htxt) - pure CmdFailure + do reportError (GhciUnknownCommand cmd htxt) + return CmdFailure NoLastCommand -> - do lift $ reportError (GhciNoLastCommandAvailable htxt) - pure CmdFailure -- JADE_TODO + do reportError (GhciNoLastCommandAvailable htxt) + return CmdFailure shellEscape :: MonadIO m => String -> m CmdExecOutcome shellEscape str = liftIO $ do @@ -1561,20 +1548,20 @@ getCurrentBreakModule = do noArgs :: MonadIO m => m () -> String -> m () noArgs m "" = m -noArgs _ _ = liftIO $ putStrLn "This command takes no arguments" -- JADE_TODO +noArgs _ _ = liftIO $ putStrLn "This command takes no arguments" withSandboxOnly :: GHC.GhcMonad m => String -> m () -> m () withSandboxOnly cmd this = do dflags <- getDynFlags if not (gopt Opt_GhciSandbox dflags) - then printForUser (text cmd <+> -- JADE_TODO + then printForUser (text cmd <+> text "is not supported with -fno-ghci-sandbox") else this ----------------------------------------------------------------------------- -- :help -help :: GhciMonad m => String -> ExceptGhciError m () +help :: GhciMonad m => String -> m () help _ = do txt <- long_help `fmap` getGHCiState liftIO $ putStr txt @@ -1582,15 +1569,15 @@ help _ = do ----------------------------------------------------------------------------- -- :info -info :: GhciMonad m => Bool -> String -> ExceptGhciError m () -info _ "" = reportError (GhciCommandSyntaxError "i" ["thing-you-want-info-about"]) +info :: GHC.GhcMonad m => Bool -> String -> m () +info _ "" = throwGhcException (CmdLineError "syntax: ':i '") info allInfo s = handleSourceError printGhciException $ do forM_ (words s) $ \thing -> do sdoc <- infoThing allInfo thing rendered <- showSDocForUser' sdoc liftIO (putStrLn rendered) -infoThing :: GhciMonad m => Bool -> String -> m SDoc +infoThing :: GHC.GhcMonad m => Bool -> String -> m SDoc infoThing allInfo str = do names <- GHC.parseName str mb_stuffs <- mapM (GHC.getInfo allInfo) names @@ -1621,7 +1608,7 @@ pprInfo (thing, fixity, cls_insts, fam_insts, docs) ----------------------------------------------------------------------------- -- :main -runMain :: GhciMonad m => String -> ExceptGhciError m () +runMain :: GhciMonad m => String -> m () runMain s = case toArgsNoLoc s of Left err -> liftIO (hPutStrLn stderr err) Right args -> doWithMain (doWithArgs args) @@ -1642,12 +1629,12 @@ runMain s = case toArgsNoLoc s of ----------------------------------------------------------------------------- -- :run -runRun :: GhciMonad m => String -> ExceptGhciError m () +runRun :: GhciMonad m => String -> m () runRun s = case toCmdArgs s of Left err -> liftIO (hPutStrLn stderr err) Right (cmd, args) -> doWithArgs args cmd -doWithArgs :: GhciMonad m => [String] -> String -> ExceptGhciError m () +doWithArgs :: GhciMonad m => [String] -> String -> m () doWithArgs args cmd = enqueueCommands ["System.Environment.withArgs " ++ show args ++ " (" ++ cmd ++ ")"] @@ -1678,7 +1665,7 @@ toArgsNoLoc str = map unLoc <$> toArgs fake_loc str fake_loc = mkRealSrcLoc (fsLit "") 1 1 -- this should never be seen, because it's discarded with the `map unLoc` -toArgsNoLocWithErrorHandler :: GhciMonad m => String -> ([String] -> ExceptGhciError m ()) -> ExceptGhciError m () +toArgsNoLocWithErrorHandler :: GhciMonad m => String -> ([String] -> m ()) -> m () toArgsNoLocWithErrorHandler str f = case toArgsNoLoc str of Left err -> reportError $ GhciInvalidArgumentString err Right ok -> f ok @@ -1686,7 +1673,7 @@ toArgsNoLocWithErrorHandler str f = case toArgsNoLoc str of ----------------------------------------------------------------------------- -- :cd -changeDirectory :: GhciMonad m => String -> ExceptGhciError m () +changeDirectory :: GhciMonad m => String -> m () changeDirectory "" = do -- :cd on its own changes to the user's home directory either_dir <- liftIO $ tryIO getHomeDirectory @@ -1721,14 +1708,14 @@ trySuccess act = ----------------------------------------------------------------------------- -- :edit -editFile :: GhciMonad m => String -> ExceptGhciError m () +editFile :: GhciMonad m => String -> m () editFile str = do file <- if null str then chooseEditFile else expandPath str st <- getGHCiState errs <- liftIO $ readIORef $ lastErrorLocations st let cmd = editor st when (null cmd) - $ reportError GhciNoSetEditor + $ throwGhcException (CmdLineError "editor not set, use :set editor") lineOpt <- liftIO $ do let sameFile p1 p2 = liftA2 (==) (canonicalizePath p1) (canonicalizePath p2) `catchIO` (\_ -> return False) @@ -1782,7 +1769,7 @@ chooseEditFile = ----------------------------------------------------------------------------- -- :def -defineMacro :: GhciMonad m => Bool{-overwrite-} -> String -> ExceptGhciError m () +defineMacro :: GhciMonad m => Bool{-overwrite-} -> String -> m () defineMacro _ (':':_) = reportError (GhciMacroInvalidStart "a colon") >> failIfExprEvalMode defineMacro _ ('!':_) = reportError (GhciMacroInvalidStart "an exclamation mark") >> failIfExprEvalMode -- TODO defineMacro overwrite s = do @@ -1797,9 +1784,12 @@ defineMacro overwrite s = do else do isCommand <- isJust <$> lookupCommand' macro_name let check_newname - | macro_name `elem` defined = reportError (GhciMacroAlreadyDefined macro_name) - | isCommand = reportError (GhciMacroOverwritesBuiltin macro_name) - | otherwise = pure () + | macro_name `elem` defined = throwGhcException (CmdLineError + ("macro '" ++ macro_name ++ "' is already defined. " ++ hint)) + | isCommand = throwGhcException (CmdLineError + ("macro '" ++ macro_name ++ "' overwrites builtin command. " ++ hint)) + | otherwise = return () + hint = " Use ':def!' to overwrite." unless overwrite check_newname -- compile the expression @@ -1833,7 +1823,7 @@ runMacro :: GhciMonad m => GHC.ForeignHValue -- String -> IO String -> String - -> ExceptGhciError m CmdExecOutcome + -> m CmdExecOutcome runMacro fun s = do interp <- hscInterp <$> GHC.getSession str <- liftIO $ evalStringToIOString interp fun s @@ -1844,7 +1834,7 @@ runMacro fun s = do ----------------------------------------------------------------------------- -- :undef -undefineMacro :: GhciMonad m => String -> ExceptGhciError m () +undefineMacro :: GhciMonad m => String -> m () undefineMacro str = mapM_ undef (words str) where undef macro_name = do cmds <- ghci_macros <$> getGHCiState @@ -1861,7 +1851,7 @@ undefineMacro str = mapM_ undef (words str) ----------------------------------------------------------------------------- -- :cmd -cmdCmd :: GhciMonad m => String -> ExceptGhciError m () +cmdCmd :: GhciMonad m => String -> m () cmdCmd str = handleSourceError printErrAndMaybeExit $ do step <- getGhciStepIO expr <- GHC.parseExpr str @@ -1889,7 +1879,7 @@ getGhciStepIO = do ----------------------------------------------------------------------------- -- :check -checkModule :: GhciMonad m => String -> ExceptGhciError m () +checkModule :: GhciMonad m => String -> m () checkModule m = do let modl = GHC.mkModuleName m ok <- handleSourceError (\e -> printErrAndMaybeExit e >> return False) $ do @@ -1911,9 +1901,9 @@ checkModule m = do ----------------------------------------------------------------------------- -- :doc -docCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +docCmd :: GHC.GhcMonad m => String -> m () docCmd "" = - throwGhcException (CmdLineError "syntax: ':doc '") -- TODO + throwGhcException (CmdLineError "syntax: ':doc '") docCmd s = do -- TODO: Maybe also get module headers for module names names <- GHC.parseName s @@ -1998,9 +1988,9 @@ handleGetDocsFailure no_docs = do ----------------------------------------------------------------------------- -- :instances -instancesCmd :: String -> GhciInput () +instancesCmd :: String -> InputT GHCi () instancesCmd "" = - throwGhcException (CmdLineError "syntax: ':instances '") -- JADE_TODO + throwGhcException (CmdLineError "syntax: ':instances '") instancesCmd s = do handleSourceError printGhciException $ do ty <- GHC.parseInstanceHead s @@ -2032,19 +2022,19 @@ wrapDeferTypeErrors load = (\originalFlags -> void $ GHC.setProgramDynFlags originalFlags) (\_ -> load) -loadModule :: GhciMonad m => [(FilePath, Maybe UnitId, Maybe Phase)] -> ExceptGhciError m SuccessFlag +loadModule :: GhciMonad m => [(FilePath, Maybe UnitId, Maybe Phase)] -> m SuccessFlag loadModule fs = do (_, result) <- runAndPrintStats (const Nothing) (loadModule' fs) either (liftIO . Exception.throwIO) return result -- | @:load@ command -loadModule_ :: GhciMonad m => [FilePath] -> ExceptGhciError m () +loadModule_ :: GhciMonad m => [FilePath] -> m () loadModule_ fs = void $ loadModule (zip3 fs (repeat Nothing) (repeat Nothing)) -loadModuleDefer :: GhciMonad m => [FilePath] -> ExceptGhciError m () +loadModuleDefer :: GhciMonad m => [FilePath] -> m () loadModuleDefer = wrapDeferTypeErrors . loadModule_ -loadModule' :: GhciMonad m => [(FilePath, Maybe UnitId, Maybe Phase)] -> ExceptGhciError m SuccessFlag +loadModule' :: GhciMonad m => [(FilePath, Maybe UnitId, Maybe Phase)] -> m SuccessFlag loadModule' files = do let (filenames, uids, phases) = unzip3 files exp_filenames <- mapM expandPath filenames @@ -2079,7 +2069,7 @@ loadModule' files = do load_module -- | @:add@ command -addModule :: GhciMonad m => [FilePath] -> ExceptGhciError m () +addModule :: GhciMonad m => [FilePath] -> m () addModule files = do revertCAFs -- always revert CAFs on load/add. files' <- mapM expandPath files @@ -2091,11 +2081,11 @@ addModule files = do _ <- doLoadAndCollectInfo (Add $ length targets') LoadAllTargets return () where - checkTarget :: GhciMonad m => Target -> ExceptGhciError m Bool + checkTarget :: GhciMonad m => Target -> m Bool checkTarget Target { targetId = TargetModule m } = checkTargetModule m checkTarget Target { targetId = TargetFile f _ } = checkTargetFile f - checkTargetModule :: GhciMonad m => ModuleName -> ExceptGhciError m Bool + checkTargetModule :: GhciMonad m => ModuleName -> m Bool checkTargetModule m = do hsc_env <- GHC.getSession let home_unit = hsc_home_unit hsc_env @@ -2107,7 +2097,7 @@ addModule files = do failIfExprEvalMode pure False - checkTargetFile :: GhciMonad m => String -> ExceptGhciError m Bool + checkTargetFile :: GhciMonad m => String -> m Bool checkTargetFile f = do exists <- liftIO (doesFileExist f) unless exists $ do @@ -2116,7 +2106,7 @@ addModule files = do return exists -- | @:unadd@ command -unAddModule :: GhciMonad m => [FilePath] -> ExceptGhciError m () +unAddModule :: GhciMonad m => [FilePath] -> m () unAddModule files = do files' <- mapM expandPath files targets <- mapM (\m -> GHC.guessTarget m Nothing Nothing) files' @@ -2126,7 +2116,7 @@ unAddModule files = do return () -- | @:reload@ command -reloadModule :: GhciMonad m => String -> ExceptGhciError m () +reloadModule :: GhciMonad m => String -> m () reloadModule m = do session <- GHC.getSession let home_unit = homeUnitId (hsc_home_unit session) @@ -2136,7 +2126,7 @@ reloadModule m = do loadTargets hu | null m = LoadAllTargets | otherwise = LoadUpTo (mkModule hu (GHC.mkModuleName m)) -reloadModuleDefer :: GhciMonad m => String -> ExceptGhciError m () +reloadModuleDefer :: GhciMonad m => String -> m () reloadModuleDefer = wrapDeferTypeErrors . reloadModule -- | Load/compile targets and (optionally) collect module-info @@ -2151,7 +2141,7 @@ reloadModuleDefer = wrapDeferTypeErrors . reloadModule -- since those commands are designed to be used by editors and -- tooling, it's useless to collect this data for normal GHCi -- sessions. -doLoadAndCollectInfo :: GhciMonad m => LoadType -> LoadHowMuch -> ExceptGhciError m SuccessFlag +doLoadAndCollectInfo :: GhciMonad m => LoadType -> LoadHowMuch -> m SuccessFlag doLoadAndCollectInfo load_type howmuch = do doCollectInfo <- isOptionSet CollectInfo @@ -2168,7 +2158,7 @@ doLoadAndCollectInfo load_type howmuch = do pure Succeeded flag -> pure flag -doLoad :: GhciMonad m => LoadType -> LoadHowMuch -> ExceptGhciError m SuccessFlag +doLoad :: GhciMonad m => LoadType -> LoadHowMuch -> m SuccessFlag doLoad load_type howmuch = do -- turn off breakpoints before we load: we can't turn them off later, because -- the ModBreaks will have gone away. @@ -2195,7 +2185,7 @@ afterLoad :: GhciMonad m => SuccessFlag -> LoadType - -> ExceptGhciError m () + -> m () afterLoad ok load_type = do revertCAFs -- always revert CAFs on load. discardTickArrays @@ -2204,7 +2194,7 @@ afterLoad ok load_type = do graph <- GHC.getModuleGraph setContextAfterLoad (isReload load_type) (Just graph) -setContextAfterLoad :: GhciMonad m => Bool -> Maybe GHC.ModuleGraph -> ExceptGhciError m () +setContextAfterLoad :: GhciMonad m => Bool -> Maybe GHC.ModuleGraph -> m () setContextAfterLoad keep_ctxt Nothing = do setContextKeepingPackageModules keep_ctxt [] setContextAfterLoad keep_ctxt (Just graph) = do @@ -2254,7 +2244,7 @@ setContextKeepingPackageModules => Bool -- True <=> keep all of remembered_ctx -- False <=> just keep package imports -> [InteractiveImport] -- new context - -> ExceptGhciError m () + -> m () setContextKeepingPackageModules keep_ctx trans_ctx = do st <- getGHCiState @@ -2286,7 +2276,7 @@ keepPackageImports = filterM is_pkg_import -modulesLoadedMsg :: GHC.GhcMonad m => SuccessFlag -> [GHC.ModSummary] -> LoadType -> ExceptGhciError m () +modulesLoadedMsg :: GHC.GhcMonad m => SuccessFlag -> [GHC.ModSummary] -> LoadType -> m () modulesLoadedMsg ok mods load_type = do dflags <- getDynFlags when (verbosity dflags > 0) $ do @@ -2330,30 +2320,10 @@ modulesLoadedMsg ok mods load_type = do <+> parens (text $ normalise $ msObjFilePath mod) -- Fix #9887 --- | Run an 'ExceptT' wrapped 'GhcMonad' while handling source errors --- and printing 'throwE' strings to 'stderr'. If in expression --- evaluation mode - throw GhcException and exit. -runExceptGhciMonad :: GhciMonad m => ExceptGhciError m () -> m () -runExceptGhciMonad act = handleSourceError printGhciException $ - either handleErr pure =<< - runExceptT act - where - handleErr err = printCommandError err >> failIfExprEvalMode -- JADE_TODO - printCommandError err = - printForUser . coloured colBold $ (coloured colRedFg (text "error")) <> colon <+> prefix err $$ - nest 2 (ppr err) $$ text "" - prefix = maybe empty (brackets . ppr . set_ghci_ns) . constructorCode - set_ghci_ns c = c { diagnosticCodeNameSpace = "GHCi" } - --- | Inverse of 'runExceptT' for \"pure\" computations --- (c.f. 'except' for 'Except') -exceptT :: Applicative m => Either e a -> ExceptT e m a -exceptT = ExceptT . pure - ----------------------------------------------------------------------------- -- | @:type@ command. See also Note [TcRnExprMode] in GHC.Tc.Module. -typeOfExpr :: GhciMonad m => String -> ExceptGhciError m () +typeOfExpr :: GhciMonad m => String -> m () typeOfExpr str = handleSourceError printErrAndMaybeExit $ case break isSpace str of ("+v", _) -> printForUser (text "`:type +v' has gone; use `:type' instead") @@ -2368,46 +2338,46 @@ typeOfExpr str = handleSourceError printErrAndMaybeExit $ ----------------------------------------------------------------------------- -- | @:type-at@ command -typeAtCmd :: GhciMonad m => String -> ExceptGhciError m () -typeAtCmd str = runExceptGhciMonad $ do - (span',sample) <- exceptT $ parseSpanArg str - infos <- lift $ mod_infos <$> getGHCiState +typeAtCmd :: GhciMonad m => String -> m () +typeAtCmd str = do + (span',sample) <- parseSpanArg str + infos <- mod_infos <$> getGHCiState (info, ty) <- findType infos span' sample let mb_rdr_env = case modinfoRdrEnv info of Strict.Just rdrs -> Just rdrs Strict.Nothing -> Nothing - lift $ printForUserGlobalRdrEnv - mb_rdr_env - (sep [text sample,nest 2 (dcolon <+> ppr ty)]) + printForUserGlobalRdrEnv + mb_rdr_env + (sep [text sample,nest 2 (dcolon <+> ppr ty)]) ----------------------------------------------------------------------------- -- | @:uses@ command -usesCmd :: GhciMonad m => String -> ExceptGhciError m () -usesCmd str = runExceptGhciMonad $ do - (span',sample) <- exceptT $ parseSpanArg str - infos <- lift $ mod_infos <$> getGHCiState +usesCmd :: GhciMonad m => String -> m () +usesCmd str = do + (span',sample) <- parseSpanArg str + infos <- mod_infos <$> getGHCiState uses <- findNameUses infos span' sample forM_ uses (liftIO . putStrLn . showSrcSpan) ----------------------------------------------------------------------------- -- | @:loc-at@ command -locAtCmd :: GhciMonad m => String -> ExceptGhciError m () -locAtCmd str = runExceptGhciMonad $ do - (span',sample) <- exceptT $ parseSpanArg str - infos <- lift $ mod_infos <$> getGHCiState +locAtCmd :: GhciMonad m => String -> m () +locAtCmd str = do + (span',sample) <- parseSpanArg str + infos <- mod_infos <$> getGHCiState (_,_,sp) <- findLoc infos span' sample liftIO . putStrLn . showSrcSpan $ sp ----------------------------------------------------------------------------- -- | @:all-types@ command -allTypesCmd :: GhciMonad m => String -> ExceptGhciError m () -allTypesCmd _ = runExceptGhciMonad $ do - infos <- lift $ mod_infos <$> getGHCiState +allTypesCmd :: GhciMonad m => String -> m () +allTypesCmd _ = do + infos <- mod_infos <$> getGHCiState forM_ (M.elems infos) $ \mi -> - forM_ (modinfoSpans mi) (lift . printSpan) + forM_ (modinfoSpans mi) printSpan where printSpan span' | Just ty <- spaninfoType span' = do @@ -2421,7 +2391,7 @@ allTypesCmd _ = runExceptGhciMonad $ do -- Helpers for locAtCmd/typeAtCmd/usesCmd -- | Parse a span: -parseSpanArg :: String -> Either GhciCommandError (RealSrcSpan,String) +parseSpanArg :: forall m. MonadIO m => String -> m (RealSrcSpan,String) parseSpanArg s = do (fp,s0) <- readAsString (skipWs s) s0' <- skipWs1 s0 @@ -2434,7 +2404,7 @@ parseSpanArg s = do (ec,s4) <- readAsInt s3' trailer <- case s4 of - [] -> Right "" + [] -> pure "" _ -> skipWs1 s4 let fs = mkFastString fp @@ -2443,29 +2413,29 @@ parseSpanArg s = do -- after the end of the span. (mkRealSrcLoc fs el (ec + 1)) - return (span',trailer) + pure (span',trailer) where - readAsInt :: String -> Either GhciCommandError (Int,String) - readAsInt "" = left' SpanPrematureEnd + mkError = reportError . GhciArgumentParseError + + readAsInt :: String -> m (Int,String) + readAsInt "" = mkError "Premature end of string while expecting Int" readAsInt s0 = case reads s0 of - [s_rest] -> Right s_rest - _ -> left' $ SpanNoReadAs (show s0) "Int" + [s_rest] -> pure s_rest + _ -> mkError ("Couldn't read" <+> text (show s0) <+> "as Int") - readAsString :: String -> Either GhciCommandError (String,String) + readAsString :: String -> m (String,String) readAsString s0 | '"':_ <- s0 = case reads s0 of - [s_rest] -> Right s_rest + [s_rest] -> pure s_rest _ -> leftRes - | s_rest@(_:_,_) <- breakWs s0 = Right s_rest + | s_rest@(_:_,_) <- breakWs s0 = pure s_rest | otherwise = leftRes where - leftRes = left' $ SpanNoReadAs (show s0) "String" - - skipWs1 :: String -> Either GhciCommandError String - skipWs1 (c:cs) | isWs c = Right (skipWs cs) - skipWs1 s0 = left' $ SpanExpectedWS (show s0) + leftRes = mkError ("Couldn't read" <+> text (show s0) <+> "as String") - left' = Left . GhciArgumentParseError + skipWs1 :: String -> m String + skipWs1 (c:cs) | isWs c = pure (skipWs cs) + skipWs1 s0 = mkError ("Expected whitespace in" <+> text (show s0)) isWs = (`elem` [' ','\t']) skipWs = dropWhile isWs @@ -2496,7 +2466,7 @@ showRealSrcSpan spn = concat [ fp, ":(", show sl, ",", show sc ----------------------------------------------------------------------------- -- | @:kind@ command -kindOfType :: GhciMonad m => Bool -> String -> ExceptGhciError m () +kindOfType :: GhciMonad m => Bool -> String -> m () kindOfType norm str = handleSourceError printErrAndMaybeExit $ do (ty, kind) <- GHC.typeKind norm str printForUser $ vcat [ text str <+> dcolon <+> pprSigmaType kind @@ -2514,11 +2484,11 @@ quit _ = return CleanExit -- running a script file #1363 -scriptCmd :: String -> GhciInput () +scriptCmd :: String -> InputT GHCi () scriptCmd ws = do case words' ws of [s] -> runScript s - _ -> throwGhcException (CmdLineError "syntax: :script ") -- JADE_TODO + _ -> throwGhcException (CmdLineError "syntax: :script ") -- | A version of 'words' that treats sequences enclosed in double quotes as -- single words and that does not break on backslash-escaped spaces. @@ -2536,14 +2506,13 @@ words' s = case dropWhile isSpace s of go acc (c : cs) | isSpace c = acc [] : words' cs | otherwise = go (acc . (c :)) cs -runScript :: () - => String -- ^ filename - -> GhciInput () +runScript :: String -- ^ filename + -> InputT GHCi () runScript filename = do filename' <- expandPath filename either_script <- liftIO $ tryIO (openFile filename' ReadMode) case either_script of - Left _err -> throwGhcException (CmdLineError $ "IO error: \""++filename++"\" " -- JADE_TODO + Left _err -> throwGhcException (CmdLineError $ "IO error: \""++filename++"\" " ++(ioeGetErrorString _err)) Right script -> do st <- getGHCiState @@ -2555,7 +2524,7 @@ runScript filename = do new_st <- getGHCiState setGHCiState new_st{progname=prog,line_number=line} where scriptLoop script = do - res <- runOneCommand handler (lift $ fileLoop script) + res <- runOneCommand handler $ fileLoop script case res of Nothing -> return () Just s -> if s @@ -2567,7 +2536,7 @@ runScript filename = do -- Displaying Safe Haskell properties of a module -isSafeCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +isSafeCmd :: GHC.GhcMonad m => String -> m () isSafeCmd m = case words m of [s] | looksLikeModuleName s -> do @@ -2577,7 +2546,7 @@ isSafeCmd m = isSafeModule md _ -> throwGhcException (CmdLineError "syntax: :issafe ") -isSafeModule :: GHC.GhcMonad m => Module -> ExceptGhciError m () +isSafeModule :: GHC.GhcMonad m => Module -> m () isSafeModule m = do mb_mod_info <- GHC.getModuleInfo m when (isNothing mb_mod_info) @@ -2627,7 +2596,7 @@ isSafeModule m = do -- Browsing a module's contents -browseCmd :: GHC.GhcMonad m => Bool -> String -> ExceptGhciError m () +browseCmd :: GHC.GhcMonad m => Bool -> String -> m () browseCmd bang m = case words m of ['*':s] | looksLikeModuleName s -> do @@ -2657,7 +2626,7 @@ guessCurrentModule cmd = do -- with bang, show class methods and data constructors separately, and -- indicate import modules, to aid qualifying unqualified names -- with sorted, sort items alphabetically -browseModule :: GHC.GhcMonad m => Bool -> Module -> Bool -> ExceptGhciError m () +browseModule :: GHC.GhcMonad m => Bool -> Module -> Bool -> m () browseModule bang modl exports_only = do mb_mod_info <- GHC.getModuleInfo modl case mb_mod_info of @@ -2737,7 +2706,7 @@ browseModule bang modl exports_only = do -- Setting the module context. For details on context handling see -- "remembered_ctx" and "transient_ctx" in GhciMonad. -moduleCmd :: GhciMonad m => String -> ExceptGhciError m () +moduleCmd :: GhciMonad m => String -> m () moduleCmd str | all sensible strs = cmd | otherwise = throwGhcException (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn") @@ -2766,16 +2735,16 @@ moduleCmd str -- (c) :module : setContext -- (d) import ...: addImportToContext -addModulesToContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> ExceptGhciError m () +addModulesToContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> m () addModulesToContext starred unstarred = restoreContextOnFailure $ do addModulesToContext_ starred unstarred -addModulesToContext_ :: GhciMonad m => [ModuleName] -> [ModuleName] -> ExceptGhciError m () +addModulesToContext_ :: GhciMonad m => [ModuleName] -> [ModuleName] -> m () addModulesToContext_ starred unstarred = do mapM_ addII (map mkIIModule starred ++ map mkIIDecl unstarred) setGHCContextFromGHCiState -remModulesFromContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> ExceptGhciError m () +remModulesFromContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> m () remModulesFromContext starred unstarred = do -- we do *not* call restoreContextOnFailure here. If the user -- is trying to fix up a context that contains errors by removing @@ -2783,7 +2752,7 @@ remModulesFromContext starred unstarred = do mapM_ rm (starred ++ unstarred) setGHCContextFromGHCiState where - rm :: GhciMonad m => ModuleName -> ExceptGhciError m () + rm :: GhciMonad m => ModuleName -> m () rm str = do m <- moduleName <$> lookupModuleName str let filt = filter ((/=) m . iiModuleName) @@ -2791,19 +2760,19 @@ remModulesFromContext starred unstarred = do st { remembered_ctx = filt (remembered_ctx st) , transient_ctx = filt (transient_ctx st) } -setContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> ExceptGhciError m () +setContext :: GhciMonad m => [ModuleName] -> [ModuleName] -> m () setContext starred unstarred = restoreContextOnFailure $ do modifyGHCiState $ \st -> st { remembered_ctx = [], transient_ctx = [] } -- delete the transient context addModulesToContext_ starred unstarred -addImportToContext :: GhciMonad m => ImportDecl GhcPs -> ExceptGhciError m () +addImportToContext :: GhciMonad m => ImportDecl GhcPs -> m () addImportToContext idecl = restoreContextOnFailure $ do addII (IIDecl idecl) -- #5836 setGHCContextFromGHCiState -- Util used by addImportToContext and addModulesToContext -addII :: GhciMonad m => InteractiveImport -> ExceptGhciError m () +addII :: GhciMonad m => InteractiveImport -> m () addII iidecl = do checkAdd iidecl modifyGHCiState $ \st -> @@ -2834,7 +2803,7 @@ restoreContextOnFailure do_this = do -- ----------------------------------------------------------------------------- -- Validate a module that we want to add to the context -checkAdd :: GHC.GhcMonad m => InteractiveImport -> ExceptGhciError m () +checkAdd :: GHC.GhcMonad m => InteractiveImport -> m () checkAdd ii = do dflags <- getDynFlags let safe = safeLanguageOn dflags @@ -2866,7 +2835,7 @@ checkAdd ii = do -- override the implicit Prelude import you can say 'import Prelude ()' -- at the prompt, just as in Haskell source. -- -setGHCContextFromGHCiState :: GhciMonad m => ExceptGhciError m () +setGHCContextFromGHCiState :: GhciMonad m => m () setGHCContextFromGHCiState = do st <- getGHCiState -- re-use checkAdd to check whether the module is valid. If the @@ -2982,7 +2951,7 @@ iiSubsumes _ _ = False -- This is pretty fragile: most options won't work as expected. ToDo: -- figure out which ones & disallow them. -setCmd :: GhciMonad m => String -> ExceptGhciError m () +setCmd :: GhciMonad m => String -> m () setCmd "" = showOptions False setCmd "-a" = showOptions True setCmd str @@ -3008,12 +2977,12 @@ setCmd str setLocalConfigBehaviour $ dropWhile isSpace rest _ -> toArgsNoLocWithErrorHandler str (void . keepGoing' setOptions) -setiCmd :: GhciMonad m => String -> ExceptGhciError m () +setiCmd :: GhciMonad m => String -> m () setiCmd "" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags False setiCmd "-a" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags True setiCmd str = toArgsNoLocWithErrorHandler str (newDynFlags True) -showOptions :: GhciMonad m => Bool -> ExceptGhciError m () +showOptions :: GhciMonad m => Bool -> m () showOptions show_all = do st <- getGHCiState dflags <- getDynFlags @@ -3063,9 +3032,9 @@ showDynFlags show_all dflags = do , Opt_PrintEvldWithShow ] -setArgs, setOptions :: GhciMonad m => [String] -> ExceptGhciError m () -setProg, setEditor, setStop :: GhciMonad m => String -> ExceptGhciError m () -setLocalConfigBehaviour :: GhciMonad m => String -> ExceptGhciError m () +setArgs, setOptions :: GhciMonad m => [String] -> m () +setProg, setEditor, setStop :: GhciMonad m => String -> m () +setLocalConfigBehaviour :: GhciMonad m => String -> m () setArgs args = do st <- getGHCiState @@ -3102,13 +3071,13 @@ setStop str@(c:_) | isDigit c setGHCiState st{ breaks = new_breaks } setStop cmd = modifyGHCiState (\st -> st { stop = cmd }) -setPrompt :: GhciMonad m => PromptFunction -> ExceptGhciError m () +setPrompt :: GhciMonad m => PromptFunction -> m () setPrompt v = modifyGHCiState (\st -> st {prompt = v}) -setPromptCont :: GhciMonad m => PromptFunction -> ExceptGhciError m () +setPromptCont :: GhciMonad m => PromptFunction -> m () setPromptCont v = modifyGHCiState (\st -> st {prompt_cont = v}) -setPromptFunc :: GHC.GhcMonad m => (PromptFunction -> ExceptGhciError m ()) -> String -> ExceptGhciError m () +setPromptFunc :: GHC.GhcMonad m => (PromptFunction -> m ()) -> String -> m () setPromptFunc fSetPrompt s = do -- We explicitly annotate the type of the expression to ensure -- that unsafeCoerce# is passed the exact type necessary rather @@ -3123,7 +3092,7 @@ setPromptFunc fSetPrompt s = do liftM text (func mods line)) setPromptString :: MonadIO m - => (PromptFunction -> ExceptGhciError m ()) -> String -> String -> ExceptGhciError m () + => (PromptFunction -> m ()) -> String -> String -> m () setPromptString fSetPrompt value err = do if null value then liftIO $ hPutStrLn stderr $ err @@ -3138,7 +3107,7 @@ setPromptString fSetPrompt value err = do setParsedPromptString fSetPrompt value setParsedPromptString :: MonadIO m - => (PromptFunction -> ExceptGhciError m ()) -> String -> ExceptGhciError m () + => (PromptFunction -> m ()) -> String -> m () setParsedPromptString fSetPrompt s = do case (checkPromptStringForErrors s) of Just err -> @@ -3157,7 +3126,7 @@ setOptions wds = -- use 'parseDynamicFlagsCmdLine' rather than 'parseDynamicFlags'. This -- function is called very often and results in repeatedly loading -- environment files (see #19650) -newDynFlags :: GhciMonad m => Bool -> [String] -> ExceptGhciError m () +newDynFlags :: GhciMonad m => Bool -> [String] -> m () newDynFlags interactive_only minus_opts = do let lopts = map noLoc minus_opts @@ -3226,7 +3195,7 @@ unknownFlagsErr fs = throwGhcException $ CmdLineError $ concatMap oneError fs suggs -> "did you mean one of:\n" ++ unlines (map (" " ++) suggs)) ghciFlags = nubSort $ flagsForCompletion True -unsetOptions :: GhciMonad m => String -> ExceptGhciError m () +unsetOptions :: GhciMonad m => String -> m () unsetOptions str = -- first, deal with the GHCi opts (+s, +t, etc.) let opts = words str @@ -3265,7 +3234,7 @@ isPlus :: String -> Either String String isPlus ('+':opt) = Left opt isPlus other = Right other -setOpt, unsetOpt :: GhciMonad m => String -> ExceptGhciError m () +setOpt, unsetOpt :: GhciMonad m => String -> m () setOpt str = case strToGHCiOpt str of @@ -3296,7 +3265,7 @@ optToStr CollectInfo = "c" -- --------------------------------------------------------------------------- -- :show -showCmd :: forall m. GhciMonad m => String -> ExceptGhciError m () +showCmd :: forall m. GhciMonad m => String -> m () showCmd "" = showOptions False showCmd "-a" = showOptions True showCmd str = do @@ -3304,14 +3273,14 @@ showCmd str = do dflags <- getDynFlags hsc_env <- GHC.getSession - let lookupCmd :: String -> Maybe (ExceptGhciError m ()) + let lookupCmd :: String -> Maybe (m ()) lookupCmd name = lookup name $ map (\(_,b,c) -> (b,c)) cmds -- (show in help?, command name, action) - action :: String -> ExceptGhciError m () -> (Bool, String, ExceptGhciError m ()) + action :: String -> m () -> (Bool, String, m ()) action name m = (True, name, m) - hidden :: String -> ExceptGhciError m () -> (Bool, String, ExceptGhciError m ()) + hidden :: String -> m () -> (Bool, String, m ()) hidden name m = (False, name, m) cmds = @@ -3345,7 +3314,7 @@ showCmd str = do $ hang (text ":show") 6 $ brackets (fsep $ punctuate (text " |") helpCmds) -showiCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +showiCmd :: GHC.GhcMonad m => String -> m () showiCmd str = do case words str of ["languages"] -> showiLanguages -- backwards compat @@ -3353,7 +3322,7 @@ showiCmd str = do ["lang"] -> showiLanguages -- useful abbreviation _ -> throwGhcException (CmdLineError ("syntax: :showi language")) -showImports :: GhciMonad m => ExceptGhciError m () +showImports :: GhciMonad m => m () showImports = do st <- getGHCiState dflags <- getDynFlags @@ -3376,7 +3345,7 @@ showImports = do map show_prel prel_iidecls ++ map show_extra (extra_imports st)) -showModules :: GHC.GhcMonad m => ExceptGhciError m () +showModules :: GHC.GhcMonad m => m () showModules = do loaded_mods <- getLoadedModules -- we want *loaded* modules only, see #1734 @@ -3388,7 +3357,7 @@ getLoadedModules = do graph <- GHC.getModuleGraph filterM isLoadedModSummary (GHC.mgModSummaries graph) -showBindings :: GHC.GhcMonad m => ExceptGhciError m () +showBindings :: GHC.GhcMonad m => m () showBindings = do bindings <- GHC.getBindings (insts, finsts) <- GHC.getInsts @@ -3411,7 +3380,7 @@ showBindings = do $$ showFixity thing fixity -printTyThing :: GHC.GhcMonad m => TyThing -> ExceptGhciError m () +printTyThing :: GHC.GhcMonad m => TyThing -> m () printTyThing tyth = printForUser (pprTyThing showToHeader tyth) isLoadedModSummary :: GHC.GhcMonad m => ModSummary -> m Bool @@ -3439,12 +3408,12 @@ Note [What to show to users] in GHC.Runtime.Eval -} -showBkptTable :: GhciMonad m => ExceptGhciError m () +showBkptTable :: GhciMonad m => m () showBkptTable = do st <- getGHCiState printForUser $ prettyLocations (breaks st) -showContext :: GHC.GhcMonad m => ExceptGhciError m () +showContext :: GHC.GhcMonad m => m () showContext = do resumes <- GHC.getResumeContext printForUser $ vcat (map pp_resume (reverse resumes)) @@ -3464,7 +3433,7 @@ pprStopped res = where mb_mod_name = moduleName <$> GHC.breakInfo_module <$> GHC.resumeBreakInfo res -showUnits :: GHC.GhcMonad m => ExceptGhciError m () +showUnits :: GHC.GhcMonad m => m () showUnits = do dflags <- getDynFlags let pkg_flags = packageFlags dflags @@ -3472,7 +3441,7 @@ showUnits = do text ("active package flags:"++if null pkg_flags then " none" else "") $$ nest 2 (vcat (map pprFlag pkg_flags)) -showPaths :: GHC.GhcMonad m => ExceptGhciError m () +showPaths :: GHC.GhcMonad m => m () showPaths = do dflags <- getDynFlags liftIO $ do @@ -3485,10 +3454,10 @@ showPaths = do text ("module import search paths:"++if null ipaths then " none" else "") $$ nest 2 (vcat (map text ipaths)) -showLanguages :: GHC.GhcMonad m => ExceptGhciError m () +showLanguages :: GHC.GhcMonad m => m () showLanguages = getDynFlags >>= liftIO . showLanguages' False -showiLanguages :: GHC.GhcMonad m => ExceptGhciError m () +showiLanguages :: GHC.GhcMonad m => m () showiLanguages = GHC.getInteractiveDynFlags >>= liftIO . showLanguages' False showLanguages' :: Bool -> DynFlags -> IO () @@ -3519,10 +3488,10 @@ showLanguages' show_all dflags = lang = fromMaybe defaultLanguage (language dflags) -showTargets :: GHC.GhcMonad m => ExceptGhciError m () +showTargets :: GHC.GhcMonad m => m () showTargets = mapM_ showTarget =<< GHC.getTargets where - showTarget :: GHC.GhcMonad m => Target -> ExceptGhciError m () + showTarget :: GHC.GhcMonad m => Target -> m () showTarget Target { targetId = TargetFile f _ } = liftIO (putStrLn f) showTarget Target { targetId = TargetModule m } = liftIO (putStrLn $ moduleNameString m) @@ -3822,18 +3791,18 @@ arrays the available identifiers of the nested functions. -- ----------------------------------------------------------------------------- -- commands for debugger -sprintCmd, printCmd, forceCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +sprintCmd, printCmd, forceCmd :: GHC.GhcMonad m => String -> m () sprintCmd = pprintClosureCommand False False printCmd = pprintClosureCommand True False forceCmd = pprintClosureCommand False True -stepCmd :: GhciMonad m => String -> ExceptGhciError m () +stepCmd :: GhciMonad m => String -> m () stepCmd arg = withSandboxOnly ":step" $ step arg where step [] = doContinue (const True) GHC.SingleStep step expression = runStmt expression GHC.SingleStep >> return () -stepLocalCmd :: GhciMonad m => String -> ExceptGhciError m () +stepLocalCmd :: GhciMonad m => String -> m () stepLocalCmd arg = withSandboxOnly ":steplocal" $ step arg where step expr @@ -3851,7 +3820,7 @@ stepLocalCmd arg = withSandboxOnly ":steplocal" $ step arg current_toplevel_decl <- enclosingTickSpan md loc doContinue (`isSubspanOf` RealSrcSpan current_toplevel_decl Strict.Nothing) GHC.SingleStep -stepModuleCmd :: GhciMonad m => String -> ExceptGhciError m () +stepModuleCmd :: GhciMonad m => String -> m () stepModuleCmd arg = withSandboxOnly ":stepmodule" $ step arg where step expr @@ -3879,14 +3848,14 @@ enclosingTickSpan md (RealSrcSpan src _) = do leftmostLargestRealSrcSpan :: RealSrcSpan -> RealSrcSpan -> Ordering leftmostLargestRealSrcSpan = on compare realSrcSpanStart S.<> on (flip compare) realSrcSpanEnd -traceCmd :: GhciMonad m => String -> ExceptGhciError m () +traceCmd :: GhciMonad m => String -> m () traceCmd arg = withSandboxOnly ":trace" $ tr arg where tr [] = doContinue (const True) GHC.RunAndLogSteps tr expression = runStmt expression GHC.RunAndLogSteps >> return () -continueCmd :: GhciMonad m => String -> ExceptGhciError m () -- #19157 +continueCmd :: GhciMonad m => String -> m () -- #19157 continueCmd argLine = withSandboxOnly ":continue" $ case contSwitch (words argLine) of Left sdoc -> printForUser sdoc @@ -3898,25 +3867,25 @@ continueCmd argLine = withSandboxOnly ":continue" $ contSwitch _ = Left $ text "After ':continue' only one ignore count is allowed" -doContinue :: GhciMonad m => (SrcSpan -> Bool) -> SingleStep -> ExceptGhciError m () +doContinue :: GhciMonad m => (SrcSpan -> Bool) -> SingleStep -> m () doContinue pre step = doContinue' pre step Nothing -doContinue' :: GhciMonad m => (SrcSpan -> Bool) -> SingleStep -> Maybe Int -> ExceptGhciError m () +doContinue' :: GhciMonad m => (SrcSpan -> Bool) -> SingleStep -> Maybe Int -> m () doContinue' pre step mbCnt= do runResult <- resume pre step mbCnt _ <- afterRunStmt pre runResult return () -abandonCmd :: GhciMonad m => String -> ExceptGhciError m () +abandonCmd :: GhciMonad m => String -> m () abandonCmd = noArgs $ withSandboxOnly ":abandon" $ do b <- GHC.abandon -- the prompt will change to indicate the new context when (not b) $ liftIO $ putStrLn "There is no computation running." -deleteCmd :: GhciMonad m => String -> ExceptGhciError m () +deleteCmd :: GhciMonad m => String -> m () deleteCmd argLine = withSandboxOnly ":delete" $ do deleteSwitch $ words argLine where - deleteSwitch :: GhciMonad m => [String] -> ExceptGhciError m () + deleteSwitch :: GhciMonad m => [String] -> m () deleteSwitch [] = liftIO $ putStrLn "The delete command requires at least one argument." -- delete all break points @@ -3924,20 +3893,20 @@ deleteCmd argLine = withSandboxOnly ":delete" $ do deleteSwitch idents = do mapM_ deleteOneBreak idents where - deleteOneBreak :: GhciMonad m => String -> ExceptGhciError m () + deleteOneBreak :: GhciMonad m => String -> m () deleteOneBreak str | all isDigit str = deleteBreak (read str) | otherwise = return () -enableCmd :: GhciMonad m => String -> ExceptGhciError m () +enableCmd :: GhciMonad m => String -> m () enableCmd argLine = withSandboxOnly ":enable" $ do enaDisaSwitch True $ words argLine -disableCmd :: GhciMonad m => String -> ExceptGhciError m () +disableCmd :: GhciMonad m => String -> m () disableCmd argLine = withSandboxOnly ":disable" $ do enaDisaSwitch False $ words argLine -enaDisaSwitch :: GhciMonad m => Bool -> [String] -> ExceptGhciError m () +enaDisaSwitch :: GhciMonad m => Bool -> [String] -> m () enaDisaSwitch enaDisa [] = printForUser (text "The" <+> text strCmd <+> text "command requires at least one argument.") @@ -3947,19 +3916,19 @@ enaDisaSwitch enaDisa ("*" : _) = enaDisaAllBreaks enaDisa enaDisaSwitch enaDisa idents = do mapM_ (enaDisaOneBreak enaDisa) idents where - enaDisaOneBreak :: GhciMonad m => Bool -> String -> ExceptGhciError m () + enaDisaOneBreak :: GhciMonad m => Bool -> String -> m () enaDisaOneBreak enaDisa strId = do sdoc_loc <- checkEnaDisa enaDisa strId case sdoc_loc of Left sdoc -> printForUser sdoc Right loc -> enaDisaAssoc enaDisa (read strId, loc) -checkEnaDisa :: GhciMonad m => Bool -> String -> ExceptGhciError m (Either SDoc BreakLocation) +checkEnaDisa :: GhciMonad m => Bool -> String -> m (Either SDoc BreakLocation) checkEnaDisa enaDisa strId = do sdoc_loc <- getBreakLoc strId pure $ sdoc_loc >>= checkEnaDisaState enaDisa strId -getBreakLoc :: GhciMonad m => String -> ExceptGhciError m (Either SDoc BreakLocation) +getBreakLoc :: GhciMonad m => String -> m (Either SDoc BreakLocation) getBreakLoc strId = do st <- getGHCiState case readMaybe strId >>= flip IntMap.lookup (breaks st) of @@ -3974,19 +3943,19 @@ checkEnaDisaState enaDisa strId loc = do text "Breakpoint" <+> text strId <+> text "already in desired state" else Right loc -enaDisaAssoc :: GhciMonad m => Bool -> (Int, BreakLocation) -> ExceptGhciError m () +enaDisaAssoc :: GhciMonad m => Bool -> (Int, BreakLocation) -> m () enaDisaAssoc enaDisa (intId, loc) = do st <- getGHCiState newLoc <- turnBreakOnOff enaDisa loc let new_breaks = IntMap.insert intId newLoc (breaks st) setGHCiState $ st { breaks = new_breaks } -enaDisaAllBreaks :: GhciMonad m => Bool -> ExceptGhciError m () +enaDisaAllBreaks :: GhciMonad m => Bool -> m() enaDisaAllBreaks enaDisa = do st <- getGHCiState mapM_ (enaDisaAssoc enaDisa) $ IntMap.assocs $ breaks st -historyCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +historyCmd :: GHC.GhcMonad m => String -> m () historyCmd arg | null arg = history 20 | all isDigit arg = history (read arg) @@ -4017,7 +3986,7 @@ bold :: SDoc -> SDoc bold c | do_bold = text start_bold <> c <> text end_bold | otherwise = c -ignoreCmd :: GhciMonad m => String -> ExceptGhciError m () -- #19157 +ignoreCmd :: GhciMonad m => String -> m () -- #19157 ignoreCmd argLine = withSandboxOnly ":ignore" $ do result <- ignoreSwitch (words argLine) case result of @@ -4026,7 +3995,7 @@ ignoreCmd argLine = withSandboxOnly ":ignore" $ do let breakInfo = GHC.BreakInfo (breakModule loc) (breakTick loc) setupBreakpoint breakInfo count -ignoreSwitch :: GhciMonad m => [String] -> ExceptGhciError m (Either SDoc (BreakLocation, Int)) +ignoreSwitch :: GhciMonad m => [String] -> m (Either SDoc (BreakLocation, Int)) ignoreSwitch [break, count] = do sdoc_loc <- getBreakLoc break pure $ (,) <$> sdoc_loc <*> getIgnoreCount count @@ -4041,12 +4010,12 @@ getIgnoreCount str = where sdocIgnore = text "Ignore count" <+> quotes (text str) -setupBreakpoint :: GhciMonad m => GHC.BreakInfo -> Int -> ExceptGhciError m () +setupBreakpoint :: GhciMonad m => GHC.BreakInfo -> Int -> m() setupBreakpoint loc count = do hsc_env <- GHC.getSession GHC.setupBreakpoint hsc_env loc count -backCmd :: GhciMonad m => String -> ExceptGhciError m () +backCmd :: GhciMonad m => String -> m () backCmd arg | null arg = back 1 | all isDigit arg = back (read arg) @@ -4060,7 +4029,7 @@ backCmd arg st <- getGHCiState enqueueCommands [stop st] -forwardCmd :: GhciMonad m => String -> ExceptGhciError m () +forwardCmd :: GhciMonad m => String -> m () forwardCmd arg | null arg = forward 1 | all isDigit arg = forward (read arg) @@ -4077,10 +4046,10 @@ forwardCmd arg enqueueCommands [stop st] -- handle the "break" command -breakCmd :: GhciMonad m => String -> ExceptGhciError m () +breakCmd :: GhciMonad m => String -> m () breakCmd argLine = withSandboxOnly ":break" $ breakSwitch $ words argLine -breakSwitch :: GhciMonad m => [String] -> ExceptGhciError m () +breakSwitch :: GhciMonad m => [String] -> m () breakSwitch [] = do liftIO $ putStrLn "The break command requires at least one argument." breakSwitch (arg1:rest) @@ -4098,14 +4067,14 @@ breakSwitch (arg1:rest) | otherwise = do -- try parsing it as an identifier breakById arg1 -breakByModule :: GhciMonad m => Module -> [String] -> ExceptGhciError m () +breakByModule :: GhciMonad m => Module -> [String] -> m () breakByModule md (arg1:rest) | all isDigit arg1 = do -- looks like a line number breakByModuleLine md (read arg1) rest breakByModule _ _ = breakSyntax -breakByModuleLine :: GhciMonad m => Module -> Int -> [String] -> ExceptGhciError m () +breakByModuleLine :: GhciMonad m => Module -> Int -> [String] -> m () breakByModuleLine md line args | [] <- args = findBreakAndSet md $ maybeToList . findBreakByLine line | [col] <- args, all isDigit col = @@ -4114,7 +4083,7 @@ breakByModuleLine md line args -- Set a breakpoint for an identifier -- See Note [Setting Breakpoints by Id] -breakById :: GhciMonad m => String -> ExceptGhciError m () -- #3000 +breakById :: GhciMonad m => String -> m () -- #3000 breakById inp = do let (mod_str, top_level, fun_str) = splitIdent inp mod_top_lvl = combineModIdent mod_str top_level @@ -4178,7 +4147,7 @@ breakSyntax = throwGhcException $ CmdLineError ("Syntax: :break [.][. ++ " :break [] []") findBreakAndSet :: GhciMonad m - => Module -> (TickArray -> [(Int, RealSrcSpan)]) -> ExceptGhciError m () + => Module -> (TickArray -> [(Int, RealSrcSpan)]) -> m () findBreakAndSet md lookupTickTree = do tickArray <- getTickArray md case lookupTickTree tickArray of @@ -4297,7 +4266,7 @@ The names of nested functions are stored in `ModBreaks.modBreaks_decls`. ----------------------------------------------------------------------------- -- :where -whereCmd :: GHC.GhcMonad m => String -> ExceptGhciError m () +whereCmd :: GHC.GhcMonad m => String -> m () whereCmd = noArgs $ do mstrs <- getCallStackAtCurrentBreakpoint case mstrs of @@ -4307,7 +4276,7 @@ whereCmd = noArgs $ do ----------------------------------------------------------------------------- -- :list -listCmd :: GhciMonad m => String -> ExceptGhciError m () +listCmd :: GhciMonad m => String -> m () listCmd "" = do mb_span <- getCurrentBreakSpan case mb_span of @@ -4329,7 +4298,7 @@ listCmd "" = do $$ text "Try" <+> doWhat) listCmd str = list2 (words str) -list2 :: GhciMonad m => [String] -> ExceptGhciError m () +list2 :: GhciMonad m => [String] -> m () list2 [arg] | all isDigit arg = do imports <- GHC.getContext case iiModules imports of @@ -4362,7 +4331,7 @@ list2 [arg] = do list2 _other = liftIO $ putStrLn "syntax: :list [ | | ]" -listModuleLine :: GHC.GhcMonad m => Module -> Int -> ExceptGhciError m () +listModuleLine :: GHC.GhcMonad m => Module -> Int -> m () listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl @@ -4382,7 +4351,7 @@ listModuleLine modl line = do -- 2) convert the BS to String using utf-string, and write it out. -- It would be better if we could convert directly between UTF-8 and the -- console encoding, of course. -listAround :: MonadIO m => RealSrcSpan -> Bool -> ExceptGhciError m () +listAround :: MonadIO m => RealSrcSpan -> Bool -> m () listAround pan do_highlight = do contents <- liftIO $ BS.readFile (unpackFS file) -- Drop carriage returns to avoid duplicates, see #9367. @@ -4460,7 +4429,7 @@ getTickArray modl = do setGHCiState st{tickarrays = extendModuleEnv arrmap modl arr} return arr -discardTickArrays :: GhciMonad m => ExceptGhciError m () +discardTickArrays :: GhciMonad m => m () discardTickArrays = modifyGHCiState (\st -> st {tickarrays = emptyModuleEnv}) mkTickArray :: [(BreakIndex,SrcSpan)] -> TickArray @@ -4472,17 +4441,17 @@ mkTickArray ticks srcSpanLines pan = [ GHC.srcSpanStartLine pan .. GHC.srcSpanEndLine pan ] -- don't reset the counter back to zero? -discardActiveBreakPoints :: GhciMonad m => ExceptGhciError m () +discardActiveBreakPoints :: GhciMonad m => m () discardActiveBreakPoints = do st <- getGHCiState mapM_ (turnBreakOnOff False) $ breaks st setGHCiState $ st { breaks = IntMap.empty } -discardInterfaceCache :: GhciMonad m => ExceptGhciError m () +discardInterfaceCache :: GhciMonad m => m () discardInterfaceCache = void (liftIO . iface_clearCache . ifaceCache =<< getGHCiState) -clearHPTs :: GhciMonad m => ExceptGhciError m () +clearHPTs :: GhciMonad m => m () clearHPTs = do let pruneHomeUnitEnv hme = hme { homeUnitEnv_hpt = emptyHomePackageTable } discardMG hsc = hsc { hsc_mod_graph = GHC.emptyMG } @@ -4495,10 +4464,10 @@ clearHPTs = do -- changes (via :load or :cd), at which stage the package flags are not going to change -- but the loaded modules will probably not use all the specified packages so the -- warning becomes spurious. At that point the warning is silently disabled. -disableUnusedPackages :: GhciMonad m => ExceptGhciError m () +disableUnusedPackages :: GhciMonad m => m () disableUnusedPackages = newDynFlags False ["-Wno-unused-packages"] -deleteBreak :: GhciMonad m => Int -> ExceptGhciError m () +deleteBreak :: GhciMonad m => Int -> m () deleteBreak identity = do st <- getGHCiState let oldLocations = breaks st @@ -4510,7 +4479,7 @@ deleteBreak identity = do let rest = IntMap.delete identity oldLocations setGHCiState $ st { breaks = rest } -turnBreakOnOff :: GhciMonad m => Bool -> BreakLocation -> ExceptGhciError m BreakLocation +turnBreakOnOff :: GhciMonad m => Bool -> BreakLocation -> m BreakLocation turnBreakOnOff onOff loc | onOff == breakEnabled loc = return loc | otherwise = do @@ -4526,7 +4495,7 @@ getModBreak m = do let decls = GHC.modBreaks_decls modBreaks return (ticks, decls) -setBreakFlag :: GhciMonad m => Module -> Int -> Bool -> ExceptGhciError m () +setBreakFlag :: GhciMonad m => Module -> Int -> Bool ->m () setBreakFlag md ix enaDisa = do let enaDisaToCount True = breakOn enaDisaToCount False = breakOff @@ -4545,17 +4514,17 @@ setBreakFlag md ix enaDisa = do -- raising another exception. We therefore don't put the recursive -- handler around the flushing operation, so if stderr is closed -- GHCi will just die gracefully rather than going into an infinite loop. -handler :: GhciMonad m => SomeException -> ExceptGhciError m Bool +handler :: GhciMonad m => SomeException -> m Bool handler exception = do flushInterpBuffers withSignalHandlers $ - ghciHandle handler (showException exception >> return False) -- JADE_TODO + ghciHandle handler (showException exception >> return False) showException :: MonadIO m => SomeException -> m () showException se = liftIO $ case fromException se of -- omit the location for CmdLineError: - Just (CmdLineError s) -> putException (s ++ "aaa") + Just (CmdLineError s) -> putException s -- ditto: Just other_ghc_ex -> putException (show other_ghc_ex) Nothing -> @@ -4667,10 +4636,10 @@ wantInterpretedModuleName modname = do return modl wantNameFromInterpretedModule :: GHC.GhcMonad m - => (Name -> SDoc -> ExceptGhciError m ()) + => (Name -> SDoc -> m ()) -> String - -> (Name -> ExceptGhciError m ()) - -> ExceptGhciError m () + -> (Name -> m ()) + -> m () wantNameFromInterpretedModule noCanDo str and_then = handleSourceError printGhciException $ do n NE.:| _ <- GHC.parseName str @@ -4685,7 +4654,7 @@ wantNameFromInterpretedModule noCanDo str and_then = text " is not interpreted" else and_then n -clearCaches :: GhciMonad m => ExceptGhciError m () +clearCaches :: GhciMonad m => m () clearCaches = discardActiveBreakPoints >> discardInterfaceCache >> disableUnusedPackages ===================================== ghc/GHCi/UI/Exception.hs ===================================== @@ -8,8 +8,6 @@ module GHCi.UI.Exception ( printGhciException , GHCiMessage(..) , GhciCommandError(..) - , GhciArgumentParseError(..) - , GhciInput , reportError) where import GHC.Prelude @@ -40,21 +38,46 @@ import GHC.Utils.Outputable import Control.Monad.IO.Class import GHC.Generics -import Control.Monad.Trans.Except (ExceptT (..), throwE) +import Control.Exception (Exception, throwIO) import System.Console.Haskeline (InputT) import Control.Monad.Trans.Class --- JADE_TODO -newtype GhciInput m a = GhciInput - { getGhciInput :: ExceptT GhciCommandError (InputT m) a } - deriving (Functor, Applicative, Monad, MonadIO) +reportError :: MonadIO m => GhciCommandError -> m a +reportError = liftIO . throwIO -instance MonadTrans GhciInput where - lift = lift -- JADE_TODO +instance Exception GhciCommandError -reportError :: Monad m => GhciCommandError -> GhciInput m a -reportError = GhciInput . throwE +data GhciCommandError + -- macro errors + = GhciMacroAlreadyDefined String + | GhciMacroInvalidStart String + | GhciMacroNotDefined + | GhciMacroOverwritesBuiltin String + -- module name errors + | GhciModuleNotFound String + | GhciNoModuleNameGuess + | GhciNoModuleInfoForCurrentFile + | GhciNoLocationInfoForModule ModuleName + | GhciNoResolvedModules + | GhciNoModuleForName Name + | GhciNoMatchingModuleExport + -- argument parse error + | GhciArgumentParseError SDoc + -- Basic errors + | GhciCommandNotSupportedInMultiMode + | GhciInvalidArgumentString String + | GhciFileNotFound String + | GhciCommandSyntaxError String [String] + | GhciInvalidPromptString + | GhciPromptCallError String + | GhciUnknownCommand String String + | GhciNoLastCommandAvailable String + | GhciUnknownFlag String [String] + | GhciNoSetEditor + deriving Generic +instance Show GhciCommandError where + show = showSDocUnsafe . ppr -- | Print the all diagnostics in a 'SourceError'. Specialised for GHCi error reporting -- for some error messages. @@ -166,49 +189,6 @@ ghciDiagnosticMessage ghc_opts msg = text "to expose it." $$ text "(Note: this unloads all the modules in the current scope.)" -data GhciArgumentParseError - = SpanPrematureEnd - | SpanNoReadAs String String - | SpanExpectedWS String - -instance Outputable GhciArgumentParseError where - ppr = \case - SpanPrematureEnd - -> "Premature end of string while expecting Int" - SpanNoReadAs actual expected - -> "Couldn't read" <+> text actual <+> "as" <+> text expected - SpanExpectedWS str - -> "Expected whitespace in" <+> text str - -data GhciCommandError - -- macro errors - = GhciMacroAlreadyDefined String - | GhciMacroInvalidStart String - | GhciMacroNotDefined - | GhciMacroOverwritesBuiltin String - -- module name errors - | GhciModuleNotFound String - | GhciNoModuleNameGuess - | GhciNoModuleInfoForCurrentFile - | GhciNoLocationInfoForModule ModuleName - | GhciNoResolvedModules - | GhciNoModuleForName Name - | GhciNoMatchingModuleExport - -- argument parse error - | GhciArgumentParseError GhciArgumentParseError - -- Basic errors - | GhciCommandNotSupportedInMultiMode - | GhciInvalidArgumentString String - | GhciFileNotFound String - | GhciCommandSyntaxError String [String] - | GhciInvalidPromptString - | GhciPromptCallError String - | GhciUnknownCommand String String - | GhciNoLastCommandAvailable String - | GhciUnknownFlag String [String] - | GhciNoSetEditor - deriving Generic - instance Outputable GhciCommandError where ppr = \case GhciMacroAlreadyDefined name @@ -231,7 +211,7 @@ instance Outputable GhciCommandError where -> "No module for" <+> ppr name GhciNoMatchingModuleExport -> "No matching export in any local modules." - GhciArgumentParseError ape -> ppr ape + GhciArgumentParseError ape -> ape GhciCommandNotSupportedInMultiMode -> "Command is not supported (yet) in multi-mode" GhciInvalidArgumentString str ===================================== ghc/GHCi/UI/Info.hs ===================================== @@ -20,6 +20,7 @@ module GHCi.UI.Info import Control.Exception import Control.Monad +import Control.Monad.IO.Class import Control.Monad.Catch as MC import Control.Monad.Trans.Class import Control.Monad.Trans.Except @@ -115,18 +116,15 @@ findLoc :: GhcMonad m => Map ModuleName ModInfo -> RealSrcSpan -> String - -> GhciInput m (ModInfo,Name,SrcSpan) + -> m (ModInfo,Name,SrcSpan) findLoc infos span0 string = do - name <- maybeToExceptT GhciNoModuleNameGuess $ - guessModule infos (srcSpanFilePath span0) - - info <- lift $ maybeToExceptT GhciNoModuleInfoForCurrentFile $ - MaybeT $ pure $ M.lookup name infos + name <- guessModule infos (srcSpanFilePath span0) `orElseThrow` GhciNoModuleNameGuess + info <- hoistMaybe (M.lookup name infos) `orElseThrow` GhciNoModuleInfoForCurrentFile name' <- findName infos span0 info string case getSrcSpan name' of - UnhelpfulSpan{} -> reportError $ GhciNoLocationInfoForModule $ maybe (ModuleName "") moduleName (nameModule_maybe name') + UnhelpfulSpan{} -> reportError $ GhciNoLocationInfoForModule (maybe (ModuleName "") moduleName (nameModule_maybe name')) span' -> pure (info,name',span') -- | Find any uses of the given identifier in the codebase. @@ -134,7 +132,7 @@ findNameUses :: (GhcMonad m) => Map ModuleName ModInfo -> RealSrcSpan -> String - -> GhciInput m [SrcSpan] + -> m [SrcSpan] findNameUses infos span0 string = locToSpans <$> findLoc infos span0 string where @@ -162,7 +160,7 @@ findName :: GhcMonad m -> RealSrcSpan -> ModInfo -> String - -> GhciInput m Name + -> m Name findName infos span0 mi string = case resolveName (modinfoSpans mi) (spanInfoFromRealSrcSpan' span0) of Nothing -> tryExternalModuleResolution @@ -186,10 +184,9 @@ findName infos span0 mi string = resolveNameFromModule :: GhcMonad m => Map ModuleName ModInfo -> Name - -> GhciInput m Name + -> m Name resolveNameFromModule infos name = do - modL <- maybe (reportError $ GhciNoModuleForName name) pure $ - nameModule_maybe name + modL <- hoistMaybe (nameModule_maybe name) `orElseThrow` GhciNoModuleForName name -- info <- maybe (throwE (ppr (moduleUnit modL) <> ":" <> JADE_TODO -- ppr modL)) return $ @@ -211,23 +208,25 @@ resolveName :: [SpanInfo] -> SpanInfo -> Maybe Var resolveName spans' si = listToMaybe $ mapMaybe spaninfoVar $ reverse spans' `spaninfosWithin` si -orErrorWith :: Maybe a -> GhciCommandError -> GhciInput m a -orErrorWith m err = maybe (reportError err) pure m +orElseThrow :: MonadIO m => MaybeT m a -> GhciCommandError -> m a +orElseThrow mt err = do + x <- runMaybeT mt + maybe (reportError err) pure x + -- | Try to find the type of the given span. findType :: GhcMonad m => Map ModuleName ModInfo -> RealSrcSpan -> String - -> GhciInput m (ModInfo, Type) + -> m (ModInfo, Type) findType infos span0 string = do - name <- guessModule infos (srcSpanFilePath span0) `orErrorWith` GhciNoModuleNameGuess - -- info <- lift $ maybeToExceptT GhciNoModuleInfoForCurrentFile $ M.lookup name infos - info <- M.lookup name infos `orErrorWith` GhciNoModuleInfoForCurrentFile + name <- guessModule infos (srcSpanFilePath span0) `orElseThrow` GhciNoModuleNameGuess + info <- hoistMaybe (M.lookup name infos) `orElseThrow` GhciNoModuleInfoForCurrentFile case resolveType (modinfoSpans info) (spanInfoFromRealSrcSpan' span0) of - Nothing -> (,) info <$> lift (exprType TM_Inst string) - Just ty -> return (info, ty) + Nothing -> (,) info <$> (exprType TM_Inst string) + Just ty -> pure (info, ty) where -- | Try to resolve the type display from the given span. resolveType :: [SpanInfo] -> SpanInfo -> Maybe Type ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -14,7 +14,6 @@ module GHCi.UI.Monad ( GHCiState(..), GhciMonad(..), GHCiOption(..), isOptionSet, setOption, unsetOption, Command(..), CommandResult(..), cmdSuccess, - GhciInput, CmdExecOutcome(..), LocalConfigBehaviour(..), PromptFunction, @@ -59,7 +58,7 @@ import GHC.Builtin.Names (gHC_INTERNAL_GHCI_HELPERS) import GHC.Runtime.Interpreter import GHC.Runtime.Context import GHCi.RemoteTypes -import GHCi.UI.Exception (printGhciException, GhciCommandError, ExceptGhciError, reportError) +import GHCi.UI.Exception (printGhciException, GhciCommandError, reportError) import GHC.Hs (ImportDecl, GhcPs, GhciLStmt, LHsDecl) import GHC.Hs.Utils import GHC.Utils.Misc @@ -92,9 +91,6 @@ import Control.Monad.Trans.Except ----------------------------------------------------------------------------- -- GHCi monad -runGhciInput :: GhciMonad m => Settings m -> GhciInput m a -> m (Either GhciCommandError a) -runGhciInput settings = runExceptT . runInputT settings . getGhciInput - data GHCiState = GHCiState { progname :: String, @@ -121,7 +117,7 @@ data GHCiState = GHCiState last_command :: Maybe Command, -- ^ @:@ at the GHCi prompt repeats the last command, so we -- remember it here - cmd_wrapper :: GhciInput CommandResult -> GhciInput (Maybe Bool), + cmd_wrapper :: InputT GHCi CommandResult -> InputT GHCi (Maybe Bool), -- ^ The command wrapper is run for each command or statement. -- The 'Bool' value denotes whether the command is successful and -- 'Nothing' means to exit GHCi. @@ -187,7 +183,7 @@ data Command = Command { cmdName :: String -- ^ Name of GHCi command (e.g. "exit") - , cmdAction :: String -> GhciInput CmdExecOutcome + , cmdAction :: String -> InputT GHCi CmdExecOutcome -- ^ The 'CmdExecOutcome' value denotes whether to exit GHCi cleanly or error out , cmdHidden :: Bool -- ^ Commands which are excluded from default completion @@ -228,7 +224,7 @@ cmdSuccess CommandIncomplete = return $ Just True type PromptFunction = [String] -> Int - -> ExceptGhciError GHCi SDoc + -> GHCi SDoc data GHCiOption = ShowTiming -- show time/allocs after evaluation @@ -322,20 +318,12 @@ instance GhciMonad GHCi where modifyGHCiState f = GHCi $ \r -> liftIO $ modifyIORef' r f reifyGHCi f = GHCi $ \r -> reifyGhc $ \s -> f (s, r) -{- instance GhciMonad (InputT GHCi) where getGHCiState = lift getGHCiState setGHCiState = lift . setGHCiState modifyGHCiState = lift . modifyGHCiState reifyGHCi = lift . reifyGHCi -instance GhciMonad m => GhciMonad (ExceptGhciError m) where - getGHCiState = lift getGHCiState - setGHCiState = lift . setGHCiState - modifyGHCiState = lift . modifyGHCiState - reifyGHCi = lift . reifyGHCi --} - liftGhc :: Ghc a -> GHCi a liftGhc m = GHCi $ \_ -> m @@ -358,17 +346,10 @@ instance HasDynFlags (InputT GHCi) where instance HasLogger (InputT GHCi) where getLogger = lift getLogger -instance (Monad m, HasLogger m) => HasLogger (ExceptGhciError m) where - getLogger = lift getLogger - instance GhcMonad (InputT GHCi) where setSession = lift . setSession getSession = lift getSession -instance GhcMonad m => GhcMonad (ExceptGhciError m) where - setSession = lift . setSession - getSession = lift getSession - isOptionSet :: GhciMonad m => GHCiOption -> m Bool isOptionSet opt = do st <- getGHCiState View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dda3e84992623132fee0bf58de5115a89f2c1ad1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dda3e84992623132fee0bf58de5115a89f2c1ad1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 18:56:16 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 14:56:16 -0400 Subject: [Git][ghc/ghc][wip/submodule-bumps] 211 commits: add -fprof-late-overloaded and -fprof-late-overloaded-calls Message-ID: <661d785047b62_3aba19b430d410991@gitlab.mail> Ben Gamari pushed to branch wip/submodule-bumps at Glasgow Haskell Compiler / GHC Commits: 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - afa5332a by Ben Gamari at 2024-04-15T14:55:36-04:00 Bump various submodule Bumps array, binary, parsec, and stm submodule to match `ghc-9.10`. Fixing #24643 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/LateCC.hs - + compiler/GHC/Core/LateCC/OverloadedCalls.hs - + compiler/GHC/Core/LateCC/TopLevelBinds.hs - + compiler/GHC/Core/LateCC/Types.hs - + compiler/GHC/Core/LateCC/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6799904fb12272f2cd9a047f4c821ae0bc931ce7...afa5332a8c28944e637bf5d8d73365db373f48e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6799904fb12272f2cd9a047f4c821ae0bc931ce7...afa5332a8c28944e637bf5d8d73365db373f48e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 19:04:03 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 15:04:03 -0400 Subject: [Git][ghc/ghc][wip/submodule-bumps] Bump various submodule Message-ID: <661d7a23d3aa6_3aba19d65984118251@gitlab.mail> Ben Gamari pushed to branch wip/submodule-bumps at Glasgow Haskell Compiler / GHC Commits: 410fc69b by Ben Gamari at 2024-04-15T15:03:43-04:00 Bump various submodule Bumps process, array, binary, parsec, and stm submodules to match `ghc-9.10`. Closes #24643, #24644. - - - - - 5 changed files: - libraries/array - libraries/binary - libraries/parsec - libraries/process - libraries/stm Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit 510456786715d96dfc9e9bc4cead9aace1ce2db6 +Subproject commit a65f8a5e7c26fe9b8012b90cbbff8866f8d39113 ===================================== libraries/binary ===================================== @@ -1 +1 @@ -Subproject commit b30971d569e934cd54d08c45c7e906cfe8af3709 +Subproject commit a501955f7ab48da81d732958c8834caaa3e470b6 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit a53f925e3ee246e2429418b7a088ecaa0976007b +Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit 4e7aa7885b3f9724b19e68d12cbd2774b11b9bd0 +Subproject commit ff8f8ceeceb14ac59accd53dd82a5d32c7e08626 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/410fc69bd5c5e71842fcd9e211b759ebecff0d70 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/410fc69bd5c5e71842fcd9e211b759ebecff0d70 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 19:08:56 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 15:08:56 -0400 Subject: [Git][ghc/ghc] Pushed new tag ghc-9.10.1-alpha3 Message-ID: <661d7b489d27e_3aba19eee4f412167c@gitlab.mail> Ben Gamari pushed new tag ghc-9.10.1-alpha3 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/ghc-9.10.1-alpha3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 19:17:28 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Mon, 15 Apr 2024 15:17:28 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] 2 commits: EPA: Fix comments in mkListSyntaxTy0 Message-ID: <661d7d487afff_3aba1911184641473b2@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 62235c07 by Alan Zimmerman at 2024-04-15T19:52:13+01:00 EPA: Fix comments in mkListSyntaxTy0 - - - - - 86062534 by Alan Zimmerman at 2024-04-15T20:13:45+01:00 EPA: Provide correct span for PatBind And remove unused paramater in checkPatBind - - - - - 7 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/printer/AnnotationNoListTuplePuns.hs Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1323,7 +1323,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1334,12 +1334,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1377,15 +1377,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1394,8 +1393,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3318,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3363,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ced4814d9a5039f35c533dac02060621e43432ab...86062534289a04184bdd6768dc0c5031713873cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ced4814d9a5039f35c533dac02060621e43432ab...86062534289a04184bdd6768dc0c5031713873cf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 19:20:28 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 15:20:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24659 Message-ID: <661d7dfc8c26_3aba1911b6ad8149420@gitlab.mail> Ben Gamari pushed new branch wip/T24659 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24659 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 19:30:57 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 15 Apr 2024 15:30:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.10 Message-ID: <661d8071807de_29b158f3d18641bd@gitlab.mail> Ben Gamari pushed new branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.10 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 21:32:18 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Mon, 15 Apr 2024 17:32:18 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] 2 commits: EPA: Fix span for PatBuilderAppType Message-ID: <661d9ce2912ef_29b158f948a410476f@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: fe3321b8 by Alan Zimmerman at 2024-04-15T22:06:44+01:00 EPA: Fix span for PatBuilderAppType Note: tests still need to be updated - - - - - 1eb1a5ae by Alan Zimmerman at 2024-04-15T22:31:39+01:00 EPA: Avoid duplicated comments in splice decls - - - - - 3 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -589,7 +589,7 @@ mkHsAppTys = foldl' mkHsAppTy mkHsAppKindTy :: XAppKindTy (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -mkHsAppKindTy x ty k = addCLocA ty k (HsAppKindTy x ty k) +mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) {- ************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -3401,7 +3401,7 @@ bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parse argpat :: { LPat GhcPs } argpat : apat { $1 } - | PREFIX_AT atype { L (getLocAnn (reLoc $2)) (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } + | PREFIX_AT atype { sLLa $1 $> (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } argpats :: { [LPat GhcPs] } : argpat argpats { $1 : $2 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -398,17 +398,14 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan @@ -1458,7 +1455,7 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L loc _)))) es ops cps + go (L loc (PatBuilderAppType pat tok ty_pat@(HsTP _ (L _loc _)))) es ops cps = go pat (L loc (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat go _ _ _ _ = return Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86062534289a04184bdd6768dc0c5031713873cf...1eb1a5ae98ab32439870867dfd39d38b64bd6a6d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86062534289a04184bdd6768dc0c5031713873cf...1eb1a5ae98ab32439870867dfd39d38b64bd6a6d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 22:01:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 15 Apr 2024 18:01:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <661da3d0bee19_29b15813b87641063d9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - ff4c7f66 by Andreas Klebinger at 2024-04-15T18:01:41-04:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - 92f89c53 by Andreas Klebinger at 2024-04-15T18:01:41-04:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 63f6c80b by Andreas Klebinger at 2024-04-15T18:01:42-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - ce582e7b by Ben Gamari at 2024-04-15T18:01:43-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 7c6f618b by Alan Zimmerman at 2024-04-15T18:01:43-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 1c265236 by Ben Gamari at 2024-04-15T18:01:44-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 9ca1666c by Teo Camarasu at 2024-04-15T18:01:44-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - 30 changed files: - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - docs/index.html.in - hadrian/src/Rules/Generate.hs - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - rts/posix/ticker/TimerFd.c - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - testsuite/tests/ghc-api/exactprint/T22919.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4695dc112984cd5b7ebfc6a3e30759e64264b4b0...9ca1666ccc8383a101d7ef5a703e142431043ac9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4695dc112984cd5b7ebfc6a3e30759e64264b4b0...9ca1666ccc8383a101d7ef5a703e142431043ac9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 15 22:30:38 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Mon, 15 Apr 2024 18:30:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-list-syntax Message-ID: <661daa8ef028b_29b15818bceb81199f6@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-list-syntax at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-list-syntax You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 05:43:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 01:43:00 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: STM: Remove (unused)coarse grained locking. Message-ID: <661e0fe4473b1_29b15849f7b54161079@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c98ddc51 by Andreas Klebinger at 2024-04-16T01:42:45-04:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - 0faf91c7 by Andreas Klebinger at 2024-04-16T01:42:45-04:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 078640bc by Simon Peyton Jones at 2024-04-16T01:42:46-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - b7d7618c by Andreas Klebinger at 2024-04-16T01:42:47-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - d630b376 by Ben Gamari at 2024-04-16T01:42:48-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - fa944f4b by Alan Zimmerman at 2024-04-16T01:42:48-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - dfe21ae0 by Ben Gamari at 2024-04-16T01:42:49-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - bd9ce3f0 by Teo Camarasu at 2024-04-16T01:42:49-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - bc321693 by Ben Gamari at 2024-04-16T01:42:50-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 30 changed files: - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - docs/index.html.in - hadrian/src/Rules/Generate.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - rts/posix/ticker/TimerFd.c - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ca1666ccc8383a101d7ef5a703e142431043ac9...bc3216933cc69026fa54ab86d8b573d43a49e855 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ca1666ccc8383a101d7ef5a703e142431043ac9...bc3216933cc69026fa54ab86d8b573d43a49e855 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 06:26:42 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 16 Apr 2024 02:26:42 -0400 Subject: [Git][ghc/ghc] Pushed new tag ghc-9.6.5-release Message-ID: <661e1a22bebc2_29b158529e2bc2453e5@gitlab.mail> Zubin pushed new tag ghc-9.6.5-release at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/ghc-9.6.5-release You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 06:46:48 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Tue, 16 Apr 2024 02:46:48 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] 23 commits: Prefer packed representation for CompiledByteCode Message-ID: <661e1ed83712d_6dd062c895428366@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 3a835a3c by Mikolaj Konarski at 2024-04-16T08:45:53+02:00 Add DCoVarSet to PluginProv (!12037) - - - - - 30 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/FlatBag.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df626244ff1c081da196adce80f2393008985301...3a835a3c6a5afce8aca4e29e51f884fbd2739a9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df626244ff1c081da196adce80f2393008985301...3a835a3c6a5afce8aca4e29e51f884fbd2739a9a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 08:26:41 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 04:26:41 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <661e364123455_6dd06e837f8621c2@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 7da63315 by Fendor at 2024-04-16T10:26:06+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesRecomp T21839c ------------------------- - - - - - 0e348bee by Fendor at 2024-04-16T10:26:06+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +233,37 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +275,200 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: + +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisitation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions: + + * The real serialiser that serialises the original value: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +477,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +498,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +522,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +547,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +566,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,12 +103,14 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +122,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +139,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1366,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1400,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1447,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/026372f78d3a762a46e7135d869092062e7c3b20...0e348bee506f2de762b552ab9cdf0102f27d9814 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/026372f78d3a762a46e7135d869092062e7c3b20...0e348bee506f2de762b552ab9cdf0102f27d9814 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 08:43:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 04:43:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Make template-haskell a stage1 package Message-ID: <661e3a4c11f52_6dd0612b242884170@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2a84ef87 by Teo Camarasu at 2024-04-16T04:43:22-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - c46c2308 by Simon Peyton Jones at 2024-04-16T04:43:22-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 90edde96 by Andreas Klebinger at 2024-04-16T04:43:23-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - e75b4576 by Ben Gamari at 2024-04-16T04:43:24-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 8f16f14a by Alan Zimmerman at 2024-04-16T04:43:24-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 98bcd9fe by Bryan Richter at 2024-04-16T04:43:25-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 41580e80 by Ben Gamari at 2024-04-16T04:43:25-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 0d278131 by Teo Camarasu at 2024-04-16T04:43:26-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - 5697df2b by Ben Gamari at 2024-04-16T04:43:26-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - ef7d0dee by Alan Zimmerman at 2024-04-16T04:43:26-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 30 changed files: - .gitignore - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - docs/index.html.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libffi-tarballs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bc3216933cc69026fa54ab86d8b573d43a49e855...ef7d0deeb069669669403dd44639b420893663dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bc3216933cc69026fa54ab86d8b573d43a49e855...ef7d0deeb069669669403dd44639b420893663dd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 08:49:38 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 04:49:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/lazier-corebindings Message-ID: <661e3ba2b8775_6dd06141cdcc996b3@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/lazier-corebindings You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 09:33:58 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Tue, 16 Apr 2024 05:33:58 -0400 Subject: [Git][ghc/ghc][wip/T23536-teo] Make template-haskell a stage1 package Message-ID: <661e4606951ae_16d9b14e1fc443165@gitlab.mail> Teo Camarasu pushed to branch wip/T23536-teo at Glasgow Haskell Compiler / GHC Commits: ef81526f by Teo Camarasu at 2024-04-16T10:33:39+01:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,116 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to +-- convert TH ASTs returned by splices into the Hs AST, both of which do not +-- depend on the fully qualified name of the type to serialise! Importantly, +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] is +-- unaffected, because the desugaring refers to names in the in-tree TH +-- library, which is built in the next stage, stage1, and later. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a +-- single version of template-haskell. +-- (Beyond the fact that doing otherwise would invite even +-- more "which `template-haskell` is this" confusion, it +-- would also result in confusing linker errors: see for +-- example #21981. In principle we could likely lift this +-- restriction with more aggressive name mangling, but the +-- knock-on effects of doing so are unexplored.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +160,7 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell + , templateHaskellNext , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.* + else + build-depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) -import Data.Int +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word -import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) import Data.Array.Byte (ByteArray(..)) +import Data.Char (ord) +import Data.Int +import Data.Ratio +import Data.Void ( Void, absurd ) +import GHC.CString ( unpackCString# ) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.ST (ST(..), runST) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import Numeric.Natural +import qualified Data.Fixed as Fixed +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from ../template-haskell/template-haskell.cabal.in by -- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef81526fbe6d8b86d7de068b486eb782853d853c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef81526fbe6d8b86d7de068b486eb782853d853c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 10:19:39 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 06:19:39 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 7 commits: Refactor the Binary serialisation interface Message-ID: <661e50bb7fe89_16d9b1a83590552c5@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 7da63315 by Fendor at 2024-04-16T10:26:06+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesRecomp T21839c ------------------------- - - - - - 0e348bee by Fendor at 2024-04-16T10:26:06+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - b7a178ed by Fendor at 2024-04-16T12:00:59+02:00 Add Eq and Ord instance to IfaceType Bump haddock submodule for IfLclName changes - - - - - a15e73b3 by Fendor at 2024-04-16T12:01:26+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 24d5bfd1 by Matthew Pickering at 2024-04-16T12:05:07+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 35256ec4 by Matthew Pickering at 2024-04-16T12:07:19+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 57f77a08 by Fendor at 2024-04-16T12:07:19+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/50f756f4a9c48c3bce6aac80d74e12311fc47261...57f77a08d347166fac16085e55bcf447ffd6ace0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/50f756f4a9c48c3bce6aac80d74e12311fc47261...57f77a08d347166fac16085e55bcf447ffd6ace0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 10:34:37 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 06:34:37 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <661e543d494d4_16d9b1c704c0555d8@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: a46734e8 by Fendor at 2024-04-16T12:33:49+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - 442649b4 by Fendor at 2024-04-16T12:33:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,43 +233,37 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } - - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do - - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count - - forwardPut bh_fs (const put_symtab) $ do - - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name - - put_payload bh_name - - return (name_count, fs_count, r) - - +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -273,11 +275,200 @@ binaryInterfaceMagic platform | otherwise = FixedLengthEncoding 0x1face64 +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. +When serialising a symbol, we lookup whether we have encountered the symbol before. +If yes, we write the index of the symbol, otherwise we generate a new index and store it in the table. + +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. + +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: + +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisitation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions: + + * The real serialiser that serialises the original value: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} + + -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +477,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +498,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +522,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +547,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +566,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData(..), getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData(..), getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,12 +103,14 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO @@ -104,11 +122,13 @@ import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) +import Data.Typeable import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) @@ -119,6 +139,9 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) +import Data.Coerce + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,197 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader TypeRep (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map TypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map TypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (typeRep (Proxy :: Proxy a)) cb + +mkSomeBinaryReader :: forall a . Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (typeRep (Proxy :: Proxy a)) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (typeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (typeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (typeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (typeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + , mkReaderFromTable :: SymbolTable a -> BinaryReader a } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +data WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1366,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1400,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1447,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e348bee506f2de762b552ab9cdf0102f27d9814...442649b4850b72557dff661089cf5c26bdc5a6fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e348bee506f2de762b552ab9cdf0102f27d9814...442649b4850b72557dff661089cf5c26bdc5a6fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 11:14:37 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 07:14:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Clone CoVars in CorePrep Message-ID: <661e5d9d40a4e_16d9b113cccdc8840@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ab222f6d by Simon Peyton Jones at 2024-04-16T07:13:57-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 91a10d77 by Andreas Klebinger at 2024-04-16T07:13:58-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - c25246a6 by Ben Gamari at 2024-04-16T07:13:59-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - ee95757d by Alan Zimmerman at 2024-04-16T07:13:59-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - dd1d3481 by Bryan Richter at 2024-04-16T07:14:00-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - e421d4e3 by Ben Gamari at 2024-04-16T07:14:00-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 6e2afa75 by Teo Camarasu at 2024-04-16T07:14:00-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - 722647eb by Ben Gamari at 2024-04-16T07:14:01-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 58f6f763 by Alan Zimmerman at 2024-04-16T07:14:01-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 30 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - docs/index.html.in - hadrian/src/Rules/Generate.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - rts/posix/ticker/TimerFd.c - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef7d0deeb069669669403dd44639b420893663dd...58f6f763a603195093f097d115d2b6b8302e2ddd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef7d0deeb069669669403dd44639b420893663dd...58f6f763a603195093f097d115d2b6b8302e2ddd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 12:17:24 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 08:17:24 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 4 commits: Add deduplication table for `IfaceType` Message-ID: <661e6c53f3b0c_16d9b11d9d84c121096@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: fc204644 by Fendor at 2024-04-16T14:16:54+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 3116d68b by Matthew Pickering at 2024-04-16T14:16:54+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - ef207f0e by Matthew Pickering at 2024-04-16T14:16:54+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 0823ceae by Fendor at 2024-04-16T14:16:54+02:00 Implement TrieMap for IfaceType - - - - - 24 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -207,6 +207,7 @@ data DynFlags = DynFlags { dmdUnboxWidth :: !Int, -- ^ Whether DmdAnal should optimistically put an -- Unboxed demand on returned products with at most -- this number of fields + ifCompression :: Int, specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types @@ -546,6 +547,7 @@ defaultDynFlags mySettings = maxPmCheckModels = 30, simplTickFactor = 100, dmdUnboxWidth = 3, -- Default: Assume an unboxed demand on function bodies returning a triple + ifCompression = 2, -- Default: Apply safe compressions specConstrThreshold = Just 2000, specConstrCount = Just 3, specConstrRecursive = 3, ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -163,7 +163,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -612,7 +612,7 @@ extract_renamed_stuff mod_summary tc_result = do -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) let out_file = ml_hie_file $ ms_location mod_summary - liftIO $ writeHieFile out_file hieFile + liftIO $ writeHieFile (flagsToIfCompression dflags) out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files @@ -1207,7 +1207,7 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do withTiming logger (text "WriteIface"<+>brackets (text iface_name)) (const ()) - (writeIface logger profile iface_name iface) + (writeIface logger profile (flagsToIfCompression dflags) iface_name iface) if (write_interface || force_write_interface) then do ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1664,6 +1664,9 @@ dynamic_flags_deps = [ , make_ord_flag defFlag "fno-refinement-level-hole-fits" (noArg (\d -> d { refLevelHoleFits = Nothing })) + , make_ord_flag defFlag "fwrite-if-compression" + (intSuffix (\n d -> d { ifCompression = n })) + , make_dep_flag defGhcFlag "fllvm-pass-vectors-in-regs" (noArg id) "vectors registers are now passed in registers by default." ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -14,6 +14,7 @@ module GHC.Iface.Binary ( writeBinIface, readBinIface, readBinIfaceHeader, + CompressionIFace(..), getSymtabName, CheckHiWay(..), TraceBinIFace(..), @@ -25,6 +26,8 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude @@ -46,14 +49,19 @@ import GHC.Types.SrcLoc import GHC.Platform import GHC.Settings.Constants import GHC.Utils.Fingerprint +import GHC.Iface.Type (IfaceType(..), getIfaceType, putIfaceType, ifaceTypeSharedByte) +import Control.Monad import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.Char -import Data.Word import Data.IORef -import Control.Monad +import Data.Map.Strict (Map) +import Data.Word +import System.IO.Unsafe +import Data.Typeable (Typeable) + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -66,6 +74,21 @@ data TraceBinIFace = TraceBinIFace (SDoc -> IO ()) | QuietBinIFace +data CompressionIFace + = NormalCompression + -- ^ Perform the normal compression operations, + -- such as deduplicating 'Name's and 'FastString's + | SafeExtraCompression + -- ^ Perform some extra compression steps that have minimal impact + -- on the run-time of 'ghc'. + -- + -- This reduces the size of '.hi' files significantly in some cases + -- and reduces overall memory usage in certain scenarios. + | MaximalCompression + -- ^ Try to compress as much as possible. + -- + -- Yields the smallest '.hi' files but at the cost of additional run-time. + -- | Read an interface file header, checking the magic number, version, and -- way. Returns the hash of the source file and a BinHandle which points at the -- start of the rest of the interface file data. @@ -158,30 +181,42 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable nameReaderTable <- initNameReaderTable name_cache - - - -- The order of these deserialisation matters! - -- - -- See Note [Order of deduplication tables during iface binary serialisation] for details. - fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) - let - fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - - nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) - let - nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - - pure bhName + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + + let -- For any 'ReaderTable', we decode the table that is found at the location + -- the forward reference points to. + -- After decoding the table, we create a 'BinaryReader' and immediately + -- add it to the 'ReaderUserData' of 'ReadBinHandle'. + decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle + decodeReaderTable tbl bh0 = do + table <- Binary.forwardGet bh (getTable tbl bh0) + let binaryReader = mkReaderFromTable tbl table + pure $ addReaderToUserData binaryReader bh0 + + -- Decode all the tables and populate the 'ReaderUserData'. + bhFinal <- foldM (\bh0 act -> act bh0) bh + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + [ decodeReaderTable fsReaderTable + , decodeReaderTable nameReaderTable + , decodeReaderTable ifaceTypeReaderTable + ] + + writeIORef bhRef (getReaderUserData bhFinal) + pure bhFinal -- | Write an interface file. -- -- See Note [Deduplication during iface binary serialisation] for details. -writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () -writeBinIface profile traceBinIface hi_path mod_iface = do +writeBinIface :: Profile -> TraceBinIFace -> CompressionIFace -> FilePath -> ModIface -> IO () +writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do bh <- openBinMem initBinMemSize let platform = profilePlatform profile put_ bh (binaryInterfaceMagic platform) @@ -195,7 +230,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p - putWithUserData traceBinIface bh mod_iface + putWithUserData traceBinIface compressionLevel bh mod_iface extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p @@ -209,9 +244,9 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () -putWithUserData traceBinIface bh payload = do - (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) +putWithUserData :: Binary a => TraceBinIFace -> CompressionIFace -> WriteBinHandle -> a -> IO () +putWithUserData traceBinIface compressionLevel bh payload = do + (name_count, fs_count, _b) <- putWithTables compressionLevel bh (\bh' -> put bh' payload) case traceBinIface of QuietBinIFace -> return () @@ -234,17 +269,19 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Order of deduplication tables during iface binary serialisation] -putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) -putWithTables bh' put_payload = do +putWithTables :: CompressionIFace -> WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables compressionLevel bh' put_payload = do -- Initialise deduplicating tables. (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initNameWriterTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel -- Initialise the 'WriterUserData'. let writerUserData = mkWriterUserData [ mkSomeBinaryWriter @FastString fsWriter , mkSomeBinaryWriter @Name nameWriter , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -252,18 +289,24 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Order of deduplication tables during iface binary serialisation] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) - where - putAllTables _ [] act = do - a <- act - pure ([], a) - putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do - putAllTables bh xs act - pure (r : res, a) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -429,6 +472,42 @@ Here, a visualisation of the table structure we currently have (ignoring 'Extens -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: CompressionIFace -> IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType compressionLevel = do + sym_tab <- initGenericSymbolTable @(Map IfaceType) + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ ifaceWriter sym_tab + ) + where + ifaceWriter sym_tab = case compressionLevel of + NormalCompression -> literalIfaceTypeSerialiser + SafeExtraCompression -> ifaceTyConAppSerialiser sym_tab + MaximalCompression -> fullIfaceTypeSerialiser sym_tab + + ifaceTyConAppSerialiser sym_tab bh ty = case ty of + IfaceTyConApp {} -> do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + _ -> putIfaceType bh ty + + + fullIfaceTypeSerialiser sym_tab bh ty = do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + + literalIfaceTypeSerialiser = putIfaceType + initNameReaderTable :: NameCache -> IO (ReaderTable Name) initNameReaderTable cache = do ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable, CompressionIFace) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -74,8 +73,8 @@ putBinLine bh xs = do -- | Write a `HieFile` to the given `FilePath`, with a proper header and -- symbol tables for `Name`s and `FastString`s -writeHieFile :: FilePath -> HieFile -> IO () -writeHieFile hie_file_path hiefile = do +writeHieFile :: CompressionIFace -> FilePath -> HieFile -> IO () +writeHieFile compression hie_file_path hiefile = do bh0 <- openBinMem initBinMemSize -- Write the header: hieHeader followed by the @@ -84,58 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBinWriter bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType compression - -- remember where the symbol table pointer will go - symtab_p_p <- tellBinWriter bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBinWriter bh - putAt bh symtab_p_p symtab_p - seekBinWriter bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBinWriter bh - putAt bh dict_p_p dict_p - seekBinWriter bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Order of deduplication tables during iface binary serialisation] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -216,50 +215,32 @@ readHieFileHeader file bh0 = do readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBinReader bin_handle - seekBinReader bin_handle dict_p - dict <- getDictionary bin_handle - seekBinReader bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBinReader bh1 - seekBinReader bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBinReader bh1 data_p' - return symtab - -putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Iface.Load ( loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, findAndReadIface, readIface, writeIface, + flagsToIfCompression, moduleFreeHolesPrecise, needWiredInHomeIface, loadWiredInHomeIface, @@ -965,11 +966,18 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do -- | Write interface file -writeIface :: Logger -> Profile -> FilePath -> ModIface -> IO () -writeIface logger profile hi_file_path new_iface +writeIface :: Logger -> Profile -> CompressionIFace -> FilePath -> ModIface -> IO () +writeIface logger profile compression_level hi_file_path new_iface = do createDirectoryIfMissing True (takeDirectory hi_file_path) let printer = TraceBinIFace (debugTraceMsg logger 3) - writeBinIface profile printer hi_file_path new_iface + writeBinIface profile printer compression_level hi_file_path new_iface + +flagsToIfCompression :: DynFlags -> CompressionIFace +flagsToIfCompression dflags = case ifCompression dflags of + 0 -> NormalCompression + 1 -> NormalCompression + 2 -> SafeExtraCompression + _ -> MaximalCompression -- | @readIface@ tries just the one file. -- ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -33,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, ifaceTypeSharedByte, -- Equality testing isIfaceLiftedTypeKind, @@ -90,11 +92,13 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) +import Data.Maybe (isJust) +import Data.Proxy +import qualified Data.Semigroup as Semi +import Data.Word (Word8) +import Control.Arrow (first) import Control.DeepSeq import Control.Monad ((<$!>)) -import Control.Arrow (first) -import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) {- ************************************************************************ @@ -109,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName @@ -2191,38 +2199,70 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + put_ bh ty = + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ty - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } + get bh = getIfaceTypeShared bh - get bh = do +-- | This is the byte tag we expect to read when the next +-- value is not an 'IfaceType' value, but an offset into a +-- lookup value. +-- +-- Must not overlap with any byte tag in 'getIfaceType'. +ifaceTypeSharedByte :: Word8 +ifaceTypeSharedByte = 99 + +-- | Like 'getIfaceType' but checks for a specific byte tag +-- that indicates that we won't be able to read a 'IfaceType' value +-- but rather an offset into a lookup table. Consequentially, +-- we look up the value for the 'IfaceType' in the look up table. +-- +-- See Note [Deduplication during iface binary serialisation] +-- for details. +getIfaceTypeShared :: ReadBinHandle -> IO IfaceType +getIfaceTypeShared bh = do + start <- tellBinReader bh + tag <- getByte bh + if ifaceTypeSharedByte == tag + then case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + else seekBinReader bh start >> getIfaceType bh + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -141,6 +150,9 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import Data.Coerce +import GHC.Data.TrieMap + + type BinArray = ForeignPtr Word8 @@ -230,22 +242,26 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) { ud_reader_data = Map.insert typRep cache (ud_reader_data (rbm_userData bh)) } } + where + cache@(SomeBinaryReader typRep _) = mkSomeBinaryReader reader -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) { ud_writer_data = Map.insert typRep cache (ud_writer_data (wbm_userData bh)) } } + where + cache@(SomeBinaryWriter typRep _) = mkSomeBinaryWriter writer -- | Get access to the underlying buffer. withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a @@ -1102,24 +1118,35 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' Nothing (\_ -> get) + +lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' mbh f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh + -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. + let !get_inner_bh = maybe (pure bh) readIORef mbh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. + inner_bh <- get_inner_bh off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = inner_bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f p bh' seekBinReader bh p -- skip over the object for now return a @@ -1173,6 +1200,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter TypeRep (BinaryWriter a) @@ -1313,6 +1346,113 @@ data WriterTable = WriterTable { putTable :: WriteBinHandle -> IO Int } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +-- | The 'GenericSymbolTable' stores a mapping from already seen elements to an index. +-- If an element wasn't seen before, it is added to the mapping together with a fresh +-- index. +-- +-- 'GenericSymbolTable' is a variant of a 'BinSymbolTable' that is polymorphic in the table implementation. +-- As such it can be used with any container that implements the 'TrieMap' type class. +-- +-- While 'GenericSymbolTable' is similar to the 'BinSymbolTable', it supports storing tree-like +-- structures such as 'Type' and 'IfaceType' more efficiently. +-- +data GenericSymbolTable m = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use. + , gen_symtab_map :: !(IORef (m Int)) + -- ^ Given a symbol, find the symbol and return its index. + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer. + -- This is an optimisation, as it allows us to write out quickly all + -- newly discovered values that are discovered when serialising 'Key m' + -- to disk. + } + +-- | Initialise a 'GenericSymbolTable', initialising the index to '0'. +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo + } + +-- | Serialise the 'GenericSymbolTable' to disk. +-- +-- Since 'GenericSymbolTable' stores tree-like structures, such as 'IfaceType', +-- serialising an element can add new elements to the mapping. +-- Thus, 'putGenericSymbolTable' first serialises all values, and then checks whether any +-- new elements have been discovered. If so, repeat the loop. +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab + putGenericSymbolTable :: WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) + case vs of + [] -> readFastMutInt symtab_next + todo -> do + mapM_ (\n -> serialiser bh n) (reverse todo) + loop + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop) + +-- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure + -- (6 arguments-ish). + forM_ [0..(sz-1)] $ \i -> do + f <- lazyGet' Nothing (\_ -> deserialiser) bh + -- f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +-- | Write an element 'Key m' to the given 'WriteBinHandle'. +-- +-- If the element was seen before, we simply write the index of that element to the +-- 'WriteBinHandle'. If we haven't seen it before, we add the element to +-- the 'GenericSymbolTable', increment the index, and return this new index. +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () +{-# INLINE putGenericSymTab #-} +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } + bh val = do + symtab_map <- readIORef symtab_map_ref + case lookupTM val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) + put_ bh (fromIntegral off :: Word32) + +-- | Read a value from a 'SymbolTable'. +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1777,3 +1777,12 @@ as such you shouldn't need to set any of them explicitly. A flag This flag sets the size (in bytes) threshold above which the second approach is used. You can disable the second approach entirely by setting the threshold to 0. + +.. ghc-flag:: -fwrite-if-compression=⟨n⟩ + :shortdesc: *default: 2.* Tweak the level of interface file compression. + :type: dynamic + :category: optimization + + :default: 2 + + TODO ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkInvisFunTy` wordTy `mkInvisFunTy` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkInvisFunTy` funTy `mkInvisFunTy` funTy `mkInvisFunTy` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/57f77a08d347166fac16085e55bcf447ffd6ace0...0823ceaec1f590e127d84ee51a57f300f18d50dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/57f77a08d347166fac16085e55bcf447ffd6ace0...0823ceaec1f590e127d84ee51a57f300f18d50dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 12:50:52 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Tue, 16 Apr 2024 08:50:52 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] Add DCoVarSet to PluginProv (!12037) Message-ID: <661e742c4d138_16d9b1225c7e814599b@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: e29277ca by Mikolaj Konarski at 2024-04-16T14:50:23+02:00 Add DCoVarSet to PluginProv (!12037) - - - - - 28 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/RepType.hs - compiler/GHC/Types/TyThing/Ppr.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Var/Set.hs - compiler/GHC/Utils/FV.hs - docs/users_guide/9.12.1-notes.rst - docs/users_guide/extending_ghc.rst - testsuite/tests/pmcheck/should_compile/T11195.hs - testsuite/tests/tcplugins/CtIdPlugin.hs - testsuite/tests/tcplugins/RewritePlugin.hs - testsuite/tests/tcplugins/TyFamPlugin.hs Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -97,7 +97,7 @@ module GHC.Core.Coercion ( emptyLiftingContext, extendLiftingContext, extendLiftingContextAndInScope, liftCoSubstVarBndrUsing, isMappedByLC, extendLiftingContextCvSubst, - mkSubstLiftingContext, zapLiftingContext, + mkSubstLiftingContext, liftingContextSubst, zapLiftingContext, substForAllCoBndrUsingLC, lcLookupCoVar, lcInScopeSet, LiftCoEnv, LiftingContext(..), liftEnvSubstLeft, liftEnvSubstRight, @@ -1456,9 +1456,9 @@ setNominalRole_maybe r co setNominalRole_maybe_helper (InstCo co arg) = InstCo <$> setNominalRole_maybe_helper co <*> pure arg setNominalRole_maybe_helper (UnivCo prov _ co1 co2) - | case prov of PhantomProv _ -> False -- should always be phantom - ProofIrrelProv _ -> True -- it's always safe - PluginProv _ -> False -- who knows? This choice is conservative. + | case prov of PhantomProv {} -> False -- should always be phantom + ProofIrrelProv {} -> True -- it's always safe + PluginProv {} -> False -- who knows? This choice is conservative. = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1583,7 +1583,7 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco - UnivCo (PluginProv _) _ _ _ -> mkKindCo co + UnivCo (PluginProv _ _) _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2040,6 +2040,9 @@ mkLiftingContext pairs mkSubstLiftingContext :: Subst -> LiftingContext mkSubstLiftingContext subst = LC subst emptyVarEnv +liftingContextSubst :: LiftingContext -> Subst +liftingContextSubst (LC subst _) = subst + -- | Extend a lifting context with a new mapping. extendLiftingContext :: LiftingContext -- ^ original LC -> TyCoVar -- ^ new variable to map... @@ -2415,7 +2418,7 @@ seqCo (AxiomRuleCo _ cs) = seqCos cs seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co -seqProv (PluginProv _) = () +seqProv (PluginProv _ cvs) = seqDVarSet cvs seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -636,7 +636,7 @@ opt_univ env sym prov role oty1 oty2 where prov' = case prov of ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco - PluginProv _ -> prov + PluginProv s cvs -> PluginProv s $ substDCoVarSet (liftingContextSubst env) cvs ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] @@ -734,7 +734,8 @@ opt_trans_rule is in_co1@(UnivCo p1 r1 tyl1 _tyr1) = Just $ PhantomProv $ opt_trans is kco1 kco2 opt_trans_prov (ProofIrrelProv kco1) (ProofIrrelProv kco2) = Just $ ProofIrrelProv $ opt_trans is kco1 kco2 - opt_trans_prov (PluginProv str1) (PluginProv str2) | str1 == str2 = Just p1 + opt_trans_prov (PluginProv str1 cvs1) (PluginProv str2 cvs2) + | str1 == str2 = Just (PluginProv str1 (cvs1 `unionDVarSet` cvs2)) opt_trans_prov _ _ = Nothing -- Push transitivity down through matching top-level constructors. ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,7 @@ orphNamesOfCo (HoleCo _) = emptyNameSet orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co -orphNamesOfProv (PluginProv _) = emptyNameSet +orphNamesOfProv (PluginProv _ _) = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -1931,6 +1931,13 @@ checkTyCon :: TyCon -> LintM () checkTyCon tc = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc) +------------------- +checkTyCoVarInScope :: Subst -> TyCoVar -> LintM () +checkTyCoVarInScope subst tcv + = checkL (tcv `isInScope` subst) $ + hang (text "The type or coercion variable" <+> pprBndr LetBind tcv) + 2 (text "is out of scope") + ------------------- lintType :: Type -> LintM LintedType @@ -1948,12 +1955,8 @@ lintType (TyVarTy tv) -- In GHCi we may lint an expression with a free -- type variable. Then it won't be in the -- substitution, but it should be in scope - Nothing | tv `isInScope` subst - -> return (TyVarTy tv) - | otherwise - -> failWithL $ - hang (text "The type variable" <+> pprBndr LetBind tv) - 2 (text "is out of scope") + Nothing -> do { checkTyCoVarInScope subst tv + ; return (TyVarTy tv) } } lintType ty@(AppTy t1 t2) @@ -2325,15 +2328,8 @@ lintCoercion (CoVarCo cv) = do { subst <- getSubst ; case lookupCoVar subst cv of Just linted_co -> return linted_co ; - Nothing - | cv `isInScope` subst - -> return (CoVarCo cv) - | otherwise - -> - -- lintCoBndr always extends the substitution - failWithL $ - hang (text "The coercion variable" <+> pprBndr LetBind cv) - 2 (text "is out of scope") + Nothing -> do { checkTyCoVarInScope subst cv + ; return (CoVarCo cv) } } @@ -2532,7 +2528,12 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov + lint_prov _ _ (PluginProv s cvs) + = do { subst <- getSubst + ; mapM_ (checkTyCoVarInScope subst) (dVarSetElems cvs) + -- Don't bother to return substituted fvs; + -- they don't matter to Lint + ; return (PluginProv s cvs) } check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -19,6 +19,7 @@ module GHC.Core.TyCo.FVs tyCoVarsOfCoDSet, tyCoFVsOfCo, tyCoFVsOfCos, tyCoVarsOfCoList, + coVarsOfCosDSet, almostDevoidCoVarOfCo, @@ -446,6 +447,13 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView -- See Note [CoercionHoles and coercion free variables] -- in GHC.Core.TyCo.Rep +------- Same again, but for DCoVarSet ---------- +-- But this time the free vars are shallow + +coVarsOfCosDSet :: [Coercion] -> DCoVarSet +coVarsOfCosDSet cos = fvDVarSetSome isCoVar (tyCoFVsOfCos cos) + + {- ********************************************************************* * * Closing over kinds @@ -660,7 +668,8 @@ tyCoFVsOfCoVar v fv_cand in_scope acc tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc -tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc +tyCoFVsOfProv (PluginProv _ cvs) _ _ (have, haveSet) = + (dVarSetElems cvs ++ have, dVarSetToVarSet cvs `unionVarSet` haveSet) tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -730,7 +739,7 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _ cvs) cv = not (cv `elemDVarSet` cvs) almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1129,7 +1138,7 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co - go_prov (PluginProv _) = emptyUniqSet + go_prov (PluginProv _ _) = emptyUniqSet go_cos cos = foldr (unionUniqSets . go_co) emptyUniqSet cos @@ -1340,4 +1349,4 @@ occCheckExpand vs_to_avoid ty ------------------ go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co - go_prov _ p@(PluginProv _) = return p + go_prov _ p@(PluginProv _ _) = return p ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1,4 +1,3 @@ - {-# LANGUAGE DeriveDataTypeable #-} {-# OPTIONS_HADDOCK not-home #-} @@ -78,7 +77,7 @@ import {-# SOURCE #-} GHC.Core.Type( chooseFunTyFlag, typeKind, typeTypeOrConstr -- friends: import GHC.Types.Var -import GHC.Types.Var.Set( elemVarSet ) +import GHC.Types.Var.Set( DCoVarSet, dVarSetElems, elemVarSet ) import GHC.Core.TyCon import GHC.Core.Coercion.Axiom @@ -886,7 +885,7 @@ data Coercion | FunCo -- FunCo :: "e" -> N/P -> e -> e -> e -- See Note [FunCo] for fco_afl, fco_afr - { fco_role :: Role + { fco_role :: Role , fco_afl :: FunTyFlag -- Arrow for coercionLKind , fco_afr :: FunTyFlag -- Arrow for coercionRKind , fco_mult :: CoercionN @@ -1533,15 +1532,19 @@ data UnivCoProvenance -- considered equivalent. See Note [ProofIrrelProv]. -- Can be used in Nominal or Representational coercions - | PluginProv String -- ^ From a plugin, which asserts that this coercion - -- is sound. The string is for the use of the plugin. + | PluginProv String !DCoVarSet + -- ^ From a plugin, which asserts that this coercion is sound. + -- The string and the variable set are for the use by the plugin. + -- The set must contain all the in-scope coercion variables + -- that the the proof represented by the coercion makes use of. + -- See Note [The importance of tracking free coercion variables]. deriving Data.Data instance Outputable UnivCoProvenance where - ppr (PhantomProv _) = text "(phantom)" - ppr (ProofIrrelProv _) = text "(proof irrel.)" - ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) + ppr (PhantomProv _) = text "(phantom)" + ppr (ProofIrrelProv _) = text "(proof irrel.)" + ppr (PluginProv str cvs) = parens (text "plugin" <+> brackets (text str) <+> ppr cvs) -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1696,6 +1699,50 @@ Here, where co5 :: (a1 ~ Bool) ~ (a2 ~ Bool) co5 = TyConAppCo Nominal (~#) [<*>, <*>, co4, ] + + +Note [The importance of tracking free coercion variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is vital that `UnivCo` (a coercion that lacks a proper proof) +tracks its free coercion variables. To see why, consider this program: + + type S :: Nat -> Nat + + data T (a::Nat) where + T1 :: T 0 + T2 :: ... + + f :: T a -> S (a+1) -> S 1 + f = /\a (x:T a) (y:a). + case x of + T1 (gco : a ~# 0) -> y |> wco + +For this to typecheck we need `wco :: S (a+1) ~# S 1`, given that `gco : a ~# 0`. +To prove that we need to know that `a+1 = 1` if `a=0`, which a plugin might know. +So it solves `wco` by providing a `UnivCo (PluginProv "my-plugin" gcvs) (a+1) 1`. + + But the `gcvs` in `PluginProv` must mention `gco`. + +Why? Otherwise we might float the entire expression (y |> wco) out of the +the case alternative for `T1` which brings `gco` into scope. If this +happens then we aren't far from a segmentation fault or much worse. +See #23923 for a real-world example of this happening. + +So it is /crucial/ for the `PluginProv` to mention, in `gcvs`, the coercion +variables used by the plugin to justify the `UnivCo` that it builds. + +Note that we don't need to track +* the coercion's free *type* variables +* coercion variables free in kinds (we only need the "shallow" free covars) + +This means that we may float past type variables which the original +proof had as free variables. While surprising, this doesn't jeopardise +the validity of the coercion, which only depends upon the scoping +relative to the free coercion variables. + +(The free coercion variables are kept as a DCoVarSet in UnivCo, +since these sets are included in interface files.) + -} @@ -1755,7 +1802,6 @@ In particular, given | tv `elemVarSet` acc = acc | otherwise = acc `extendVarSet` tv - we want to end up with fvs ty = go emptyVarSet ty emptyVarSet where @@ -1785,6 +1831,38 @@ Here deep_fvs and deep_tcf are mutually recursive, unlike fvs and tcf. But, amazingly, we get good code here too. GHC is careful not to mark TyCoFolder data constructor for deep_tcf as a loop breaker, so the record selections still cancel. And eta expansion still happens too. + +Note [Use explicit recursion in foldTyCo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In foldTyCo you'll see things like: + go_tys _ [] = mempty + go_tys env (t:ts) = go_ty env t `mappend` go_tys env ts +where we use /explicit recursion/. You might wonder about using foldl instead: + go_tys env = foldl (\t acc -> go_ty env t `mappend` acc) mempty +Or maybe foldl', or foldr. + +But don't do that for two reasons (see #24591) + +* We sometimes instantiate `a` to (Endo VarSet). Remembering + newtype Endo a = Endo (a->a) + after inlining `foldTyCo` bodily, the explicit recursion looks like + go_tys _ [] = \acc -> acc + go_tys env (t:ts) = \acc -> go_ty env t (go_tys env ts acc) + The strictness analyser has no problem spotting that this function is + strict in `acc`, provided `go_ty` is. + + But in the foldl form that is /much/ less obvious, and the strictness + analyser fails utterly. Result: lots and lots of thunks get built. In + !12037, Mikolaj found that GHC allocated /six times/ as much heap + on test perf/compiler/T9198 as a result of this single problem! + +* Second, while I think that using `foldr` would be fine (simple experiments in + #24591 suggest as much), it builds a local loop (with env free) and I'm not 100% + confident it'll be lambda lifted in the end. It seems more direct just to write + the code we want. + + On the other hand in `go_cvs` we might hope that the `foldr` will fuse with the + `dVarSetElems` so I have used `foldr`. -} data TyCoFolder env a @@ -1823,12 +1901,11 @@ foldTyCo (TyCoFolder { tcf_view = view = let !env' = tycobinder env tv vis -- Avoid building a thunk here in go_ty env (varType tv) `mappend` go_ty env' inner - -- Explicit recursion because using foldr builds a local - -- loop (with env free) and I'm not confident it'll be - -- lambda lifted in the end + -- See Note [Use explicit recursion in foldTyCo] go_tys _ [] = mempty go_tys env (t:ts) = go_ty env t `mappend` go_tys env ts + -- See Note [Use explicit recursion in foldTyCo] go_cos _ [] = mempty go_cos env (c:cs) = go_co env c `mappend` go_cos env cs @@ -1862,7 +1939,11 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co - go_prov _ (PluginProv _) = mempty + go_prov _ (PluginProv _ cvs) = go_cvs env cvs + + -- See Note [Use explicit recursion in foldTyCo] + go_cvs env cvs = foldr (add_one env) mempty (dVarSetElems cvs) + add_one env cv acc = covar env cv `mappend` acc -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1928,7 +2009,7 @@ coercionSize (AxiomRuleCo _ cs) = 1 + sum (map coercionSize cs) provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co -provSize (PluginProv _) = 1 +provSize (PluginProv _ _) = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core.TyCo.Subst cloneTyVarBndr, cloneTyVarBndrs, substVarBndr, substVarBndrs, substTyVarBndr, substTyVarBndrs, - substCoVarBndr, + substCoVarBndr, substDCoVarSet, substTyVar, substTyVars, substTyVarToTyVar, substTyCoVars, substTyCoBndr, substForAllCoBndr, @@ -910,12 +910,18 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) - go_prov p@(PluginProv _) = p + go_prov (PluginProv s cvs) = PluginProv s $ substDCoVarSet subst cvs -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) = h { ch_co_var = updateVarType go_ty cv } +-- | Perform a substitution within a 'DVarSet' of free variables, +-- returning the shallow free coercion variables. +substDCoVarSet :: Subst -> DCoVarSet -> DCoVarSet +substDCoVarSet subst cvs = coVarsOfCosDSet $ map (substCoVar subst) $ + dVarSetElems cvs + substForAllCoBndr :: Subst -> TyCoVar -> KindCoercion -> (Subst, TyCoVar, Coercion) substForAllCoBndr subst ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -20,9 +20,11 @@ import GHC.Data.FastString import GHC.Core.TyCo.Rep import GHC.Core.TyCo.FVs (tyCoVarsOfTypesWellScoped, tyCoVarsOfTypeList) +import GHC.Data.Maybe (orElse) import GHC.Types.Name hiding (varName) import GHC.Types.Var import GHC.Types.Var.Env +import GHC.Types.Var.Set import GHC.Utils.Misc (strictMap) import Data.List (mapAccumL) @@ -233,9 +235,7 @@ tidyCo env@(_, subst) co -- the case above duplicates a bit of work in tidying h and the kind -- of tv. But the alternative is to use coercionKind, which seems worse. go (FunCo r afl afr w co1 co2) = ((FunCo r afl afr $! go w) $! go co1) $! go co2 - go (CoVarCo cv) = case lookupVarEnv subst cv of - Nothing -> CoVarCo cv - Just cv' -> CoVarCo cv' + go (CoVarCo cv) = CoVarCo $! go_cv cv go (HoleCo h) = HoleCo h go (AxiomInstCo con ind cos) = AxiomInstCo con ind $! strictMap go cos go (UnivCo p r t1 t2) = (((UnivCo $! (go_prov p)) $! r) $! @@ -249,9 +249,11 @@ tidyCo env@(_, subst) co go (SubCo co) = SubCo $! go co go (AxiomRuleCo ax cos) = AxiomRuleCo ax $ strictMap go cos + go_cv cv = lookupVarEnv subst cv `orElse` cv + go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co - go_prov p@(PluginProv _) = p + go_prov (PluginProv s cvs) = PluginProv s $ mapDVarSet go_cv cvs tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -580,7 +580,7 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) - go_prov _ p@(PluginProv _) = p + go_prov _ p@(PluginProv _ _) = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -912,7 +912,8 @@ mapTyCo mapper -> (go_ty (), go_tys (), go_co (), go_cos ()) {-# INLINE mapTyCoX #-} -- See Note [Specialising mappers] -mapTyCoX :: Monad m => TyCoMapper env m +mapTyCoX :: forall m env. Monad m + => TyCoMapper env m -> ( env -> Type -> m Type , env -> [Type] -> m [Type] , env -> Coercion -> m Coercion @@ -924,6 +925,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar , tcm_hole = cohole }) = (go_ty, go_tys, go_co, go_cos) where + -- See Note [Use explicit recursion in mapTyCo] go_tys !_ [] = return [] go_tys !env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys @@ -954,12 +956,14 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar ; inner' <- go_ty env' inner ; return $ ForAllTy (Bndr tv' vis) inner' } + -- See Note [Use explicit recursion in mapTyCo] go_cos !_ [] = return [] go_cos !env (co:cos) = (:) <$> go_co env co <*> go_cos env cos go_mco !_ MRefl = return MRefl go_mco !env (MCo co) = MCo <$> (go_co env co) + go_co :: env -> Coercion -> m Coercion go_co !env (Refl ty) = Refl <$> go_ty env ty go_co !env (GRefl r ty mco) = mkGReflCo r <$> go_ty env ty <*> go_mco env mco go_co !env (AppCo c1 c2) = mkAppCo <$> go_co env c1 <*> go_co env c2 @@ -999,8 +1003,28 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov !env (PhantomProv co) = PhantomProv <$> go_co env co go_prov !env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co - go_prov !_ p@(PluginProv _) = return p - + go_prov !env (PluginProv s cvs) = PluginProv s <$> go_fcvs env (dVarSetElems cvs) + + -- See Note [Use explicit recursion in mapTyCo] + go_fcvs :: env -> [CoVar] -> m DTyCoVarSet + go_fcvs _ [] = return emptyDVarSet + go_fcvs env (cv:cvs) = do { co <- covar env cv + ; cvs' <- go_fcvs env cvs + ; return (tyCoVarsOfCoDSet co `unionDVarSet` cvs') } + +{- Note [Use explicit recursion in mapTyCo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We use explicit recursion in `mapTyCo`, rather than calling, say, `strictFoldDVarSet`, +for exactly the same reason as in Note [Use explicit recursion in foldTyCo] in +GHC.Core.TyCo.Rep. We are in a monadic context, and using too-clever higher order +functions makes the strictness analyser produce worse results. + +We could probably use `foldr`, since it is inlined bodily, fairly early; but +I'm doing the simple thing and inlining it by hand. + +See !12037 for performance glitches caused by using `strictFoldDVarSet` (which is +definitely not inlined bodily). +-} {- ********************************************************************* * * ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -88,6 +88,7 @@ import GHC.Utils.Panic import GHC.Utils.Misc import Data.Maybe ( isNothing, catMaybes ) +import Data.List ( partition ) {- Note [Avoiding space leaks in toIface*] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -176,7 +177,7 @@ toIfaceTypeX :: VarSet -> Type -> IfaceType -- translates the tyvars in 'free' as IfaceFreeTyVars -- -- Synonyms are retained in the interface type -toIfaceTypeX fr (TyVarTy tv) -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type +toIfaceTypeX fr (TyVarTy tv) -- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type | tv `elemVarSet` fr = IfaceFreeTyVar tv | otherwise = IfaceTyVar (toIfaceTyVar tv) toIfaceTypeX fr ty@(AppTy {}) = @@ -283,7 +284,7 @@ toIfaceCoercionX fr co go (Refl ty) = IfaceReflCo (toIfaceTypeX fr ty) go (GRefl r ty mco) = IfaceGReflCo r (toIfaceTypeX fr ty) (go_mco mco) go (CoVarCo cv) - -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type + -- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type | cv `elemVarSet` fr = IfaceFreeCoVar cv | otherwise = IfaceCoVarCo (toIfaceCoVar cv) go (HoleCo h) = IfaceHoleCo (coHoleCoVar h) @@ -318,9 +319,11 @@ toIfaceCoercionX fr co fr' = fr `delVarSet` tv go_prov :: UnivCoProvenance -> IfaceUnivCoProv - go_prov (PhantomProv co) = IfacePhantomProv (go co) - go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) - go_prov (PluginProv str) = IfacePluginProv str + go_prov (PhantomProv co) = IfacePhantomProv (go co) + go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) + go_prov (PluginProv str cvs) = IfacePluginProv str (map toIfaceCoVar bound_cvs) free_cvs + where + (free_cvs, bound_cvs) = partition (`elemVarSet` fr) (dVarSetElems cvs) toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/Iface/Rename.hs ===================================== @@ -678,6 +678,8 @@ rnIfaceCo (IfaceAxiomInstCo n i cs) = IfaceAxiomInstCo <$> rnIfaceGlobal n <*> pure i <*> mapM rnIfaceCo cs rnIfaceCo (IfaceUnivCo s r t1 t2) = IfaceUnivCo s r <$> rnIfaceType t1 <*> rnIfaceType t2 + -- Renaming affects only type constructors, not coercion variables, + -- so no need to recurse into the provenance. rnIfaceCo (IfaceSymCo c) = IfaceSymCo <$> rnIfaceCo c rnIfaceCo (IfaceTransCo c1 c2) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1795,7 +1795,7 @@ freeNamesIfCoercion (IfaceAxiomRuleCo _ax cos) freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co -freeNamesIfProv (IfacePluginProv _) = emptyNameSet +freeNamesIfProv (IfacePluginProv _ _ _) = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -155,7 +155,7 @@ type IfaceKind = IfaceType -- Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType' -- before being printed. See Note [Pretty printing via Iface syntax] in "GHC.Types.TyThing.Ppr" data IfaceType - = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType] + = IfaceFreeTyVar TyVar -- See Note [Free TyVars and CoVars in IfaceType] | IfaceTyVar IfLclName -- Type/coercion variable only, not tycon | IfaceLitTy IfaceTyLit | IfaceAppTy IfaceType IfaceAppArgs @@ -285,7 +285,7 @@ instance Outputable IfaceTyConSort where ppr (IfaceSumTyCon n) = text "sum:" <> ppr n ppr IfaceEqualityTyCon = text "equality" -{- Note [Free tyvars in IfaceType] +{- Note [Free TyVars and CoVars in IfaceType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nowadays (since Nov 16, 2016) we pretty-print a Type by converting to an IfaceType and pretty printing that. This eliminates a lot of @@ -433,7 +433,7 @@ data IfaceCoercion | IfaceCoVarCo IfLclName | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion] | IfaceAxiomRuleCo IfLclName [IfaceCoercion] - -- There are only a fixed number of CoAxiomRules, so it suffices + -- ^ There are only a fixed number of CoAxiomRules, so it suffices -- to use an IfaceLclName to distinguish them. -- See Note [Adding built-in type families] in GHC.Builtin.Types.Literals | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType @@ -444,13 +444,16 @@ data IfaceCoercion | IfaceInstCo IfaceCoercion IfaceCoercion | IfaceKindCo IfaceCoercion | IfaceSubCo IfaceCoercion - | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType] + | IfaceFreeCoVar CoVar -- ^ See Note [Free TyVars and CoVars in IfaceType] | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion] data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion - | IfacePluginProv String + | IfacePluginProv String [IfLclName] [Var] + -- ^ Local covars and open (free) covars resp + -- See Note [Free TyVars and CoVars in IfaceType] + {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -671,7 +674,7 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) - go_prov co@(IfacePluginProv _) = co + go_prov co@(IfacePluginProv _ _ _) = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1024,7 +1027,7 @@ ppr_ty ctxt_prec ty | not (isIfaceRhoType ty) = ppr_sigma ShowForAllMust ctxt_prec ty ppr_ty _ (IfaceForAllTy {}) = panic "ppr_ty" -- Covered by not.isIfaceRhoType ppr_ty _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar! -ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [Free tyvars in IfaceType] +ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [Free TyVars and CoVars in IfaceType] ppr_ty ctxt_prec (IfaceTyConApp tc tys) = pprTyTcApp ctxt_prec tc tys ppr_ty ctxt_prec (IfaceTupleTy i p tys) = ppr_tuple ctxt_prec i p tys -- always fully saturated ppr_ty _ (IfaceLitTy n) = pprIfaceTyLit n @@ -1956,7 +1959,7 @@ ppr_co ctxt_prec co@(IfaceForAllCo {}) = let (tvs, co'') = split_co co' in ((name,kind_co,visL,visR):tvs,co'') split_co co' = ([], co') --- Why these three? See Note [Free tyvars in IfaceType] +-- Why these three? See Note [Free TyVars and CoVars in IfaceType] ppr_co _ (IfaceFreeCoVar covar) = ppr covar ppr_co _ (IfaceCoVarCo covar) = ppr covar ppr_co _ (IfaceHoleCo covar) = braces (ppr covar) @@ -2011,8 +2014,8 @@ pprIfaceUnivCoProv (IfacePhantomProv co) = text "phantom" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co -pprIfaceUnivCoProv (IfacePluginProv s) - = text "plugin" <+> doubleQuotes (text s) +pprIfaceUnivCoProv (IfacePluginProv s cvs fcvs) + = hang (text "plugin") 2 (sep [doubleQuotes (text s), ppr cvs, ppr fcvs]) ------------------- instance Outputable IfaceTyCon where @@ -2173,6 +2176,7 @@ ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where put_ _ (IfaceFreeTyVar tv) = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ bh (IfaceForAllTy aa ab) = do putByte bh 0 @@ -2321,9 +2325,10 @@ instance Binary IfaceCoercion where put_ bh b put_ _ (IfaceFreeCoVar cv) = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv) + -- See Note [Free TyVars and CoVars in IfaceType] put_ _ (IfaceHoleCo cv) = pprPanic "Can't serialise IfaceHoleCo" (ppr cv) - -- See Note [Holes in IfaceCoercion] + -- See Note [Holes in IfaceCoercion] get bh = do tag <- getByte bh @@ -2393,9 +2398,12 @@ instance Binary IfaceUnivCoProv where put_ bh (IfaceProofIrrelProv a) = do putByte bh 2 put_ bh a - put_ bh (IfacePluginProv a) = do + put_ bh (IfacePluginProv a cvs fcvs) = do putByte bh 3 put_ bh a + -- See Note [Free TyVars and CoVars in IfaceType] + assertPpr (null fcvs) (ppr cvs $$ ppr fcvs) $ + put_ bh cvs get bh = do tag <- getByte bh @@ -2405,7 +2413,8 @@ instance Binary IfaceUnivCoProv where 2 -> do a <- get bh return $ IfaceProofIrrelProv a 3 -> do a <- get bh - return $ IfacePluginProv a + cvs <- get bh + return $ IfacePluginProv a cvs [] _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1493,7 +1493,10 @@ tcIfaceCo = go tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco -tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str +tcIfaceUnivCoProv (IfacePluginProv str cvs fcvs) = + assertPpr (null fcvs) (ppr fcvs) $ do + cvs' <- mapM tcIfaceLclId cvs + return $ PluginProv str $ mkDVarSet cvs' {- ************************************************************************ ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -156,7 +156,7 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co - go_prov (PluginProv _) = emptyNameEnv + go_prov (PluginProv _ _) = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1592,7 +1592,10 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co - go_prov dv (PluginProv _) = return dv + go_prov dv (PluginProv _ cvs) = strictFoldDVarSet zt_cv (return dv) cvs + + zt_cv :: CoVar -> TcM CandidatesQTvs -> TcM CandidatesQTvs + zt_cv cv mdvs = do { dvs <- mdvs; go_cv dvs cv } go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -1120,7 +1120,7 @@ To achieve this, we use a variant of the 'typed' lens from 'generic-lens' first, and decide whether to recur into it using the HasTypeQ type family. - The two different behaviours are controlled by two main instances (*) and (**). - - (*) recurs into a subtype, when we have a type family equation such as: + - (*) recurses into a subtype, when we have a type family equation such as: ConRecursInto "TcRnCannotDeriveInstance" = 'Just DeriveInstanceErrReason ===================================== compiler/GHC/Types/RepType.hs ===================================== @@ -535,7 +535,7 @@ and returns the PrimRep IntRep. (See the definition of runtimeRepSimpleDataCons GHC.Builtin.Types and its helper function mk_runtime_rep_dc.) Example 2 passes the promoted list as the one argument to the extracted function. The extracted function is defined as prim_rep_fun within tupleRepDataCon in GHC.Builtin.Types. It takes one argument, decomposes -the promoted list (with extractPromotedList), and then recurs back to runtimeRepPrimRep +the promoted list (with extractPromotedList), and then recurses back to runtimeRepPrimRep to process the LiftedRep and WordRep, concatenating the results. -} ===================================== compiler/GHC/Types/TyThing/Ppr.hs ===================================== @@ -98,7 +98,7 @@ Consequences: (in GHC.IfaceToCore). For example, IfaceClosedSynFamilyTyCon stores a [IfaceAxBranch] that is used only for pretty-printing. -- See Note [Free tyvars in IfaceType] in GHC.Iface.Type +- See Note [Free TyVars and CoVars in IfaceType] in GHC.Iface.Type See #7730, #8776 for details -} ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Unique.DSet ( lookupUniqDSet, uniqDSetToList, partitionUniqDSet, - mapUniqDSet + mapUniqDSet, strictFoldUniqDSet ) where import GHC.Prelude @@ -125,7 +125,15 @@ partitionUniqDSet p = coerce . partitionUDFM p . getUniqDSet -- See Note [UniqSet invariant] in GHC.Types.Unique.Set mapUniqDSet :: Uniquable b => (a -> b) -> UniqDSet a -> UniqDSet b -mapUniqDSet f = mkUniqDSet . map f . uniqDSetToList +mapUniqDSet f (UniqDSet m) = UniqDSet $ unsafeCastUDFMKey $ mapUDFM f m + -- Simply apply `f` to each element, retaining all the structure unchanged. + -- The identification of keys and elements prevents a derived Functor + -- instance, but `unsafeCastUDFMKey` makes it possible to apply the strict + -- mapping from DFM. + +strictFoldUniqDSet :: (a -> r -> r) -> r -> UniqDSet a -> r +strictFoldUniqDSet k r s = foldl' (\ !r e -> k e r) r $ + uniqDSetToList s -- Two 'UniqDSet's are considered equal if they contain the same -- uniques. ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Var.Set ( nonDetStrictFoldVarSet, -- * Deterministic Var set types - DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, + DVarSet, DIdSet, DTyVarSet, DCoVarSet, DTyCoVarSet, -- ** Manipulating these sets emptyDVarSet, unitDVarSet, mkDVarSet, @@ -38,7 +38,7 @@ module GHC.Types.Var.Set ( isEmptyDVarSet, delDVarSet, delDVarSetList, minusDVarSet, nonDetStrictFoldDVarSet, - filterDVarSet, mapDVarSet, + filterDVarSet, mapDVarSet, strictFoldDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, sizeDVarSet, seqDVarSet, @@ -232,6 +232,9 @@ type DIdSet = UniqDSet Id -- | Deterministic Type Variable Set type DTyVarSet = UniqDSet TyVar +-- | Deterministic Coercion Variable Set +type DCoVarSet = UniqDSet CoVar + -- | Deterministic Type or Coercion Variable Set type DTyCoVarSet = UniqDSet TyCoVar @@ -308,6 +311,9 @@ allDVarSet p = allUDFM p . getUniqDSet mapDVarSet :: Uniquable b => (a -> b) -> UniqDSet a -> UniqDSet b mapDVarSet = mapUniqDSet +strictFoldDVarSet :: (a -> r -> r) -> r -> UniqDSet a -> r +strictFoldDVarSet = strictFoldUniqDSet + filterDVarSet :: (Var -> Bool) -> DVarSet -> DVarSet filterDVarSet = filterUniqDSet ===================================== compiler/GHC/Utils/FV.hs ===================================== @@ -21,6 +21,7 @@ module GHC.Utils.FV ( delFVs, filterFV, mapUnionFV, + fvDVarSetSome, ) where import GHC.Prelude @@ -195,3 +196,7 @@ mkFVs :: [Var] -> FV mkFVs vars fv_cand in_scope acc = mapUnionFV unitFV vars fv_cand in_scope acc {-# INLINE mkFVs #-} + +fvDVarSetSome :: InterestingVarFun -> FV -> DVarSet +fvDVarSetSome interesting_var fv = + mkDVarSet $ fst $ fv interesting_var emptyVarSet ([], emptyVarSet) ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -15,6 +15,14 @@ Language Compiler ~~~~~~~~ +- Constructor ``PluginProv`` of type ``UnivCoProvenance``, relevant +for typing plugins, gets an extra ``DCoVarSet`` argument. +The argument is intended to contain the in-scope coercion variables +that the the proof represented by the coercion makes use of. +See ``Note [The importance of tracking free coercion variables]`` +in ``GHC.Core.TyCo.Rep``, :ref:`constraint-solving-with-plugins` +and the migration guide. + GHCi ~~~~ ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -760,10 +760,33 @@ This evidence is ignored for Given constraints, which GHC "solves" simply by discarding them; typically this is used when they are uninformative (e.g. reflexive equations). For Wanted constraints, the evidence will form part of the Core term that is generated after -typechecking, and can be checked by ``-dcore-lint``. It is possible for -the plugin to create equality axioms for use in evidence terms, but GHC -does not check their consistency, and inconsistent axiom sets may lead -to segfaults or other runtime misbehaviour. +typechecking, and can be checked by ``-dcore-lint``. + +When solving a Wanted equality constraint (of type ``t1 ~N# t2`` +or ``t1 ~R# t2`` for nominal and representation equalities respectively), +the evidence (of type ``EvTerm``) will take the form ``EvExpr (Coercion co)``, +where the coercion ``co`` has type ``co :: t1 ~N# t2`` or ``co :: t1 ~R# t2`` +respectively. + +It is up to the plugin to construct a suitable coercion ``co``. +However, one possibility is to construct one of form :: + + UnivCo (PluginProv "my-plugin" gcvs) role t1 t2 + +A ``UnivCo`` of this form says "trust me: my-plugin has solved this Wanted +using (only) ``gcvs``". + +Here + +* The ``role`` should be the role of the original equality constraint + (nominal or representational). +* The ``gcvs`` is a set of "given coercion variables"; these are the coercion + variable bound by enclosing Given constraints, which the plugin has used + to justify solving the Wanted. + +For soundness, it is very important to include the ``gcvs``; otherwise +GHC may transform the program into a form that seg-faults. +See #23923 for a long dicussion. Evidence is required also when creating new Given constraints, which are usually implied by old ones. It is not uncommon that the evidence of a new ===================================== testsuite/tests/pmcheck/should_compile/T11195.hs ===================================== @@ -84,7 +84,7 @@ opt_trans_rule is in_co1@(UnivCo p1 r1 tyl1 _tyr1) = Just $ PhantomProv $ opt_trans is kco1 kco2 opt_trans_prov (ProofIrrelProv kco1) (ProofIrrelProv kco2) = Just $ ProofIrrelProv $ opt_trans is kco1 kco2 - opt_trans_prov (PluginProv str1) (PluginProv str2) + opt_trans_prov (PluginProv str1 _) (PluginProv str2 _) | str1 == str2 = Just p1 opt_trans_prov _ _ = Nothing ===================================== testsuite/tests/tcplugins/CtIdPlugin.hs ===================================== @@ -21,6 +21,7 @@ import GHC.Tc.Plugin import GHC.Tc.Types import GHC.Tc.Types.Constraint import GHC.Tc.Types.Evidence +import GHC.Types.Unique.DSet -- common import Common @@ -41,7 +42,7 @@ solver :: [String] -> PluginDefs -> EvBindsVar -> [Ct] -> [Ct] -> TcPluginM TcPluginSolveResult solver _args defs ev givens wanteds = do - let pluginCo = mkUnivCo (PluginProv "CtIdPlugin") Representational + let pluginCo = mkUnivCo (PluginProv "CtIdPlugin" emptyUniqDSet) Representational -- Empty is fine. This plugin does not use "givens". let substEvidence ct ct' = evCast (ctEvExpr $ ctEvidence ct') $ pluginCo (ctPred ct') (ctPred ct) ===================================== testsuite/tests/tcplugins/RewritePlugin.hs ===================================== @@ -45,6 +45,8 @@ import GHC.Tc.Types.Constraint ) import GHC.Tc.Types.Evidence ( EvTerm(EvExpr), Role(Nominal) ) +import GHC.Types.Unique.DSet + ( emptyUniqDSet ) import GHC.Types.Unique.FM ( UniqFM, listToUFM ) @@ -85,5 +87,5 @@ mkTyFamReduction :: TyCon -> [ Type ] -> Type -> Reduction mkTyFamReduction tyCon args res = Reduction co res where co :: Coercion - co = mkUnivCo ( PluginProv "RewritePlugin" ) Nominal + co = mkUnivCo ( PluginProv "RewritePlugin" emptyUniqDSet) Nominal -- Empty is fine. This plugin does not use "givens". ( mkTyConApp tyCon args ) res ===================================== testsuite/tests/tcplugins/TyFamPlugin.hs ===================================== @@ -39,6 +39,8 @@ import GHC.Tc.Types.Constraint ) import GHC.Tc.Types.Evidence ( EvBindsVar, EvTerm(EvExpr), Role(Nominal) ) +import GHC.Types.Unique.DSet + ( emptyUniqDSet ) -- common import Common @@ -78,6 +80,6 @@ solveCt ( PluginDefs {..} ) ct@( classifyPredType . ctPred -> EqPred NomEq lhs r , let evTerm :: EvTerm evTerm = EvExpr . Coercion - $ mkUnivCo ( PluginProv "TyFamPlugin" ) Nominal lhs rhs + $ mkUnivCo ( PluginProv "TyFamPlugin" emptyUniqDSet) Nominal lhs rhs -- Empty is fine. This plugin does not use "givens". = pure $ Just ( evTerm, ct ) solveCt _ ct = pure Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e29277caccfbf3577ab48d7454121ec47c522778 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e29277caccfbf3577ab48d7454121ec47c522778 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 14:21:59 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 16 Apr 2024 10:21:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24676 Message-ID: <661e8987bda_157d4344fe44109917@gitlab.mail> Simon Peyton Jones pushed new branch wip/T24676 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24676 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 14:35:51 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 10:35:51 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Clone CoVars in CorePrep Message-ID: <661e8cc713a8c_157d4369be28121765@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 01970a90 by Simon Peyton Jones at 2024-04-16T10:34:59-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 563dbac2 by Andreas Klebinger at 2024-04-16T10:35:00-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 02251684 by Ben Gamari at 2024-04-16T10:35:01-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - f8e1c19b by Alan Zimmerman at 2024-04-16T10:35:01-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - c9cb33b2 by Bryan Richter at 2024-04-16T10:35:02-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - ddbc0539 by Ben Gamari at 2024-04-16T10:35:02-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 0336cc55 by Teo Camarasu at 2024-04-16T10:35:02-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - ee153cb7 by Ben Gamari at 2024-04-16T10:35:03-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 30 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - docs/index.html.in - hadrian/src/Rules/Generate.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - rts/posix/ticker/TimerFd.c - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58f6f763a603195093f097d115d2b6b8302e2ddd...ee153cb72f4187995dd3e97bc34d9815f71c22d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58f6f763a603195093f097d115d2b6b8302e2ddd...ee153cb72f4187995dd3e97bc34d9815f71c22d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 14:36:17 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 16 Apr 2024 10:36:17 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 7 commits: Refactor the Binary serialisation interface Message-ID: <661e8ce12edda_157d435b35101311cc@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: a46734e8 by Fendor at 2024-04-16T12:33:49+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - 442649b4 by Fendor at 2024-04-16T12:33:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 05ddf708 by Fendor at 2024-04-16T16:34:42+02:00 Add Eq and Ord instance to IfaceType Bump haddock submodule for IfLclName changes - - - - - 93908b27 by Fendor at 2024-04-16T16:34:42+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions. We fix this by adding a deduplication table to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - d65f6ab7 by Matthew Pickering at 2024-04-16T16:34:42+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - f5b0be92 by Matthew Pickering at 2024-04-16T16:34:42+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 418133a9 by Fendor at 2024-04-16T16:34:42+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0823ceaec1f590e127d84ee51a57f300f18d50dc...418133a9b6252d6501759a9d0d0de27b6786e183 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0823ceaec1f590e127d84ee51a57f300f18d50dc...418133a9b6252d6501759a9d0d0de27b6786e183 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 18:36:04 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 14:36:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Make template-haskell a stage1 package Message-ID: <661ec514216f3_15ffb389de4c3292d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 06a72e2e by Teo Camarasu at 2024-04-16T14:35:37-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 1caae6fc by Ben Gamari at 2024-04-16T14:35:37-04:00 Bump parsec submodule to 3.1.17.0 - - - - - cd4093c2 by Simon Peyton Jones at 2024-04-16T14:35:38-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 09f50241 by Andreas Klebinger at 2024-04-16T14:35:39-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 7b7f1ea8 by Teo Camarasu at 2024-04-16T14:35:40-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - aedcae3d by Ben Gamari at 2024-04-16T14:35:40-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 2cf189f4 by Alan Zimmerman at 2024-04-16T14:35:41-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - da629ca8 by Bryan Richter at 2024-04-16T14:35:41-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - d2e13d5e by Ben Gamari at 2024-04-16T14:35:41-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 98a029e3 by Teo Camarasu at 2024-04-16T14:35:42-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - 7d067fc4 by Ben Gamari at 2024-04-16T14:35:42-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - distrib/mkDocs/mkDocs - docs/index.html.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ee153cb72f4187995dd3e97bc34d9815f71c22d2...7d067fc444c4ef58cb2090450d992c5470b55b2a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ee153cb72f4187995dd3e97bc34d9815f71c22d2...7d067fc444c4ef58cb2090450d992c5470b55b2a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 16 23:10:47 2024 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 16 Apr 2024 19:10:47 -0400 Subject: [Git][ghc/ghc][wip/T23764] 1011 commits: Compute all emitted diagnostic codes Message-ID: <661f05775952d_2f0bc8ede540101846@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23764 at Glasgow Haskell Compiler / GHC Commits: 0ef1d8ae by sheaf at 2023-08-08T21:26:51-04:00 Compute all emitted diagnostic codes This commit introduces in GHC.Types.Error.Codes the function constructorCodes :: forall diag. (...) => Map DiagnosticCode String which computes a collection of all the diagnostic codes that correspond to a particular type. In particular, we can compute the collection of all diagnostic codes emitted by GHC using the invocation constructorCodes @GhcMessage We then make use of this functionality in the new "codes" test which checks consistency and coverage of GHC diagnostic codes. It performs three checks: - check 1: all non-outdated GhcDiagnosticCode equations are statically used. - check 2: all outdated GhcDiagnosticCode equations are statically unused. - check 3: all statically used diagnostic codes are covered by the testsuite (modulo accepted exceptions). - - - - - 4bc7b1e5 by Fraser Tweedale at 2023-08-08T21:27:32-04:00 numberToRangedRational: fix edge cases for exp ≈ (maxBound :: Int) Currently a negative exponent less than `minBound :: Int` results in Infinity, which is very surprising and obviously wrong. ``` λ> read "1e-9223372036854775808" :: Double 0.0 λ> read "1e-9223372036854775809" :: Double Infinity ``` There is a further edge case where the exponent can overflow when increased by the number of tens places in the integer part, or underflow when decreased by the number of leading zeros in the fractional part if the integer part is zero: ``` λ> read "10e9223372036854775807" :: Double 0.0 λ> read "0.01e-9223372036854775808" :: Double Infinity ``` To resolve both of these issues, perform all arithmetic and comparisons involving the exponent in type `Integer`. This approach also eliminates the need to explicitly check the exponent against `maxBound :: Int` and `minBound :: Int`, because the allowed range of the exponent (i.e. the result of `floatRange` for the target floating point type) is certainly within those bounds. This change implements CLC proposal 192: https://github.com/haskell/core-libraries-committee/issues/192 - - - - - 6eab07b2 by Alan Zimmerman at 2023-08-08T21:28:10-04:00 EPA: Remove Location from WarningTxt source This is not needed. - - - - - 1a98d673 by Sebastian Graf at 2023-08-09T16:24:29-04:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 2274abc8 by Sebastian Graf at 2023-08-09T16:24:29-04:00 More explicit strictness in GHC.Real - - - - - ce8aa54c by Sebastian Graf at 2023-08-09T16:24:30-04:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - d004a36d by Sebastian Graf at 2023-08-09T16:24:30-04:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 8c73505e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - d8d993f1 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Disable tests RepPolyWrappedVar2 and RepPolyUnsafeCoerce1 in JS backend ... because those coerce between incompatible/unknown PrimReps. - - - - - f06e87e4 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Inlining literals into boring contexts is OK - - - - - 4a6b7c87 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Clarify floating of unsafeEqualityProofs (#23754) - - - - - b0f4752e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 7e0c8b3b by Sebastian Graf at 2023-08-09T16:24:30-04:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Annoyingly, in -O0 we sometimes generate ``` foo = case "blah"# of sat { __DEFAULT -> unpackCString# sat } ``` which makes it a bit harder to spot that we can emit a standard `stg_unpack_cstring` thunk. Fixes #23270. - - - - - 357f2738 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Deactivate -fcatch-nonexhaustive-cases in ghc-bignum (#23345) - - - - - 59202c80 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. In the ghc/alloc perf test `LargeRecord`, we introduce an additional Simplifier iteration due to #17910. E.g., FloatOut produces a binding ``` lvl_s6uK [Occ=Once1] :: GHC.Types.Int [LclId] lvl_s6uK = GHC.Types.I# 2# lvl_s6uL [Occ=Once1] :: GHC.Types.Any [LclId] lvl_s6uL = case Unsafe.Coerce.unsafeEqualityProof ... of { Unsafe.Coerce.UnsafeRefl v2_i6tr -> lvl_s6uK `cast` (... v2_i6tr ...) } ``` That occurs once and hence is pre-inlined unconditionally in the next Simplifier pass. It's non-trivial to find a way around that, but not really harmful otherwise. Hence we accept a 1.2% increase on some architectures. Metric Increase: LargeRecord - - - - - 00d31188 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - bf885d7a by Matthew Craven at 2023-08-09T16:25:07-04:00 Bump bytestring submodule to 0.11.5, again Fixes #23789. The bytestring commit used here is unreleased; a release can be made when necessary. - - - - - 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - ac379264 by Krzysztof Gogolewski at 2024-04-17T00:57:21+02:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 10 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - .gitlab/generate-ci/gen_ci.hs - .gitlab/generate-ci/generate-job-metadata - .gitlab/generate-ci/generate-jobs - .gitlab/issue_templates/bug.md → .gitlab/issue_templates/default.md The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c03efb0abd6ed90246fcbf063c5989c13cd10c6...ac379264956df89db32abc5f2a2bb89cf92ab6e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c03efb0abd6ed90246fcbf063c5989c13cd10c6...ac379264956df89db32abc5f2a2bb89cf92ab6e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:06:40 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:06:40 -0400 Subject: [Git][ghc/ghc][master] Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <661f12908af28_2f0bc8173e71c1079f7@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 10 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - testsuite/tests/numeric/should_run/all.T - + testsuite/tests/numeric/should_run/mul2int.hs - + testsuite/tests/numeric/should_run/mul2int.stdout - + testsuite/tests/numeric/should_run/mul2int.stdout-ws-32 Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -1556,7 +1556,7 @@ genCCall target dest_regs arg_regs bid = do -- pprTraceM "genCCall target" (ppr target) -- pprTraceM "genCCall formal" (ppr dest_regs) -- pprTraceM "genCCall actual" (ppr arg_regs) - + platform <- getPlatform case target of -- The target :: ForeignTarget call can either -- be a foreign procedure with an address expr @@ -1584,7 +1584,6 @@ genCCall target dest_regs arg_regs bid = do let (_res_hints, arg_hints) = foreignTargetHints target arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints - platform <- getPlatform let packStack = platformOS platform == OSDarwin (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL @@ -1625,6 +1624,139 @@ genCCall target dest_regs arg_regs bid = do | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + PrimTarget (MO_S_Mul2 w) + -- Life is easier when we're working with word sized operands, + -- we can use SMULH to compute the high 64 bits, and dst_needed + -- checks if the high half's bits are all the same as the low half's + -- top bit. + | w == W64 + , [src_a, src_b] <- arg_regs + -- dst_needed = did the result fit into just the low half + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + -- Are all high bits equal to the sign bit of the low word? + -- nd = (hi == ASR(lo,width-1)) ? 1 : 0 + CMP (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL` + CSET (OpReg W64 nd) NE + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- using the normal 64 bit multiply. Calculating the dst_needed value is + -- complicated a little by the need to be careful when truncation happens. + -- Currently this case can't be generated since + -- timesInt2# :: Int# -> Int# -> (# Int#, Int#, Int# #) + -- TODO: Should this be removed or would other primops be useful? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a', _format_x, code_a) <- getSomeReg src_a + (reg_b', _format_y, code_b) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + -- Do everything in a full 64 bit registers + w' = platformWordWidth platform + + (reg_a, code_a') <- signExtendReg w w' reg_a' + (reg_b, code_b') <- signExtendReg w w' reg_b' + + return ( + code_a `appOL` + code_b `appOL` + code_a' `appOL` + code_b' `snocOL` + -- the low 2w' of lo contains the full multiplication; + -- eg: int8 * int8 -> int16 result + -- so lo is in the last w of the register, and hi is in the second w. + SMULL (OpReg w' lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Make sure we hold onto the sign bits for dst_needed + ASR (OpReg w' hi) (OpReg w' lo) (OpImm (ImmInt $ widthInBits w)) `appOL` + -- lo can now be truncated so we can get at it's top bit easily. + truncateReg w' w lo `snocOL` + -- Note the use of CMN (compare negative), not CMP: we want to + -- test if the top half is negative one and the top + -- bit of the bottom half is positive one. eg: + -- hi = 0b1111_1111 (actually 64 bits) + -- lo = 0b1010_1111 (-81, so the result didn't need the top half) + -- lo' = ASR(lo,7) (second reg of SMN) + -- = 0b0000_0001 (theeshift gives us 1 for negative, + -- and 0 for positive) + -- hi == -lo'? + -- 0b1111_1111 == 0b1111_1111 (yes, top half is just overflow) + -- Another way to think of this is if hi + lo' == 0, which is what + -- CMN really is under the hood. + CMN (OpReg w' hi) (OpRegShift w' lo SLSR (widthInBits w - 1)) `snocOL` + -- Set dst_needed to 1 if hi and lo' were (negatively) equal + CSET (OpReg w' nd) EQ `appOL` + -- Finally truncate hi to drop any extraneous sign bits. + truncateReg w' w hi + , Nothing) + -- Can't handle > 64 bit operands + | otherwise -> unsupported (MO_S_Mul2 w) + PrimTarget (MO_U_Mul2 w) + -- The unsigned case is much simpler than the signed, all we need to + -- do is the multiplication straight into the destination registers. + | w == W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + UMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- Need to be careful to truncate the low half, but the upper half should be + -- be ok if the invariant in [Signed arithmetic on AArch64] is maintained. + -- Currently this case can't be produced by the compiler since + -- timesWord2# :: Word# -> Word# -> (# Word#, Word# #) + -- TODO: Remove? Or would the extra primop be useful for avoiding the extra + -- steps needed to do this in userland? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + w' = opRegWidth w + return ( + code_x `appOL` + code_y `snocOL` + -- UMULL: Xd = Wa * Wb with 64 bit result + -- W64 inputs should have been caught by case above + UMULL (OpReg W64 lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Extract and truncate high result + -- hi[w:0] = lo[2w:w] + UBFX (OpReg W64 hi) (OpReg W64 lo) + (OpImm (ImmInt $ widthInBits w)) -- lsb + (OpImm (ImmInt $ widthInBits w)) -- width to extract + `appOL` + truncateReg W64 w lo + , Nothing) + | otherwise -> unsupported (MO_U_Mul2 w) + + -- or a possibly side-effecting machine operation -- mop :: CallishMachOp (see GHC.Cmm.MachOp) PrimTarget mop -> do @@ -1714,7 +1846,6 @@ genCCall target dest_regs arg_regs bid = do -- Arithmatic -- These are not supported on X86, so I doubt they are used much. - MO_S_Mul2 _w -> unsupported mop MO_S_QuotRem _w -> unsupported mop MO_U_QuotRem _w -> unsupported mop MO_U_QuotRem2 _w -> unsupported mop @@ -1723,7 +1854,6 @@ genCCall target dest_regs arg_regs bid = do MO_SubWordC _w -> unsupported mop MO_AddIntC _w -> unsupported mop MO_SubIntC _w -> unsupported mop - MO_U_Mul2 _w -> unsupported mop -- Memory Ordering MO_AcquireFence -> return (unitOL DMBISH, Nothing) ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -79,11 +79,14 @@ regUsageOfInstr platform instr = case instr of -- 1. Arithmetic Instructions ------------------------------------------------ ADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) CMP l r -> usage (regOp l ++ regOp r, []) + CMN l r -> usage (regOp l ++ regOp r, []) MSUB dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) MUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) NEG dst src -> usage (regOp src, regOp dst) SMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) UDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -209,11 +212,14 @@ patchRegsOfInstr instr env = case instr of -- 1. Arithmetic Instructions ---------------------------------------------- ADD o1 o2 o3 -> ADD (patchOp o1) (patchOp o2) (patchOp o3) CMP o1 o2 -> CMP (patchOp o1) (patchOp o2) + CMN o1 o2 -> CMN (patchOp o1) (patchOp o2) MSUB o1 o2 o3 o4 -> MSUB (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) MUL o1 o2 o3 -> MUL (patchOp o1) (patchOp o2) (patchOp o3) NEG o1 o2 -> NEG (patchOp o1) (patchOp o2) SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2) (patchOp o3) SMULL o1 o2 o3 -> SMULL (patchOp o1) (patchOp o2) (patchOp o3) + UMULH o1 o2 o3 -> UMULH (patchOp o1) (patchOp o2) (patchOp o3) + UMULL o1 o2 o3 -> UMULL (patchOp o1) (patchOp o2) (patchOp o3) SDIV o1 o2 o3 -> SDIV (patchOp o1) (patchOp o2) (patchOp o3) SUB o1 o2 o3 -> SUB (patchOp o1) (patchOp o2) (patchOp o3) UDIV o1 o2 o3 -> UDIV (patchOp o1) (patchOp o2) (patchOp o3) @@ -540,6 +546,7 @@ data Instr -- | ADR ... -- | ADRP ... | CMP Operand Operand -- rd - op2 + | CMN Operand Operand -- rd + op2 -- | MADD ... -- | MNEG ... | MSUB Operand Operand Operand Operand -- rd = ra - rn × rm @@ -562,8 +569,8 @@ data Instr -- | UMADDL ... -- Xd = Xa + Wn × Wm -- | UMNEGL ... -- Xd = - Wn × Wm -- | UMSUBL ... -- Xd = Xa - Wn × Wm - -- | UMULH ... -- Xd = (Xn × Xm)_127:64 - -- | UMULL ... -- Xd = Wn × Wm + | UMULH Operand Operand Operand -- Xd = (Xn × Xm)_127:64 + | UMULL Operand Operand Operand -- Xd = Wn × Wm -- 2. Bit Manipulation Instructions ---------------------------------------- | SBFM Operand Operand Operand Operand -- rd = rn[i,j] @@ -644,12 +651,15 @@ instrCon i = POP_STACK_FRAME{} -> "POP_STACK_FRAME" ADD{} -> "ADD" CMP{} -> "CMP" + CMN{} -> "CMN" MSUB{} -> "MSUB" MUL{} -> "MUL" NEG{} -> "NEG" SDIV{} -> "SDIV" SMULH{} -> "SMULH" SMULL{} -> "SMULL" + UMULH{} -> "UMULH" + UMULL{} -> "UMULL" SUB{} -> "SUB" UDIV{} -> "UDIV" SBFM{} -> "SBFM" ===================================== compiler/GHC/CmmToAsm/AArch64/Ppr.hs ===================================== @@ -372,12 +372,15 @@ pprInstr platform instr = case instr of CMP o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 | otherwise -> op2 (text "\tcmp") o1 o2 + CMN o1 o2 -> op2 (text "\tcmn") o1 o2 MSUB o1 o2 o3 o4 -> op4 (text "\tmsub") o1 o2 o3 o4 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul") o1 o2 o3 | otherwise -> op3 (text "\tmul") o1 o2 o3 SMULH o1 o2 o3 -> op3 (text "\tsmulh") o1 o2 o3 SMULL o1 o2 o3 -> op3 (text "\tsmull") o1 o2 o3 + UMULH o1 o2 o3 -> op3 (text "\tumulh") o1 o2 o3 + UMULL o1 o2 o3 -> op3 (text "\tumull") o1 o2 o3 NEG o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfneg") o1 o2 | otherwise -> op2 (text "\tneg") o1 o2 ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -76,7 +76,8 @@ initStgToCmmConfig dflags mod = StgToCmmConfig | otherwise -> const True - , stgToCmmAllowIntMul2Instr = (ncg && x86ish) || llvm + , stgToCmmAllowIntMul2Instr = (ncg && (x86ish || aarch64)) || llvm + , stgToCmmAllowWordMul2Instr = (ncg && (x86ish || ppc || aarch64)) || llvm -- SIMD flags , stgToCmmVecInstrsErr = vec_err , stgToCmmAvx = isAvxEnabled dflags @@ -92,6 +93,9 @@ initStgToCmmConfig dflags mod = StgToCmmConfig JSPrimitives -> (False, False) NcgPrimitives -> (True, False) LlvmPrimitives -> (False, True) + aarch64 = case platformArch platform of + ArchAArch64 -> True + _ -> False x86ish = case platformArch platform of ArchX86 -> True ArchX86_64 -> True ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -70,6 +70,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmAllowQuotRem2 :: !Bool -- ^ Allowed to generate QuotRem , stgToCmmAllowExtendedAddSubInstrs :: !Bool -- ^ Allowed to generate AddWordC, SubWordC, Add2, etc. , stgToCmmAllowIntMul2Instr :: !Bool -- ^ Allowed to generate IntMul2 instruction + , stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction , stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks. ------------------------------ SIMD flags ------------------------------------ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1623,7 +1623,7 @@ emitPrimOp cfg primop = else Right genericIntSubCOp WordMul2Op -> \args -> opCallishHandledLater args $ - if allowExtAdd + if allowWord2Mul then Left (MO_U_Mul2 (wordWidth platform)) else Right genericWordMul2Op @@ -1850,6 +1850,7 @@ emitPrimOp cfg primop = allowQuotRem2 = stgToCmmAllowQuotRem2 cfg allowExtAdd = stgToCmmAllowExtendedAddSubInstrs cfg allowInt2Mul = stgToCmmAllowIntMul2Instr cfg + allowWord2Mul = stgToCmmAllowWordMul2Instr cfg allowFMA = stgToCmmAllowFMAInstr cfg ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -50,6 +50,7 @@ test('T4383', normal, compile_and_run, ['']) test('add2', normal, compile_and_run, ['-fobject-code']) test('mul2', normal, compile_and_run, ['-fobject-code']) +test('mul2int', normal, compile_and_run, ['-fobject-code']) test('quotRem2', normal, compile_and_run, ['-fobject-code']) test('T5863', normal, compile_and_run, ['']) ===================================== testsuite/tests/numeric/should_run/mul2int.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE MagicHash, UnboxedTuples #-} + +import GHC.Exts +import Data.Bits + +main :: IO () +main = do g 5 6 + g (-5) 6 + g 0x7ECA71DBFF1B7D8C 49 + g (-0x7ECA71DBFF1B7D8C) 49 + g 0x7ECA71DBFF1B7D8C 0x7E0EC51DFD94FE35 + g 0x7ECA71DBFF1B7D8C (-0x7E0EC51DFD94FE35) + + +g :: Int -> Int -> IO () +g wx@(I# x) wy@(I# y) + = do putStrLn "-----" + putStrLn ("Doing " ++ show wx ++ " * " ++ show wy) + case x `timesInt2#` y of + (# n, h, l #) -> + do let wh = I# h + wl = I# l + wlw = W# (int2Word# l) + wn = I# n + r | wn == 1 = shiftL (fromIntegral wh) (finiteBitSize wh) + + fromIntegral wlw + | otherwise = fromIntegral wl + + putStrLn ("High: " ++ show wh) + putStrLn ("Low: " ++ show wl) + putStrLn ("Needed: " ++ show wn) + putStrLn ("Result: " ++ show (r :: Integer)) + putStrLn ("Should be: " ++ show (fromIntegral wx * fromIntegral wy :: Integer)) + + ===================================== testsuite/tests/numeric/should_run/mul2int.stdout ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing 9136239983766240652 * 49 +High: 24 +Low: 4953901435516553164 +Needed: 1 +Result: 447675759204545791948 +Should be: 447675759204545791948 +----- +Doing -9136239983766240652 * 49 +High: -25 +Low: -4953901435516553164 +Needed: 1 +Result: -447675759204545791948 +Should be: -447675759204545791948 +----- +Doing 9136239983766240652 * 9083414231051992629 +High: 4498802171008813567 +Low: 3355592377236579836 +Needed: 1 +Result: 82988252286848496451678442784944154108 +Should be: 82988252286848496451678442784944154108 +----- +Doing 9136239983766240652 * -9083414231051992629 +High: -4498802171008813568 +Low: -3355592377236579836 +Needed: 1 +Result: -82988252286848496451678442784944154108 +Should be: -82988252286848496451678442784944154108 ===================================== testsuite/tests/numeric/should_run/mul2int.stdout-ws-32 ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing -14975604 * 49 +High: -1 +Low: -733804596 +Needed: 0 +Result: -733804596 +Should be: -733804596 +----- +Doing 14975604 * 49 +High: 0 +Low: 733804596 +Needed: 0 +Result: 733804596 +Should be: 733804596 +----- +Doing -14975604 * -40567243 +High: 141449 +Low: 137487868 +Needed: 1 +Result: 607518966539772 +Should be: 607518966539772 +----- +Doing -14975604 * 40567243 +High: -141450 +Low: -137487868 +Needed: 1 +Result: -607518966539772 +Should be: -607518966539772 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbdf1995956a7457c34b6895c67ef48f6c8384f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbdf1995956a7457c34b6895c67ef48f6c8384f2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:07:31 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:07:31 -0400 Subject: [Git][ghc/ghc][master] Make template-haskell a stage1 package Message-ID: <661f12c3d415_2f0bc8195b2ac1137d2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 14 changed files: - .gitignore - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghci/ghci.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/template-haskell.cabal.in Changes: ===================================== .gitignore ===================================== @@ -166,6 +166,7 @@ _darcs/ /libraries/ghc-boot/ghc-boot.cabal /libraries/ghc-boot-th/GNUmakefile /libraries/ghc-boot-th/ghc-boot-th.cabal +/libraries/ghc-boot-th-next/ghc-boot-th-next.cabal /libraries/ghc-boot-th/ghc.mk /libraries/ghc-heap/ghc-heap.cabal /libraries/ghci/GNUmakefile @@ -182,6 +183,7 @@ _darcs/ /libraries/synopsis.png /libraries/stamp/ /libraries/template-haskell/template-haskell.cabal +/libraries/template-haskell-next/template-haskell-next.cabal /linter.log /mk/are-validating.mk /mk/build.mk ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2916,3 +2916,116 @@ tcGetInterp = do case hsc_interp hsc_env of Nothing -> liftIO $ throwIO (InstallationError "Template haskell requires a target code interpreter") Just i -> pure i + +-- Note [Bootstrapping Template Haskell] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Staged Metaprogramming as implemented in Template Haskell introduces a whole +-- new dimension of staging to the already staged bootstrapping process. +-- The `template-haskell` library plays a crucial role in this process. +-- +-- Nomenclature: +-- +-- boot/stage0 compiler: An already released compiler used to compile GHC +-- stage(N+1) compiler: The result of compiling GHC from source with stage(N) +-- Recall that any code compiled by the stage1 compiler should be binary +-- identical to the same code compiled by later stages. +-- boot TH: the `template-haskell` that comes with (and is linked to) the +-- boot/stage0 compiler +-- in-tree TH: the `template-haskell` library that lives in GHC's repository. +-- Recall that building in-tree TH with the stage1 compiler yields a binary +-- that is identical to the in-tree TH compiled by stage2. +-- boot library: A library such as bytestring or containers that GHC depends on. +-- CONFUSINGLY, we build these libraries with the boot compiler as well as +-- the stage1 compiler; thus the "boot" in boot library does not refer to a +-- stage. +-- +-- Here is how we bootstrap `template-haskell` in tandem with GHC: +-- +-- 1. Link the stage1 compiler against the boot TH library. +-- 2. When building the stage1 compiler, build a CPP'd version of the in-tree +-- TH using the boot compiler under a different package-id, +-- `template-haskell-next`, and build stage1 GHC against that. +-- 3. Build the in-tree TH with the stage1 compiler. +-- 4. Build and link the stage2 compiler against the in-tree TH. +-- +-- Observations: +-- +-- A. The vendoring in (2) means that the fully qualified name of the in-tree TH +-- AST will be, e.g., `template-haskell-next:...VarE`, not `template-haskell:...VarE`. +-- That is OK, because we need it just for the `Binary` instance and to +-- convert TH ASTs returned by splices into the Hs AST, both of which do not +-- depend on the fully qualified name of the type to serialise! Importantly, +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] is +-- unaffected, because the desugaring refers to names in the in-tree TH +-- library, which is built in the next stage, stage1, and later. +-- +-- (Rejected) alternative designs: +-- +-- 1b. Build the in-tree TH with the stage0 compiler and link the stage1 compiler +-- against it. This is what we did until Apr 24 and it is problematic (#23536): +-- * (It rules out using TH in GHC, for example to derive GHC.Core.Map types, +-- because the boot compiler expects the boot TH AST in splices, but, e.g., +-- splice functions in GHC.Core.Map.TH would return the in-tree TH AST. +-- However, at the moment, we are not using TH in GHC anyway.) +-- * Ultimately, we must link the stage1 compiler against a +-- single version of template-haskell. +-- (Beyond the fact that doing otherwise would invite even +-- more "which `template-haskell` is this" confusion, it +-- would also result in confusing linker errors: see for +-- example #21981. In principle we could likely lift this +-- restriction with more aggressive name mangling, but the +-- knock-on effects of doing so are unexplored.) +-- * If the single version is the in-tree TH, we have to recompile all boot +-- libraries (e.g. bytestring, containers) with this new TH version. +-- * But the boot libraries must *not* be built against a non-boot TH version. +-- The reason is Note [Hard-wiring in-tree template-haskell for desugaring quotes]: +-- The boot compiler will desugar quotes wrt. names in the boot TH version. +-- A quote like `[| unsafePackLenLiteral |]` in bytestring will desugar +-- to `varE (mkNameS "unsafePackLenLiteral")`, and all +-- those smart constructors refer to locations in *boot TH*, because that +-- is all that the boot GHC knows about. +-- If the in-tree TH were to move or rename the definition of +-- `mkNameS`, the boot compiler would report a linker error when +-- compiling bytestring. +-- * (Stopping to use quotes in bytestring is no solution, either, because +-- the `Lift` type class is wired-in as well. +-- Only remaining option: provide an entirely TH-less variant of every +-- boot library. That would place a huge burden on maintainers and is +-- thus rejected.) +-- * We have thus made it impossible to refactor in-tree TH. +-- This problem was discussed in #23536. +-- 1c. Do not build the stage1 compiler against any template-haskell library. +-- This is viable because no splices need to be run as part of the +-- bootstrapping process, so we could CPP away all the code in the stage1 +-- compiler that refers to template-haskell types. However, +-- * it is not so simple either: a surprising example is GHC.Tc.Errors.Types +-- where we would need to replace all TH types with dummy types. +-- (We *cannot* simply CPP away TH-specific error constructors because +-- that affects binary compatibility with the stage2 compiler.) +-- * we would still need to vendor the updated Extension enum, so even +-- though we had to use a lot of CPP, we still end up depending on names +-- that are not present in the stage2 compiler. +-- * this design would never allow us to use TH in GHC's code base, for +-- example in GHC.Core.Map. +-- It seems simpler just to depend on a template-haskell library in a fake +-- namespace. +-- 2b. Alternatively vendor the parts relevant to serialising +-- the (new, in-tree) TH AST into `ghc-boot`, thus shadowing definitions in the +-- implicitly linked boot TH. +-- * We found that this led to quite a bit of duplication in the +-- `ghc-boot` cabal file. + +-- Note [Hard-wiring in-tree template-haskell for desugaring quotes] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- To desugar Template Haskell quotes, GHC needs to wire in a bunch of Names in the +-- `template-haskell` library as Note [Known-key names], in GHC.Builtin.Names.TH. +-- Consider +-- > foo :: Q Exp +-- > foo = [| unwords ["hello", "world"] |] +-- this desugars to Core that looks like this +-- > varE (mkNameS "unwords") `appE` listE [litE (stringE "hello"), litE (stringE "world")] +-- And all these smart constructors are known-key. +-- NB: Since the constructors are known-key, it is impossible to link this program +-- against another template-haskell library in which, e.g., `varE` was moved into a +-- different module. So effectively, GHC is hard-wired against the in-tree +-- template-haskell library. ===================================== compiler/ghc.cabal.in ===================================== @@ -82,6 +82,15 @@ Flag hadrian-stage0 Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library Default-Language: GHC2021 Exposed: False @@ -115,7 +124,6 @@ Library containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, - template-haskell == 2.22.*, hpc >= 0.6 && < 0.8, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, @@ -125,6 +133,13 @@ Library ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ + if flag(bootstrap) + Build-Depends: + template-haskell-next + else + Build-Depends: + template-haskell == 2.22.* + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else ===================================== hadrian/src/Packages.hs ===================================== @@ -4,12 +4,12 @@ module Packages ( array, base, binary, bytestring, cabal, cabalSyntax, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, osString, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, + runGhc, semaphoreCompat, stm, templateHaskell, templateHaskellNext, terminfo, text, time, timeout, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -37,11 +37,11 @@ ghcPackages :: [Package] ghcPackages = [ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps , compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls - , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform + , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform , ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim , ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString - , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell, templateHaskellNext , terminfo, text, time, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -54,7 +54,7 @@ isGhcPackage = (`elem` ghcPackages) -- | Package definitions, see 'Package'. array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls, - exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcPlatform, + exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform, ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghci, ghcInternal, ghciWrapper, ghcPkg, ghcPrim, ghcToolchain, ghcToolchainBin, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, @@ -87,6 +87,7 @@ ghc = prg "ghc-bin" `setPath` "ghc" ghcBignum = lib "ghc-bignum" ghcBoot = lib "ghc-boot" ghcBootTh = lib "ghc-boot-th" +ghcBootThNext = lib "ghc-boot-th-next" ghcPlatform = lib "ghc-platform" ghcCompact = lib "ghc-compact" ghcConfig = prg "ghc-config" `setPath` "testsuite/ghc-config" @@ -123,6 +124,7 @@ runGhc = util "runghc" semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" +templateHaskellNext = lib "template-haskell-next" terminfo = lib "terminfo" text = lib "text" time = lib "time" ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -35,7 +35,10 @@ extra_dependencies = where th_internal = (templateHaskell, "Language.Haskell.TH.Lib.Internal") - dep (p1, m1) (p2, m2) s = do + dep (p1, m1) (p2, m2) s = + -- We use the boot compiler's `template-haskell` library when building stage0, + -- so we don't need to register dependencies. + if isStage0 s then pure [] else do let context = Context s p1 (error "extra_dependencies: way not set") (error "extra_dependencies: iplace not set") ways <- interpretInContext context getLibraryWays mapM (\way -> (,) <$> path s way p1 m1 <*> path s way p2 m2) (S.toList ways) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -307,14 +307,18 @@ escapedPkgName = map f . pkgName f '-' = '_' f other = other -templateRule :: FilePath -> Interpolations -> Rules () -templateRule outPath interps = do +templateRuleFrom :: FilePath -> FilePath -> Interpolations -> Rules () +templateRuleFrom inPath outPath interps = do outPath %> \_ -> do - s <- readFile' (outPath <.> "in") + s <- readFile' inPath result <- runInterpolations interps s writeFile' outPath result putSuccess ("| Successfully generated " ++ outPath ++ " from its template") +templateRule :: FilePath -> Interpolations -> Rules () +templateRule outPath = + templateRuleFrom (outPath <.> "in") outPath + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -324,11 +328,31 @@ templateRules = do templateRule "utils/remote-iserv/remote-iserv.cabal" $ projectVersion templateRule "utils/runghc/runghc.cabal" $ projectVersion templateRule "libraries/ghc-boot/ghc-boot.cabal" $ projectVersion - templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ projectVersion + templateRule "libraries/ghc-boot-th/ghc-boot-th.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/ghc-boot-th/ghc-boot-th.cabal.in" + "libraries/ghc-boot-th-next/ghc-boot-th-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../ghc-boot-th" + ] templateRule "libraries/ghci/ghci.cabal" $ projectVersion templateRule "libraries/ghc-heap/ghc-heap.cabal" $ projectVersion templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion - templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion + templateRule "libraries/template-haskell/template-haskell.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "" + , interpolateVar "SourceRoot" $ pure "." + ] + templateRuleFrom "libraries/template-haskell/template-haskell.cabal.in" + "libraries/template-haskell-next/template-haskell-next.cabal" $ mconcat + [ projectVersion + , interpolateVar "Suffix" $ pure "-next" + , interpolateVar "SourceRoot" $ pure "../template-haskell" + ] templateRule "libraries/prologue.txt" $ packageVersions templateRule "rts/include/ghcversion.h" $ mconcat [ interpolateSetting "ProjectVersionInt" ProjectVersionInt ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -85,25 +85,13 @@ multiSetup pkg_s = do need (srcs ++ gens) let rexp m = ["-reexported-module", m] let hidir = root "interfaces" pkgPath p - writeFile' (resp_file root p) (intercalate "\n" (th_hack arg_list + writeFile' (resp_file root p) (intercalate "\n" (arg_list ++ modules cd ++ concatMap rexp (reexportModules cd) ++ ["-outputdir", hidir])) return (resp_file root p) - -- The template-haskell package is compiled with -this-unit-id=template-haskell but - -- everything which depends on it depends on `-package-id-template-haskell-2.17.0.0` - -- and so the logic for detetecting which home-units depend on what is defeated. - -- The workaround here is just to rewrite all the `-package-id` arguments to - -- point to `template-haskell` instead which works for the multi-repl case. - -- See #20887 - th_hack :: [String] -> [String] - th_hack ((isPrefixOf "-package-id template-haskell" -> True) : xs) = "-package-id" : "template-haskell" : xs - th_hack (x:xs) = x : th_hack xs - th_hack [] = [] - - toolRuleBody :: FilePath -> Action () toolRuleBody fp = do mm <- dirMap @@ -158,7 +146,7 @@ toolTargets = [ binary -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcToolchain , ghcToolchainBin @@ -172,7 +160,7 @@ toolTargets = [ binary , mtl , parsec , time - , templateHaskell + , templateHaskellNext , text , transformers , semaphoreCompat ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -93,7 +93,7 @@ stage0Packages = do , ghc , runGhc , ghcBoot - , ghcBootTh + , ghcBootThNext , ghcPlatform , ghcHeap , ghcToolchain @@ -108,7 +108,7 @@ stage0Packages = do , parsec , semaphoreCompat , time - , templateHaskell + , templateHaskellNext , text , transformers , unlit @@ -127,6 +127,10 @@ stage1Packages = do -- but not win32/unix because it depends on cross-compilation target | p == win32 = False | p == unix = False + -- These packages are only needed for bootstrapping. + -- See Note [Bootstrapping Template Haskell] + | p == templateHaskellNext = False + | p == ghcBootThNext = False | otherwise = True libraries0 <- filter good_stage0_package <$> stage0Packages @@ -143,6 +147,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcBootTh , ghcBignum , ghcCompact , ghcExperimental @@ -156,6 +161,7 @@ stage1Packages = do , pretty , rts , semaphoreCompat + , templateHaskell , stm , unlit , xhtml ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -87,6 +87,7 @@ packageArgs = do -- We do it through a cabal flag in ghc.cabal , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0" , flag StaticLibzstd `cabalFlag` "static-libzstd" + , stage0 `cabalFlag` "bootstrap" ] , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ] @@ -121,6 +122,10 @@ packageArgs = do , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ? input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] + -------------------------------- ghcBoot ------------------------------ + , package ghcBoot ? + builder (Cabal Flags) ? (stage0 `cabalFlag` "bootstrap") + --------------------------------- ghci --------------------------------- , package ghci ? mconcat [ @@ -151,9 +156,12 @@ packageArgs = do -- compiler comes with the same versions as the one we are building. -- builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir - , builder (Cabal Flags) ? ifM stage0 - (andM [cross, bootCross] `cabalFlag` "internal-interpreter") - (arg "internal-interpreter") + , builder (Cabal Flags) ? mconcat + [ ifM stage0 + (andM [cross, bootCross] `cabalFlag` "internal-interpreter") + (arg "internal-interpreter") + , stage0 `cabalFlag` "bootstrap" + ] ] @@ -178,6 +186,10 @@ packageArgs = do , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" + ---------------------------- template-haskell -------------------------- + , package templateHaskellNext ? + builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap" + ---------------------------------- text -------------------------------- , package text ? mconcat -- Disable SIMDUTF by default due to packaging difficulties ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: ghc-boot-th.cabal is automatically generated from --- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing --- ghc-boot-th.cabal.in, not ghc-boot-th.cabal. +-- WARNING: ghc-boot-th at Suffix@.cabal is automatically generated from +-- ghc-boot-th at Suffix@.cabal.in by ../../configure. Make sure you are editing +-- ghc-boot-th at Suffix@.cabal.in, not ghc-boot-th at Suffix@.cabal. -name: ghc-boot-th +name: ghc-boot-th at Suffix@ version: @ProjectVersionMunged@ license: BSD3 license-file: LICENSE @@ -27,6 +27,7 @@ source-repository head subdir: libraries/ghc-boot-th Library + hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -35,6 +35,15 @@ source-repository head location: https://gitlab.haskell.org/ghc/ghc.git subdir: libraries/ghc-boot +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + Library default-language: Haskell2010 other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables @@ -56,13 +65,6 @@ Library GHC.UniqueSubdir GHC.Version - -- reexport modules from ghc-boot-th so that packages don't have to import - -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to - -- understand and to refactor. - reexported-modules: - GHC.LanguageExtensions.Type - , GHC.ForeignSrcLang.Type - , GHC.Lexeme -- reexport platform modules from ghc-platform reexported-modules: @@ -81,7 +83,22 @@ Library filepath >= 1.3 && < 1.6, deepseq >= 1.4 && < 1.6, ghc-platform >= 0.1, - ghc-boot-th == @ProjectVersionMunged@ + + -- reexport modules from ghc-boot-th so that packages + -- don't have to import all of ghc-boot and ghc-boot-th. + -- It makes the dependency graph easier to understand. + reexported-modules: + GHC.LanguageExtensions.Type + , GHC.ForeignSrcLang.Type + , GHC.Lexeme + + if flag(bootstrap) + build-depends: + ghc-boot-th-next == @ProjectVersionMunged@ + else + build-depends: + ghc-boot-th == @ProjectVersionMunged@ + if !os(windows) build-depends: unix >= 2.7 && < 2.9 ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -22,6 +22,15 @@ Flag internal-interpreter Default: False Manual: True +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -84,8 +93,14 @@ library filepath >= 1.4 && < 1.6, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.22.*, transformers >= 0.5 && < 0.7 + if flag(bootstrap) + build-depends: + template-haskell-next == 2.22.* + else + build-depends: + template-haskell == 2.22.* + if !os(windows) Build-Depends: unix >= 2.7 && < 2.9 ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -34,49 +34,52 @@ module Language.Haskell.TH.Syntax -- $infix ) where -import qualified Data.Fixed as Fixed +import Prelude import Data.Data hiding (Fixity(..)) import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import System.FilePath import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) -import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Fix (MonadFix (..)) -import Control.Applicative (Applicative(..)) import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) import Control.Exception.Base (FixIOException (..)) import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) import System.IO ( hPutStrLn, stderr ) -import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) -import Data.Int +import Data.Char ( isAlpha, isAlphaNum, isUpper ) import Data.List.NonEmpty ( NonEmpty(..) ) -import Data.Void ( Void, absurd ) import Data.Word -import Data.Ratio -import GHC.CString ( unpackCString# ) import GHC.Generics ( Generic ) -import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), - TYPE, RuntimeRep(..), Levity(..), Multiplicity (..) ) import qualified Data.Kind as Kind (Type) -import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.Ptr ( Ptr, plusPtr ) import GHC.Lexeme ( startsVarSym, startsVarId ) import GHC.ForeignSrcLang.Type import Language.Haskell.TH.LanguageExtensions -import Numeric.Natural import Prelude hiding (Applicative(..)) import Foreign.ForeignPtr import Foreign.C.String import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#ifndef BOOTSTRAP_TH +import Control.Monad (liftM) import Data.Array.Byte (ByteArray(..)) +import Data.Char (ord) +import Data.Int +import Data.Ratio +import Data.Void ( Void, absurd ) +import GHC.CString ( unpackCString# ) import GHC.Exts ( ByteArray#, unsafeFreezeByteArray#, copyAddrToByteArray#, newByteArray# , isByteArrayPinned#, isTrue#, sizeofByteArray#, unsafeCoerce#, byteArrayContents# , copyByteArray#, newPinnedByteArray#) import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..)) +import GHC.Prim ( Int#, Word#, Char#, Double#, Float#, Addr# ) import GHC.ST (ST(..), runST) +import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..)) +import Numeric.Natural +import qualified Data.Fixed as Fixed +#endif ----------------------------------------------------- -- @@ -1018,6 +1021,8 @@ class Lift (t :: TYPE r) where liftTyped :: Quote m => t -> Code m t +-- See Note [Bootstrapping Template Haskell] +#ifndef BOOTSTRAP_TH -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where liftTyped x = unsafeCodeCoerce (lift x) @@ -1384,10 +1389,11 @@ rightName = 'Right nonemptyName :: Name nonemptyName = '(:|) +#endif oneName, manyName :: Name -oneName = 'One -manyName = 'Many +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" ----------------------------------------------------- -- ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -1,8 +1,8 @@ --- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by +-- WARNING: template-haskell at Suffix@.cabal is automatically generated from ../template-haskell/template-haskell.cabal.in by -- ../../configure. Make sure you are editing template-haskell.cabal.in, not --- template-haskell.cabal. +-- template-haskell at Suffix@.cabal. -name: template-haskell +name: template-haskell at Suffix@ version: 2.22.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 @@ -20,6 +20,15 @@ description: See for more information. +Flag bootstrap + Description: + Enabled when building the stage1 compiler in order to vendor the in-tree + `template-haskell` library (including its dependency `ghc-boot-th`), while + allowing dependencies to depend on the boot `template-haskell` library. + See Note [Bootstrapping Template Haskell] + Default: False + Manual: True + extra-source-files: changelog.md source-repository head @@ -56,7 +65,7 @@ Library build-depends: base >= 4.11 && < 4.21, - ghc-boot-th == @ProjectVersionMunged@, + ghc-boot-th at Suffix@ == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* @@ -64,12 +73,15 @@ Library System.FilePath System.FilePath.Posix System.FilePath.Windows - hs-source-dirs: ./vendored-filepath . + hs-source-dirs: @SourceRoot@/vendored-filepath @SourceRoot@ default-extensions: ImplicitPrelude ghc-options: -Wall - -- We need to set the unit ID to template-haskell (without a - -- version number) as it's magic. - ghc-options: -this-unit-id template-haskell + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + else + -- We need to set the unit ID to template-haskell (without a + -- version number) as it's magic. + ghc-options: -this-unit-id template-haskell View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42bd040702d9a1c620354e7de05aaff6ee849f38 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42bd040702d9a1c620354e7de05aaff6ee849f38 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:08:26 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:08:26 -0400 Subject: [Git][ghc/ghc][master] Bump parsec submodule to 3.1.17.0 Message-ID: <661f12fa8d765_2f0bc81c15f4c119775@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 1 changed file: - libraries/parsec Changes: ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 4a44a8cdaa8c3eaa97a73a6da05940dd3bf7c93b +Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d973e47b118c4cbddb8d74fe56b8093386b49a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d973e47b118c4cbddb8d74fe56b8093386b49a1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:09:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:09:06 -0400 Subject: [Git][ghc/ghc][master] Clone CoVars in CorePrep Message-ID: <661f13224106e_2f0bc81c463681228ae@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 5 changed files: - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T Changes: ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -20,7 +20,7 @@ module GHC.Core.TyCo.Subst extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, extendTCvSubst, extendTCvSubstWithClone, extendCvSubst, extendCvSubstWithClone, - extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone, + extendTvSubst, extendTvSubstWithClone, extendTvSubstList, extendTvSubstAndInScope, extendTCvSubstList, unionSubst, zipTyEnv, zipCoEnv, @@ -372,13 +372,6 @@ extendTvSubst (Subst in_scope ids tvs cvs) tv ty = assert (isTyVar tv) $ Subst in_scope ids (extendVarEnv tvs tv ty) cvs -extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst -extendTvSubstBinderAndInScope subst (Named (Bndr v _)) ty - = assert (isTyVar v ) - extendTvSubstAndInScope subst v ty -extendTvSubstBinderAndInScope subst (Anon {}) _ - = subst - extendTvSubstWithClone :: Subst -> TyVar -> TyVar -> Subst -- Adds a new tv -> tv mapping, /and/ extends the in-scope set with the clone -- Does not look in the kind of the new variable; ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -205,8 +205,7 @@ module GHC.Core.Type ( zapSubst, getSubstInScope, setInScope, getSubstRangeTyCoFVs, extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, extendTCvSubst, extendCvSubst, - extendTvSubst, extendTvSubstBinderAndInScope, - extendTvSubstList, extendTvSubstAndInScope, + extendTvSubst, extendTvSubstList, extendTvSubstAndInScope, extendTCvSubstList, extendTvSubstWithClone, extendTCvSubstWithClone, ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Core.Utils import GHC.Core.Opt.Arity import GHC.Core.Lint ( EndPassConfig(..), endPassIO ) import GHC.Core +import GHC.Core.Subst import GHC.Core.Make hiding( FloatBind(..) ) -- We use our own FloatBind here import GHC.Core.Type import GHC.Core.Coercion @@ -56,7 +57,6 @@ import GHC.Utils.Logger import GHC.Types.Demand import GHC.Types.Var -import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) @@ -103,25 +103,7 @@ The goal of this pass is to prepare for code generation. 5. ANF-isation results in additional bindings that can obscure values. We float these out; see Note [Floating in CorePrep]. -6. Clone all local Ids. - This means that all such Ids are unique, rather than the - weaker guarantee of no clashes which the simplifier provides. - And that is what the code generator needs. - - We don't clone TyVars or CoVars. The code gen doesn't need that, - and doing so would be tiresome because then we'd need - to substitute in types and coercions. - - We need to clone ids for two reasons: - + Things associated with labels in the final code must be truly unique in - order to avoid labels being shadowed in the final output. - + Even binders without info tables like function arguments or alternative - bound binders must be unique at least in their type/unique combination. - We only emit a single declaration for each binder when compiling to C - so if binders are not unique we would either get duplicate declarations - or misstyped variables. The later happend in #22402. - + We heavily use unique-keyed maps in the backend which can go wrong when - ids with the same unique are meant to represent the same variable. +6. Clone all local Ids. See Note [Cloning in CorePrep] 7. Give each dynamic CCall occurrence a fresh unique; this is rather like the cloning step above. @@ -178,6 +160,65 @@ Here is the syntax of the Core produced by CorePrep: We define a synonym for each of these non-terminals. Functions with the corresponding name produce a result in that syntax. + +Note [Cloning in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +In CorePrep we +* Always clone non-CoVar Ids, so each has a unique Unique +* Sometimes clone CoVars and TyVars + +We always clone non-CoVarIds, for three reasons + +1. Things associated with labels in the final code must be truly unique in + order to avoid labels being shadowed in the final output. + +2. Even binders without info tables like function arguments or alternative + bound binders must be unique at least in their type/unique combination. + We only emit a single declaration for each binder when compiling to C + so if binders are not unique we would either get duplicate declarations + or misstyped variables. The later happend in #22402. + +3. We heavily use unique-keyed maps in the backend which can go wrong when + ids with the same unique are meant to represent the same variable. + +Generally speaking we don't clone TyVars or CoVars. The code gen doesn't need +that (they are erased), and doing so would be tiresome because then we'd need +to substitute in types and coercions. But sometimes need to: see +Note [Cloning CoVars and TyVars] + +Note [Cloning CoVars and TyVars] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Normally we don't need to clone TyVars and CoVars, but there is one occasion +when we do (see #24463). When we have + case unsafeEqualityProof ... of UnsafeRefl g -> ... +we try to float it, using UnsafeEqualityCase. +Why? See (U3) in Note [Implementing unsafeCoerce] + +Alas, floating it widens the scope of `g`, and that led to catastrophe in +#24463, when two identically-named g's shadowed. + +Solution: clone `g`; see `cpCloneCoVarBndr`. + +BUT once we clone `g` we must apply the cloning substitution to all types +and coercions. But that in turn means that, given a binder like + /\ (a :: kind |> g). blah +we must substitute in a's kind, and hence need to substitute for `a` +itself in `blah`. + +So our plan is: + * Maintain a full Subst in `cpe_subst` + + * Clone a CoVar when we we meet an `isUnsafeEqualityCase`; + otherwise TyVar/CoVar binders are never cloned. + + * So generally the TCvSubst is empty + + * Apply the substitution to type and coercion arguments in Core; but + happily `substTy` has a no-op short-cut for an empty TCvSubst, so this + is usually very cheap. + + * In `cpCloneBndr`, for a tyvar/covar binder, check for an empty substitution; + in that case just do nothing -} type CpeArg = CoreExpr -- Non-terminal 'arg' @@ -763,10 +804,10 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) -- For example -- f (g x) ===> ([v = g x], f v) -cpeRhsE _ (Type ty) - = return (emptyFloats, Type ty) -cpeRhsE _ (Coercion co) - = return (emptyFloats, Coercion co) +cpeRhsE env (Type ty) + = return (emptyFloats, Type (cpSubstTy env ty)) +cpeRhsE env (Coercion co) + = return (emptyFloats, Coercion (cpSubstCo env co)) cpeRhsE env expr@(Lit lit) | LitNumber LitNumBigNat i <- lit = cpeBigNatLit env i @@ -799,7 +840,7 @@ cpeRhsE env (Tick tickish expr) cpeRhsE env (Cast expr co) = do { (floats, expr') <- cpeRhsE env expr - ; return (floats, Cast expr' co) } + ; return (floats, Cast expr' (cpSubstCo env co)) } cpeRhsE env expr@(Lam {}) = do { let (bndrs,body) = collectBinders expr @@ -807,7 +848,7 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } -cpeRhsE env (Case scrut bndr _ alts@[Alt con bs _]) +cpeRhsE env (Case scrut bndr _ alts@[Alt con [covar] _]) -- See (U3) in Note [Implementing unsafeCoerce] -- We need make the Case float, otherwise we get -- let x = case ... of UnsafeRefl co -> @@ -823,14 +864,18 @@ cpeRhsE env (Case scrut bndr _ alts@[Alt con bs _]) -- (such as `print003`). | Just rhs <- isUnsafeEqualityCase scrut bndr alts = do { (floats_scrut, scrut) <- cpeBody env scrut - ; (env, bndr) <- cpCloneBndr env bndr - ; (env, bs) <- cpCloneBndrs env bs + + ; (env, bndr') <- cpCloneBndr env bndr + ; (env, covar') <- cpCloneCoVarBndr env covar + -- Important: here we clone the CoVar + -- See Note [Cloning CoVars and TyVars] + -- Up until here this should do exactly the same as the regular code -- path of `cpeRhsE Case{}`. ; (floats_rhs, rhs) <- cpeBody env rhs -- ... but we want to float `floats_rhs` as in (U3) so that rhs' might -- become a value - ; let case_float = UnsafeEqualityCase scrut bndr con bs + ; let case_float = UnsafeEqualityCase scrut bndr' con [covar'] -- NB: It is OK to "evaluate" the proof eagerly. -- Usually there's the danger that we float the unsafeCoerce out of -- a branching Case alt. Not so here, because the regular code path @@ -849,7 +894,7 @@ cpeRhsE env (Case scrut bndr ty alts) where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 ty alts'') } + ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -1184,10 +1229,14 @@ cpeApp top_env expr in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) - -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth + -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth + where + arg_ty' = cpSubstTy env arg_ty CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth + -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth + where + co' = cpSubstCo env co CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make @@ -1199,7 +1248,10 @@ cpeApp top_env expr rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co - -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth + -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth + where + co' = cpSubstCo env co + -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -2220,6 +2272,7 @@ binding for data constructors; see Note [Data constructor workers]. Note [CorePrep inlines trivial CoreExpr not Id] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +TODO Why does cpe_env need to be an IdEnv CoreExpr, as opposed to an IdEnv Id? Naively, we might conjecture that trivial updatable thunks as per Note [Inlining in CorePrep] always have the form @@ -2259,11 +2312,11 @@ data CorePrepEnv -- the case where a function we think should bottom -- unexpectedly returns. - , cpe_env :: IdEnv CoreExpr -- Clone local Ids - -- ^ This environment is used for three operations: + , cpe_subst :: Subst + -- ^ The IdEnv part of the substitution is used for three operations: -- -- 1. To support cloning of local Ids so that they are - -- all unique (see item (6) of CorePrep overview). + -- all unique (see Note [Cloning in CorePrep]) -- -- 2. To support beta-reduction of runRW, see -- Note [runRW magic] and Note [runRW arg]. @@ -2271,6 +2324,9 @@ data CorePrepEnv -- 3. To let us inline trivial RHSs of non top-level let-bindings, -- see Note [lazyId magic], Note [Inlining in CorePrep] -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) + -- + -- The TyCoVar part of the substitution is used only for + -- Note [Cloning CoVars and TyVars] , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } @@ -2278,33 +2334,48 @@ data CorePrepEnv mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg - , cpe_env = emptyVarEnv + , cpe_subst = emptySubst , cpe_rec_ids = emptyUnVarSet } extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv -extendCorePrepEnv cpe id id' - = cpe { cpe_env = extendVarEnv (cpe_env cpe) id (Var id') } +extendCorePrepEnv cpe@(CPE { cpe_subst = subst }) id id' + = cpe { cpe_subst = subst2 } + where + subst1 = extendSubstInScope subst id' + subst2 = extendIdSubst subst1 id (Var id') + +extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv +extendCorePrepEnvList cpe@(CPE { cpe_subst = subst }) prs + = cpe { cpe_subst = subst2 } + where + subst1 = extendSubstInScopeList subst (map snd prs) + subst2 = extendIdSubstList subst1 [(id, Var id') | (id,id') <- prs] extendCorePrepEnvExpr :: CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv extendCorePrepEnvExpr cpe id expr - = cpe { cpe_env = extendVarEnv (cpe_env cpe) id expr } - -extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv -extendCorePrepEnvList cpe prs - = cpe { cpe_env = extendVarEnvList (cpe_env cpe) - (map (\(id, id') -> (id, Var id')) prs) } + = cpe { cpe_subst = extendIdSubst (cpe_subst cpe) id expr } lookupCorePrepEnv :: CorePrepEnv -> Id -> CoreExpr lookupCorePrepEnv cpe id - = case lookupVarEnv (cpe_env cpe) id of - Nothing -> Var id - Just exp -> exp + = case lookupIdSubst_maybe (cpe_subst cpe) id of + Just e -> e + Nothing -> Var id + -- Do not use GHC.Core.Subs.lookupIdSubst because that is a no-op on GblIds; + -- and Tidy has made top-level externally-visible Ids into GblIds enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv enterRecGroupRHSs env grp = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } +cpSubstTy :: CorePrepEnv -> Type -> Type +cpSubstTy (CPE { cpe_subst = subst }) ty = substTy subst ty + -- substTy has a short-cut if the TCvSubst is empty + +cpSubstCo :: CorePrepEnv -> Coercion -> Coercion +cpSubstCo (CPE { cpe_subst = subst }) co = substCo subst co + -- substCo has a short-cut if the TCvSubst is empty + ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2312,12 +2383,31 @@ enterRecGroupRHSs env grp cpCloneBndrs :: CorePrepEnv -> [InVar] -> UniqSM (CorePrepEnv, [OutVar]) cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs +cpCloneCoVarBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) +-- Clone the CoVar +-- See Note [Cloning CoVars and TyVars] +cpCloneCoVarBndr env@(CPE { cpe_subst = subst }) covar + = assertPpr (isCoVar covar) (ppr covar) $ + do { uniq <- getUniqueM + ; let covar1 = setVarUnique covar uniq + covar2 = updateVarType (substTy subst) covar1 + subst1 = extendTCvSubstWithClone subst covar covar2 + ; return (env { cpe_subst = subst1 }, covar2) } + cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) -cpCloneBndr env bndr - | isTyCoVar bndr - = return (env, bndr) - | otherwise - = do { bndr' <- clone_it bndr +-- See Note [Cloning in CorePrep] +cpCloneBndr env@(CPE { cpe_subst = subst }) bndr + | isTyCoVar bndr -- See Note [Cloning CoVars and TyVars] + = if isEmptyTCvSubst subst -- The common case + then return (env { cpe_subst = extendSubstInScope subst bndr }, bndr) + else -- No need to clone the Unique; but we must apply the substitution + let bndr1 = updateVarType (substTy subst) bndr + subst1 = extendTCvSubstWithClone subst bndr bndr1 + in return (env { cpe_subst = subst1 }, bndr1) + + | otherwise -- A non-CoVar Id + = do { bndr1 <- clone_it bndr + ; let bndr2 = updateIdTypeAndMult (substTy subst) bndr1 -- Drop (now-useless) rules/unfoldings -- See Note [Drop unfoldings and rules] @@ -2327,10 +2417,10 @@ cpCloneBndr env bndr ; let !unfolding' = trimUnfolding (realIdUnfolding bndr) -- Simplifier will set the Id's unfolding - bndr'' = bndr' `setIdUnfolding` unfolding' - `setIdSpecialisation` emptyRuleInfo + bndr3 = bndr2 `setIdUnfolding` unfolding' + `setIdSpecialisation` emptyRuleInfo - ; return (extendCorePrepEnv env bndr bndr'', bndr'') } + ; return (extendCorePrepEnv env bndr bndr3, bndr3) } where clone_it bndr | isLocalId bndr ===================================== testsuite/tests/core-to-stg/T24463.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE ViewPatterns #-} + +module T24463 where + +import Unsafe.Coerce (unsafeCoerce) + +data Term where + BinaryTerm :: !arg1 -> !arg2 -> Term + +f :: Term -> (b, c) +f (BinaryTerm t1 t2) = (unsafeCoerce t1, unsafeCoerce t2) + +pattern P :: b -> c -> Term +pattern P t1 t2 <- (f -> (t1, t2)) ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,3 +4,4 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24463', normal, compile, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d38bfa0c0f910208822579acaa999f87c2f8c65 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d38bfa0c0f910208822579acaa999f87c2f8c65 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:10:07 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:10:07 -0400 Subject: [Git][ghc/ghc][master] NCG: Fix a bug where we errounously removed a required jump instruction. Message-ID: <661f135f9e1b5_2f0bc81fd96b01262dd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 13 changed files: - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - + testsuite/tests/codeGen/should_run/T24507.hs - + testsuite/tests/codeGen/should_run/T24507.stdout - + testsuite/tests/codeGen/should_run/T24507_cmm.cmm Changes: ===================================== compiler/GHC/CmmToAsm/AArch64.hs ===================================== @@ -47,6 +47,7 @@ instance Instruction AArch64.Instr where patchRegsOfInstr = AArch64.patchRegsOfInstr isJumpishInstr = AArch64.isJumpishInstr jumpDestsOfInstr = AArch64.jumpDestsOfInstr + canFallthroughTo = AArch64.canFallthroughTo patchJumpInstr = AArch64.patchJumpInstr mkSpillInstr = AArch64.mkSpillInstr mkLoadInstr = AArch64.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -317,6 +317,12 @@ jumpDestsOfInstr (BL t _ _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr _ = [] +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid +canFallthroughTo (J (TBlock target)) bid = bid == target +canFallthroughTo (B (TBlock target)) bid = bid == target +canFallthroughTo _ _ = False + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points. ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -771,10 +771,9 @@ dropJumps :: forall a i. Instruction i => LabelMap a -> [GenBasicBlock i] dropJumps _ [] = [] dropJumps info (BasicBlock lbl ins:todo) | Just ins <- nonEmpty ins --This can happen because of shortcutting - , [dest] <- jumpDestsOfInstr (NE.last ins) , BasicBlock nextLbl _ : _ <- todo - , not (mapMember dest info) - , nextLbl == dest + , canFallthroughTo (NE.last ins) nextLbl + , not (mapMember nextLbl info) = BasicBlock lbl (NE.init ins) : dropJumps info todo | otherwise = BasicBlock lbl ins : dropJumps info todo ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -71,11 +71,17 @@ class Instruction instr where :: instr -> Bool - -- | Give the possible destinations of this jump instruction. + -- | Give the possible *local block* destinations of this jump instruction. -- Must be defined for all jumpish instructions. jumpDestsOfInstr :: instr -> [BlockId] + -- | Check if the instr always transfers control flow + -- to the given block. Used by code layout to eliminate + -- jumps that can be replaced by fall through. + canFallthroughTo + :: instr -> BlockId -> Bool + -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join ===================================== compiler/GHC/CmmToAsm/Monad.hs ===================================== @@ -78,8 +78,15 @@ data NcgImpl statics instr jumpDest = NcgImpl { cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl statics instr], generateJumpTableForInstr :: instr -> Maybe (NatCmmDecl statics instr), getJumpDestBlockId :: jumpDest -> Maybe BlockId, + -- | Does this jump always jump to a single destination and is shortcutable? + -- + -- We use this to determine shortcutable instructions - See Note [What is shortcutting] + -- Note that if we return a destination here we *most* support the relevant shortcutting in + -- shortcutStatics for jump tables and shortcutJump for the instructions itself. canShortcut :: instr -> Maybe jumpDest, + -- | Replace references to blockIds with other destinations - used to update jump tables. shortcutStatics :: (BlockId -> Maybe jumpDest) -> statics -> statics, + -- | Change the jump destination(s) of an instruction. shortcutJump :: (BlockId -> Maybe jumpDest) -> instr -> instr, -- | 'Module' is only for printing internal labels. See Note [Internal proc -- labels] in CLabel. @@ -105,6 +112,25 @@ data NcgImpl statics instr jumpDest = NcgImpl { -- when possible. } +{- Note [supporting shortcutting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For the concept of shortcutting see Note [What is shortcutting]. + +In order to support shortcutting across multiple backends uniformly we +use canShortcut, shortcutStatics and shortcutJump. + +canShortcut tells us if the backend support shortcutting of a instruction +and if so what destination we should retarget instruction to instead. + +shortcutStatics exists to allow us to update jump destinations in jump tables. + +shortcutJump updates the instructions itself. + +A backend can opt out of those by always returning Nothing for canShortcut +and implementing shortcutStatics/shortcutJump as \_ x -> x + +-} + {- Note [pprNatCmmDeclS and pprNatCmmDeclH] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each NcgImpl provides two implementations of its CmmDecl printer, pprNatCmmDeclS ===================================== compiler/GHC/CmmToAsm/PPC.hs ===================================== @@ -46,6 +46,7 @@ instance Instruction PPC.Instr where patchRegsOfInstr = PPC.patchRegsOfInstr isJumpishInstr = PPC.isJumpishInstr jumpDestsOfInstr = PPC.jumpDestsOfInstr + canFallthroughTo = PPC.canFallthroughTo patchJumpInstr = PPC.patchJumpInstr mkSpillInstr = PPC.mkSpillInstr mkLoadInstr = PPC.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/PPC/Instr.hs ===================================== @@ -22,6 +22,7 @@ module GHC.CmmToAsm.PPC.Instr , patchJumpInstr , patchRegsOfInstr , jumpDestsOfInstr + , canFallthroughTo , takeRegRegMoveInstr , takeDeltaInstr , mkRegRegMoveInstr @@ -509,6 +510,13 @@ isJumpishInstr instr JMP{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo instr bid + = case instr of + BCC _ target _ -> target == bid + BCCFAR _ target _ -> target == bid + _ -> False + -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the ===================================== compiler/GHC/CmmToAsm/Reg/Liveness.hs ===================================== @@ -126,6 +126,11 @@ instance Instruction instr => Instruction (InstrSR instr) where Instr instr -> isJumpishInstr instr _ -> False + canFallthroughTo i bid + = case i of + Instr instr -> canFallthroughTo instr bid + _ -> False + jumpDestsOfInstr i = case i of Instr instr -> jumpDestsOfInstr instr ===================================== compiler/GHC/CmmToAsm/X86.hs ===================================== @@ -51,6 +51,7 @@ instance Instruction X86.Instr where patchRegsOfInstr = X86.patchRegsOfInstr isJumpishInstr = X86.isJumpishInstr jumpDestsOfInstr = X86.jumpDestsOfInstr + canFallthroughTo = X86.canFallthroughTo patchJumpInstr = X86.patchJumpInstr mkSpillInstr = X86.mkSpillInstr mkLoadInstr = X86.mkLoadInstr ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -31,6 +31,7 @@ module GHC.CmmToAsm.X86.Instr , mkSpillInstr , mkRegRegMoveInstr , jumpDestsOfInstr + , canFallthroughTo , patchRegsOfInstr , patchJumpInstr , isMetaInstr @@ -669,6 +670,17 @@ isJumpishInstr instr CALL{} -> True _ -> False +canFallthroughTo :: Instr -> BlockId -> Bool +canFallthroughTo insn bid + = case insn of + JXX _ target -> bid == target + JMP_TBL _ targets _ _ -> all isTargetBid targets + _ -> False + where + isTargetBid target = case target of + Nothing -> True + Just (DestBlockId target) -> target == bid + _ -> False jumpDestsOfInstr :: Instr ===================================== testsuite/tests/codeGen/should_run/T24507.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} + +module Main where + +import GHC.Exts + +foreign import prim "foo" foo :: Int# -> Int# + +main = do + + let f x = case x of I# x' -> case foo x' of x -> print (I# x) + mapM_ f [1..7] \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/T24507.stdout ===================================== @@ -0,0 +1,7 @@ +1 +2 +2 +2 +2 +2 +2 ===================================== testsuite/tests/codeGen/should_run/T24507_cmm.cmm ===================================== @@ -0,0 +1,35 @@ +#include "Cmm.h" + +bar() { + return (2); +} + +foo(W_ x) { + + switch(x) { + case 1: goto a; + case 2: goto b; + case 3: goto c; + case 4: goto d; + case 5: goto e; + case 6: goto f; + case 7: goto g; + } + return (1); + + a: + return (1); + b: + jump bar(); + c: + jump bar(); + d: + jump bar(); + e: + jump bar(); + f: + jump bar(); + g: + jump bar(); + +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fe2b410ac0d8951f07ffcc9f3c6c97bc312df48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fe2b410ac0d8951f07ffcc9f3c6c97bc312df48 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:11:29 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:11:29 -0400 Subject: [Git][ghc/ghc][master] Fix documentation preview from doc-tarball job Message-ID: <661f13b122bd7_2f0bc81f6e568134337@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 2 changed files: - .gitlab-ci.yml - distrib/mkDocs/mkDocs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -557,12 +557,17 @@ doc-tarball: LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" artifacts: + expose_as: "Documentation Preview" paths: - haddock.html.tar.xz + - docs/haddock/ - libraries.html.tar.xz + - docs/libraries/ - users_guide.html.tar.xz - - index.html - - "*.pdf" + - docs/users_guide/ + - docs/index.html + - Haddock.pdf + - users_guide.pdf script: - | mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ @@ -582,8 +587,8 @@ doc-tarball: fi - rm -Rf docs - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST + - mv docs/*.tar.xz docs/*.pdf . - ls -lh - - mv docs/*.tar.xz docs/index.html . hackage-doc-tarball: stage: packaging ===================================== distrib/mkDocs/mkDocs ===================================== @@ -43,7 +43,7 @@ do dir=${i%*/} tar -Jcf ../../../../../$dir.html.tar.xz $dir done -mv index.html ../../../../.. +mv index.html users_guide libraries ../../../../.. cd .. mv ./*.pdf ../../../.. || \ die "failed to find PDFs" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f99126a7b4991e777dbdb5baf029d452fa9d533 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f99126a7b4991e777dbdb5baf029d452fa9d533 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:12:20 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:12:20 -0400 Subject: [Git][ghc/ghc][master] rts: Ignore EINTR while polling in timerfd itimer implementation Message-ID: <661f13e4eb1a8_2f0bc81de48b4138925@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 1 changed file: - rts/posix/ticker/TimerFd.c Changes: ===================================== rts/posix/ticker/TimerFd.c ===================================== @@ -112,7 +112,12 @@ static void *itimer_thread_func(void *_handle_tick) TSAN_ANNOTATE_BENIGN_RACE(&exited, "itimer_thread_func"); while (!RELAXED_LOAD(&exited)) { if (poll(pollfds, 2, -1) == -1) { - sysErrorBelch("Ticker: poll failed: %s", strerror(errno)); + // While the RTS attempts to mask signals, some foreign libraries + // may rely on signal delivery may unmask them. Consequently we may + // see EINTR. See #24610. + if (errno != -EINTR) { + sysErrorBelch("Ticker: poll failed: %s", strerror(errno)); + } } // We check the pipe first, even though the timerfd may also have triggered. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a0642eada4086360b329dde07045661d90a495f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a0642eada4086360b329dde07045661d90a495f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:13:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:13:14 -0400 Subject: [Git][ghc/ghc][master] EPA: Add additional comments field to AnnsModule Message-ID: <661f141ac2d74_2f0bc81ca40bc14475d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 23 changed files: - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/parser/should_compile/T23315/T23315.stderr - testsuite/tests/printer/T18791.stderr - testsuite/tests/printer/Test20297.stdout - testsuite/tests/printer/Test24533.stdout - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs.hs ===================================== @@ -101,12 +101,14 @@ deriving instance Data (HsModule GhcPs) data AnnsModule = AnnsModule { am_main :: [AddEpAnn], - am_decls :: [TrailingAnn], - am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- End of file and end of prior token + am_decls :: [TrailingAnn], -- ^ Semis before the start of top decls + am_cs :: [LEpaComment], -- ^ Comments before start of top decl, + -- used in exact printing only + am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- ^ End of file and end of prior token } deriving (Data, Eq) instance NoAnn AnnsModule where - noAnn = AnnsModule [] [] Nothing + noAnn = AnnsModule [] [] [] Nothing instance Outputable (HsModule GhcPs) where ppr (HsModule { hsmodExt = XModulePs { hsmodHaddockModHeader = mbDoc } ===================================== compiler/GHC/Parser.y ===================================== @@ -881,7 +881,7 @@ signature :: { Located (HsModule GhcPs) } : 'signature' modid maybe_warning_pragma maybeexports 'where' body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs-> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnSignature $1, mj AnnWhere $5] (fstOf3 $6) Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnSignature $1, mj AnnWhere $5] (fstOf3 $6) [] Nothing) cs) (thdOf3 $6) $3 Nothing) (Just $2) $4 (fst $ sndOf3 $6) (snd $ sndOf3 $6))) @@ -891,7 +891,7 @@ module :: { Located (HsModule GhcPs) } : 'module' modid maybe_warning_pragma maybeexports 'where' body {% fileSrcSpan >>= \ loc -> acsFinal (\cs eof -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1, mj AnnWhere $5] (fstOf3 $6) eof) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1, mj AnnWhere $5] (fstOf3 $6) [] eof) cs) (thdOf3 $6) $3 Nothing) (Just $2) $4 (fst $ sndOf3 $6) (snd $ sndOf3 $6)) @@ -899,7 +899,7 @@ module :: { Located (HsModule GhcPs) } | body2 {% fileSrcSpan >>= \ loc -> acsFinal (\cs eof -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [] (fstOf3 $1) eof) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [] (fstOf3 $1) [] eof) cs) (thdOf3 $1) Nothing Nothing) Nothing Nothing (fst $ sndOf3 $1) (snd $ sndOf3 $1)))) } @@ -939,14 +939,14 @@ header :: { Located (HsModule GhcPs) } : 'module' modid maybe_warning_pragma maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] [] Nothing) cs) EpNoLayout $3 Nothing) (Just $2) $4 $6 [] ))) } | 'signature' modid maybe_warning_pragma maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] [] Nothing) cs) EpNoLayout $3 Nothing) (Just $2) $4 $6 [] ))) } ===================================== testsuite/tests/ghc-api/exactprint/T22919.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T22919.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T22919.hs:1:29-33 }))] [] + [] (Just ((,) { T22919.hs:3:1 } ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20239.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20239.hs:1:18-22 }))] [] + [] (Just ((,) { Test20239.hs:9:1 } @@ -200,7 +201,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:50 }) (EpaSpan { Test20239.hs:7:86 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:50 }) + (EpaSpan { Test20239.hs:7:86 })) (L (EpAnn (EpaSpan { Test20239.hs:7:51-85 }) @@ -269,7 +273,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:68 }) (EpaSpan { Test20239.hs:7:85 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:68 }) + (EpaSpan { Test20239.hs:7:85 })) (L (EpAnn (EpaSpan { Test20239.hs:7:69-84 }) @@ -334,7 +341,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:83 }) (EpaSpan { Test20239.hs:7:84 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:83 }) + (EpaSpan { Test20239.hs:7:84 })) (HsBoxedOrConstraintTuple) [])))))))))))))]) (Nothing)))]) ===================================== testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { ZeroWidthSemi.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { ZeroWidthSemi.hs:1:22-26 }))] [] + [] (Just ((,) { ZeroWidthSemi.hs:9:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T17544.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544.hs:3:15-19 }))] [] + [] (Just ((,) { T17544.hs:57:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T17544_kw.hs:11:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544_kw.hs:13:13-17 }))] [] + [] (Just ((,) { T17544_kw.hs:25:1 } @@ -227,7 +228,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T17544_kw.hs:19:18 }) (EpaSpan { T17544_kw.hs:19:19 })) + (AnnParen + AnnParens + (EpaSpan { T17544_kw.hs:19:18 }) + (EpaSpan { T17544_kw.hs:19:19 })) (HsBoxedOrConstraintTuple) [])))]) (L ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T24221.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T24221.hs:1:15-19 }))] [] + [] (Just ((,) { T24221.hs:43:4 } ===================================== testsuite/tests/module/mod185.stderr ===================================== @@ -8,6 +8,7 @@ (EpAnn (EpaSpan { mod185.hs:1:1 }) (AnnsModule + [] [] [] (Just ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { DumpParsedAst.hs:4:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAst.hs:4:22-26 }))] [] + [] (Just ((,) { DumpParsedAst.hs:26:1 } @@ -228,7 +229,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { DumpParsedAst.hs:9:16 }) (EpaSpan { DumpParsedAst.hs:9:18 })) + (AnnParen + AnnParensSquare + (EpaSpan { DumpParsedAst.hs:9:16 }) + (EpaSpan { DumpParsedAst.hs:9:18 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:9:17 }) @@ -315,7 +319,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:11:10 }) (EpaSpan { DumpParsedAst.hs:11:17 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:11:10 }) + (EpaSpan { DumpParsedAst.hs:11:17 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:11:11-16 }) @@ -410,7 +417,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:11:26 }) (EpaSpan { DumpParsedAst.hs:11:36 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:11:26 }) + (EpaSpan { DumpParsedAst.hs:11:36 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:11:27-35 }) @@ -555,7 +565,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { DumpParsedAst.hs:10:27 }) (EpaSpan { DumpParsedAst.hs:10:29 })) + (AnnParen + AnnParensSquare + (EpaSpan { DumpParsedAst.hs:10:27 }) + (EpaSpan { DumpParsedAst.hs:10:29 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:10:28 }) @@ -732,7 +745,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:15:25 }) (EpaSpan { DumpParsedAst.hs:15:29 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:15:25 }) + (EpaSpan { DumpParsedAst.hs:15:29 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:15:26-28 }) @@ -867,7 +883,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:17:17 }) (EpaSpan { DumpParsedAst.hs:17:27 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:17:17 }) + (EpaSpan { DumpParsedAst.hs:17:27 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:17:18-26 }) @@ -1460,7 +1479,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:22:22 }) (EpaSpan { DumpParsedAst.hs:22:37 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:22:22 }) + (EpaSpan { DumpParsedAst.hs:22:37 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:22:23-36 }) @@ -1567,7 +1589,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:22:42 }) (EpaSpan { DumpParsedAst.hs:22:52 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:22:42 }) + (EpaSpan { DumpParsedAst.hs:22:52 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:22:43-51 }) @@ -1688,7 +1713,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:23:10 }) (EpaSpan { DumpParsedAst.hs:23:34 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:23:10 }) + (EpaSpan { DumpParsedAst.hs:23:34 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:23:11-33 }) ===================================== testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { DumpParsedAstComments.hs:5:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAstComments.hs:5:30-34 }))] [] + [] (Just ((,) { DumpParsedAstComments.hs:20:1 } ===================================== testsuite/tests/parser/should_compile/DumpSemis.stderr ===================================== @@ -22,6 +22,7 @@ (EpaSpan { DumpSemis.hs:4:7 })) ,(AddSemiAnn (EpaSpan { DumpSemis.hs:4:8 }))] + [] (Just ((,) { DumpSemis.hs:46:1 } ===================================== testsuite/tests/parser/should_compile/KindSigs.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { KindSigs.hs:6:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { KindSigs.hs:6:17-21 }))] [] + [] (Just ((,) { KindSigs.hs:36:1 } ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T15323.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T15323.hs:3:15-19 }))] [] + [] (Just ((,) { T15323.hs:7:1 } @@ -163,7 +164,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { T15323.hs:6:31 }) (EpaSpan { T15323.hs:6:36 })) + (AnnParen + AnnParens + (EpaSpan { T15323.hs:6:31 }) + (EpaSpan { T15323.hs:6:36 })) (L (EpAnn (EpaSpan { T15323.hs:6:32-35 }) ===================================== testsuite/tests/parser/should_compile/T20452.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20452.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20452.hs:3:15-19 }))] [] + [] (Just ((,) { T20452.hs:10:1 } @@ -376,7 +377,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { T20452.hs:8:57 }) (EpaSpan { T20452.hs:8:74 })) + (AnnParen + AnnParensSquare + (EpaSpan { T20452.hs:8:57 }) + (EpaSpan { T20452.hs:8:74 })) (L (EpAnn (EpaSpan { T20452.hs:8:58-73 }) @@ -385,7 +389,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T20452.hs:8:58 }) (EpaSpan { T20452.hs:8:73 })) + (AnnParen + AnnParens + (EpaSpan { T20452.hs:8:58 }) + (EpaSpan { T20452.hs:8:73 })) (HsBoxedOrConstraintTuple) [(L (EpAnn @@ -585,7 +592,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { T20452.hs:9:57 }) (EpaSpan { T20452.hs:9:74 })) + (AnnParen + AnnParensSquare + (EpaSpan { T20452.hs:9:57 }) + (EpaSpan { T20452.hs:9:74 })) (L (EpAnn (EpaSpan { T20452.hs:9:58-73 }) @@ -594,7 +604,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T20452.hs:9:58 }) (EpaSpan { T20452.hs:9:73 })) + (AnnParen + AnnParens + (EpaSpan { T20452.hs:9:58 }) + (EpaSpan { T20452.hs:9:73 })) (HsBoxedOrConstraintTuple) [(L (EpAnn ===================================== testsuite/tests/parser/should_compile/T20718.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20718.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718.hs:3:15-19 }))] [] + [] (Just ((,) { T20718.hs:12:1 } ===================================== testsuite/tests/parser/should_compile/T20718b.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20718b.hs:4:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718b.hs:4:16-20 }))] [] + [] (Just ((,) { T20718b.hs:8:1 } ===================================== testsuite/tests/parser/should_compile/T20846.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20846.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20846.hs:1:15-19 }))] [] + [] (Just ((,) { T20846.hs:5:1 } ===================================== testsuite/tests/parser/should_compile/T23315/T23315.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnSignature (EpaSpan { T23315.hsig:1:1-9 })) ,(AddEpAnn AnnWhere (EpaSpan { T23315.hsig:1:18-22 }))] [] + [] (Nothing)) (EpaComments [])) @@ -94,7 +95,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T23315.hsig:3:6 }) (EpaSpan { T23315.hsig:3:7 })) + (AnnParen + AnnParens + (EpaSpan { T23315.hsig:3:6 }) + (EpaSpan { T23315.hsig:3:7 })) (HsBoxedOrConstraintTuple) [])))))))) ,(L ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T18791.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T18791.hs:2:15-19 }))] [] + [] (Just ((,) { T18791.hs:6:1 } ===================================== testsuite/tests/printer/Test20297.stdout ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20297.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.hs:2:18-22 }))] [] + [] (Just ((,) { Test20297.hs:12:1 } @@ -418,6 +419,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20297.ppr.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.ppr.hs:2:18-22 }))] [] + [] (Just ((,) { Test20297.ppr.hs:9:25 } ===================================== testsuite/tests/printer/Test24533.stdout ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test24533.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:2:18-22 }))] [] + [] (Just ((,) { Test24533.hs:17:1 } @@ -643,6 +644,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test24533.ppr.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test24533.ppr.hs:2:18-22 }))] [] + [] (Just ((,) { Test24533.ppr.hs:6:20 } ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -965,8 +965,10 @@ lepa k epAnn = fmap (\newAnns -> epAnn { anns = newAnns }) -- data AnnsModule -- = AnnsModule { --- am_main :: [AddEpAnn], --- am_decls :: AnnList +-- am_main :: [AddEpAnn], +-- am_decls :: [TrailingAnn], +-- am_cs :: [LEpaComment], +-- am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- } deriving (Data, Eq) lam_main :: Lens AnnsModule [AddEpAnn] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a53cd3fde89fb10599604e8d5c9127077eb0572 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a53cd3fde89fb10599604e8d5c9127077eb0572 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:14:02 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:14:02 -0400 Subject: [Git][ghc/ghc][master] Remove unrunnable FreeBSD CI jobs Message-ID: <661f144ab9a3b_2f0bc8279e0e41478b9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 2 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -995,7 +995,6 @@ job_groups = , fastCI (standardBuildsWithConfig Amd64 Windows vanilla) , disableValidate (standardBuildsWithConfig Amd64 Windows nativeInt) , addValidateRule TestPrimops (standardBuilds Amd64 Darwin) - , allowFailureGroup (onlyRule FreeBSDLabel (validateBuilds Amd64 FreeBSD13 vanilla)) , fastCI (standardBuilds AArch64 Darwin) , fastCI (standardBuildsWithConfig AArch64 (Linux Debian10) (splitSectionsBroken vanilla)) , disableValidate (standardBuildsWithConfig AArch64 (Linux Debian11) (splitSectionsBroken vanilla)) ===================================== .gitlab/jobs.yaml ===================================== @@ -695,70 +695,6 @@ "ac_cv_func_utimensat": "no" } }, - "nightly-x86_64-freebsd13-validate": { - "after_script": [ - ".gitlab/ci.sh save_cache", - ".gitlab/ci.sh save_test_output", - ".gitlab/ci.sh clean", - "cat ci_timings" - ], - "allow_failure": true, - "artifacts": { - "expire_in": "8 weeks", - "paths": [ - "ghc-x86_64-freebsd13-validate.tar.xz", - "junit.xml", - "unexpected-test-output.tar.gz" - ], - "reports": { - "junit": "junit.xml" - }, - "when": "always" - }, - "cache": { - "key": "x86_64-freebsd13-$CACHE_REV", - "paths": [ - "cabal-cache", - "toolchain" - ] - }, - "dependencies": [], - "image": null, - "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } - ], - "rules": [ - { - "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", - "when": "on_success" - } - ], - "script": [ - ".gitlab/ci.sh setup", - ".gitlab/ci.sh configure", - ".gitlab/ci.sh build_hadrian", - ".gitlab/ci.sh test_hadrian" - ], - "stage": "full-build", - "tags": [ - "x86_64-freebsd13" - ], - "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate", - "BUILD_FLAVOUR": "validate", - "CABAL_INSTALL_VERSION": "3.10.2.0", - "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib --enable-strict-ghc-toolchain-check", - "GHC_VERSION": "9.6.4", - "HADRIAN_ARGS": "--docs=no-sphinx", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-freebsd13-validate", - "XZ_OPT": "-9" - } - }, "nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", @@ -4466,69 +4402,6 @@ "ac_cv_func_utimensat": "no" } }, - "x86_64-freebsd13-validate": { - "after_script": [ - ".gitlab/ci.sh save_cache", - ".gitlab/ci.sh save_test_output", - ".gitlab/ci.sh clean", - "cat ci_timings" - ], - "allow_failure": true, - "artifacts": { - "expire_in": "2 weeks", - "paths": [ - "ghc-x86_64-freebsd13-validate.tar.xz", - "junit.xml", - "unexpected-test-output.tar.gz" - ], - "reports": { - "junit": "junit.xml" - }, - "when": "always" - }, - "cache": { - "key": "x86_64-freebsd13-$CACHE_REV", - "paths": [ - "cabal-cache", - "toolchain" - ] - }, - "dependencies": [], - "image": null, - "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } - ], - "rules": [ - { - "if": "(($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", - "when": "on_success" - } - ], - "script": [ - ".gitlab/ci.sh setup", - ".gitlab/ci.sh configure", - ".gitlab/ci.sh build_hadrian", - ".gitlab/ci.sh test_hadrian" - ], - "stage": "full-build", - "tags": [ - "x86_64-freebsd13" - ], - "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate", - "BUILD_FLAVOUR": "validate", - "CABAL_INSTALL_VERSION": "3.10.2.0", - "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib --enable-strict-ghc-toolchain-check", - "GHC_VERSION": "9.6.4", - "HADRIAN_ARGS": "--docs=no-sphinx", - "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-freebsd13-validate" - } - }, "x86_64-linux-alpine3_12-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5c43259005b09999db4376e200945093cc79b35 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5c43259005b09999db4376e200945093cc79b35 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:14:27 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:14:27 -0400 Subject: [Git][ghc/ghc][master] rel-eng: Fix mktemp usage in recompress-all Message-ID: <661f1463b7ed2_2f0bc82a93f881480c2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - 1 changed file: - .gitlab/rel_eng/recompress-all Changes: ===================================== .gitlab/rel_eng/recompress-all ===================================== @@ -21,7 +21,7 @@ usage : %.zip : %.tar.xz echo "[tarxz->zip] $< to $@..." - tmp="$$(mktemp tmp.XXX)" && \ + tmp="$$(mktemp -d tmp.XXX)" && \ tar -C "$$tmp" -xf $< && \ cd "$$tmp" && \ zip -9 -r $@ * && \ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/914eb49a0637ef12c3f7db71c9da93c05389497b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/914eb49a0637ef12c3f7db71c9da93c05389497b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:14:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:14:52 -0400 Subject: [Git][ghc/ghc][master] Fix ghc API link in docs/index.html Message-ID: <661f147cad023_2f0bc823da7dc149973@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - 2 changed files: - docs/index.html.in - hadrian/src/Rules/Generate.hs Changes: ===================================== docs/index.html.in ===================================== @@ -39,7 +39,7 @@

  • - GHC API + GHC API

    Documentation for the GHC API. ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -360,7 +360,7 @@ templateRules = do , interpolateSetting "ProjectPatchLevel1" ProjectPatchLevel1 , interpolateSetting "ProjectPatchLevel2" ProjectPatchLevel2 ] - templateRule "docs/index.html" $ packageVersions + templateRule "docs/index.html" $ packageUnitIds Stage1 templateRule "docs/users_guide/ghc_config.py" $ mconcat [ projectVersion , packageUnitIds Stage1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f30e4984fb048818051465698ef8e4e20dacb577 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f30e4984fb048818051465698ef8e4e20dacb577 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 00:15:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 16 Apr 2024 20:15:14 -0400 Subject: [Git][ghc/ghc][master] template-haskell: Declare TH.Lib.Internal as not-home Message-ID: <661f149267645_2f0bc82bf14341515c0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 1 changed file: - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -1,4 +1,4 @@ -{-# OPTIONS_HADDOCK hide #-} +{-# OPTIONS_HADDOCK not-home #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7a3d6b5ee5e0c16af295579da3c54d8f0c37a05 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7a3d6b5ee5e0c16af295579da3c54d8f0c37a05 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 02:40:40 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 16 Apr 2024 22:40:40 -0400 Subject: [Git][ghc/ghc][wip/az/epa-list-syntax] 13 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <661f36a8dc746_4a90a92502c55371@gitlab.mail> Ben Gamari pushed to branch wip/az/epa-list-syntax at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 496d262d by Alan Zimmerman at 2024-04-16T22:40:34-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - distrib/mkDocs/mkDocs - docs/index.html.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fd836fdb0248f4a2a7a6682ca1410a19187fa540...496d262da3ea0f344a9f8847fb203e22a6d62aed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fd836fdb0248f4a2a7a6682ca1410a19187fa540...496d262da3ea0f344a9f8847fb203e22a6d62aed You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 07:26:29 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 17 Apr 2024 03:26:29 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 2 commits: Add some tests to check for size of interface files when serialising Message-ID: <661f79a5ee9b_4a90a2ea8ee87303a@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 30ecc6d2 by Matthew Pickering at 2024-04-17T09:21:50+02:00 Add some tests to check for size of interface files when serialising various types - - - - - 481d625b by Fendor at 2024-04-17T09:21:50+02:00 Implement TrieMap for IfaceType - - - - - 14 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/ghc.cabal.in - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Utils.Outputable import qualified Data.Map as Map import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import GHC.Types.Literal (Literal) {- This module implements TrieMaps over Core related data structures @@ -128,6 +129,8 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX +type LiteralMap = Map.Map Literal + -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. data CoreMapX a ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -13,8 +13,6 @@ module GHC.Data.TrieMap( MaybeMap, -- * Maps over 'List' values ListMap, - -- * Maps over 'Literal's - LiteralMap, -- * 'TrieMap' class TrieMap(..), insertTM, deleteTM, foldMapTM, isEmptyTM, @@ -30,7 +28,6 @@ module GHC.Data.TrieMap( import GHC.Prelude -import GHC.Types.Literal import GHC.Types.Unique.DFM import GHC.Types.Unique( Uniquable ) @@ -39,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -343,15 +342,87 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } -{- -************************************************************************ -* * - Basic maps -* * -************************************************************************ --} +{- Composition -} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} -type LiteralMap a = Map.Map Literal a {- ************************************************************************ ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -113,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -109,6 +109,8 @@ import GHC.Core.Map.Expr import GHC.Data.TrieMap import GHC.Types.Name.Env import Control.Monad( (>=>) ) +import qualified Data.Map as Map +import GHC.Types.Literal ( Literal ) -------------- -- The Trie -- @@ -122,6 +124,8 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } +type LiteralMap = Map.Map Literal + -- TODO(22292): derive instance Functor StgArgMap where fmap f SAM { sam_var = varm, sam_lit = litm } = SAM ===================================== compiler/ghc.cabal.in ===================================== @@ -579,6 +579,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkVisFunTyMany` wordTy `mkVisFunTyMany` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/418133a9b6252d6501759a9d0d0de27b6786e183...481d625b1a5fa5cd1ba9d0f4487b4a128badfa20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/418133a9b6252d6501759a9d0d0de27b6786e183...481d625b1a5fa5cd1ba9d0f4487b4a128badfa20 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 08:50:24 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 17 Apr 2024 04:50:24 -0400 Subject: [Git][ghc/ghc][wip/az/epa-list-syntax] EPA: Fix comments in mkListSyntaxTy0 Message-ID: <661f8d50cd921_3e818f2cd60c7856a@gitlab.mail> Alan Zimmerman pushed to branch wip/az/epa-list-syntax at Glasgow Haskell Compiler / GHC Commits: e35171ba by Alan Zimmerman at 2024-04-17T09:49:56+01:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 3 changed files: - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e35171badc482e4f901da351f638ce44e98704c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e35171badc482e4f901da351f638ce44e98704c2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 09:10:44 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 05:10:44 -0400 Subject: [Git][ghc/ghc][wip/T24624] 113 commits: docs: Remove mention of non-existent Ord instance for Complex Message-ID: <661f92142439b_3e818f52b2a0814a2@gitlab.mail> Teo Camarasu pushed to branch wip/T24624 at Glasgow Haskell Compiler / GHC Commits: 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - af17cdb5 by Teo Camarasu at 2024-04-17T10:10:34+01:00 wip - - - - - 22 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ad03706bbac5111d818e6f039d749a94755259c0...af17cdb5e51a6cbc5e51831add4c5d0fd5fe3730 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ad03706bbac5111d818e6f039d749a94755259c0...af17cdb5e51a6cbc5e51831add4c5d0fd5fe3730 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 09:12:27 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 05:12:27 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24652 Message-ID: <661f927b5e51e_3e818f68dcc4836fa@gitlab.mail> Teo Camarasu pushed new branch wip/T24652 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24652 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 09:20:52 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 05:20:52 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <661f9474a89da_3e818f7f2b64854a4@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 53b9a3eb by Teo Camarasu at 2024-04-17T10:20:43+01:00 Remove unecessary stage0 packages - - - - - 1 changed file: - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,30 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +134,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +151,16 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53b9a3eb90f4e68cd7a5850925ba3c0230d3135b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53b9a3eb90f4e68cd7a5850925ba3c0230d3135b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 10:06:00 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 06:06:00 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <661f9f08b25fe_3e818fd20ac890114@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 4b14ca09 by Teo Camarasu at 2024-04-17T11:05:51+01:00 Remove unecessary stage0 packages - - - - - 1 changed file: - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,31 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +135,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +152,16 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b14ca092505d87681378c73d4bf3845a61a0201 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b14ca092505d87681378c73d4bf3845a61a0201 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 10:15:42 2024 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Wed, 17 Apr 2024 06:15:42 -0400 Subject: [Git][ghc/ghc][wip/T23764] 13 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <661fa14e27c48_3e818ff1a400921a5@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23764 at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 47b0cf3d by Krzysztof Gogolewski at 2024-04-17T12:15:29+02:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/HsType.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - distrib/mkDocs/mkDocs - docs/index.html.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ac379264956df89db32abc5f2a2bb89cf92ab6e9...47b0cf3d3947b59e04a32e123ae75545fae3adae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ac379264956df89db32abc5f2a2bb89cf92ab6e9...47b0cf3d3947b59e04a32e123ae75545fae3adae You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 10:40:01 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 17 Apr 2024 06:40:01 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <661fa7011d8a0_3e818f1272f80100357@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: e6558ece by Sebastian Graf at 2024-04-17T12:39:41+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 26 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - + testsuite/tests/dmdanal/should_run/T24124b.hs - testsuite/tests/dmdanal/should_run/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/simplStg/should_compile/T15226b.stderr Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_MAGIC (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -159,19 +159,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -306,6 +306,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -596,7 +603,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -649,7 +656,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -681,7 +688,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -843,13 +850,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 ty alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 ty alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -938,14 +955,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -987,7 +1004,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1006,9 +1023,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1021,7 +1038,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1031,7 +1048,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1057,24 +1074,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1121,13 +1153,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1183,13 +1215,13 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1198,10 +1230,10 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1481,20 +1513,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1672,7 +1710,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1704,6 +1742,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1817,6 +1900,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -1983,23 +2069,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2017,6 +2123,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2049,7 +2156,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2510,7 +2617,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2237,8 +2238,95 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -24,7 +26,7 @@ -- ----------------------------------------------------------------------------- -module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..) ) where +module GHC.Magic ( inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) ) where -------------------------------------------------- -- See Note [magicIds] in GHC.Types.Id.Make @@ -58,8 +60,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +81,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. @@ -119,6 +122,20 @@ runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). {-# NOINLINE runRW# #-} -- runRW# is inlined manually in CorePrep runRW# m = m realWorld# +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy lazy a in (# s, a' #) + -- Why `lazy lazy`? Because lazy is defined in this same module and DmdAnal + -- will infer its own, strict demand signature for its RHS instead of using + -- the signature attached to wired-in Id. Since lazy is NOINLINE, the + -- second-order call `lazy lazy` will obscure the definition. + -- Alternatives: (1) put seq# into a different module, or + -- (2) handle lazy specially during Demand Analysis + -- | @'dataToTag#'@ evaluates its argument and returns the index -- (starting at zero) of the constructor used to produce that -- argument. Any algebraic data type with all of its constructors ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,36 @@ +{-# LANGUAGE MagicHash #-} + +import GHC.Exts +import Debug.Trace +import GHC.IO +import GHC.ST + +data StrictPair a b = !a :*: !b + +strictFun :: Int -> Int +{-# OPAQUE strictFun #-} +strictFun x = x*x*x + +opaqueId :: a -> a +{-# OPAQUE opaqueId #-} +{-# RULES + "opaqueId/noinline" opaqueId = noinline +#-} +-- work around noinline's special desugaring +opaqueId v = v + +evaluateST :: a -> ST s a +-- hide the fact that we are actually in IO because !11515 +-- causes seq# to look like it can throw precise exceptions +evaluateST x = ST (\s -> seq# x s) + +fun :: Int -> Int -> ST s Int +{-# OPAQUE fun #-} +fun = lazy $ \ !x y -> do + -- This should evaluate x before y. + _ <- evaluateST $ opaqueId (x :*: x) + _ <- evaluateST y + evaluateST $! strictFun x + +main :: IO () +main = () <$ stToIO (fun (trace "x eval'd" 12) (trace "y eval'd" 13)) ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,3 +4,4 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile_and_run, ['-O']) ===================================== testsuite/tests/dmdanal/should_run/T24124b.hs ===================================== @@ -0,0 +1,9 @@ +import Control.Exception + +f :: Int -> Int -> IO Int +f x y = do + evaluate x + pure $! y + 1 +{-# NOINLINE f #-} + +main = f (error "should see this") (error "should not see this") >> pure () ===================================== testsuite/tests/dmdanal/should_run/all.T ===================================== @@ -33,3 +33,5 @@ test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) +# T24124b: Do not make f strict. But semantics of seq# is broken; need strictnessBarrier +test('T24124b', [expect_broken(22935), exit_code(1)], compile_and_run, ['']) ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -17,23 +17,23 @@ T15226b.testFun1 -> b -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=<1L><1L>, Cpr=1(, 1), Unf=OtherCon []] = {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> let { sat [Occ=Once1] :: T15226b.StrictPair a b [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.MkStrictPair! [sat conrep]; + } in (# #) [sat]; + }; }; T15226b.testFun :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = +[GblId, Arity=3, Str=<1L><1L>, Cpr=1(, 1), Unf=OtherCon []] = {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; T15226b.MkStrictPair [InlPrag=CONLIKE] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6558ece95c090a0f69e03099422e2df885188a5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6558ece95c090a0f69e03099422e2df885188a5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 10:44:05 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 17 Apr 2024 06:44:05 -0400 Subject: [Git][ghc/ghc][wip/T24124] 26 commits: users-guide: Clarify language extension documentation Message-ID: <661fa7f569aaa_3e818f13bf514105412@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - acd61f22 by Sebastian Graf at 2024-04-17T12:43:53+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6558ece95c090a0f69e03099422e2df885188a5...acd61f227cbce5b7c927c90c77351de1c2ad23e7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6558ece95c090a0f69e03099422e2df885188a5...acd61f227cbce5b7c927c90c77351de1c2ad23e7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 11:00:25 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 17 Apr 2024 07:00:25 -0400 Subject: [Git][ghc/ghc][wip/T23109] 40 commits: Validate -main-is flag using parseIdentifier Message-ID: <661fabc947cb1_3e818f17079b01139db@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 1837d5ad by Simon Peyton Jones at 2024-04-17T11:08:15+01:00 Make newtype instances opaque I think this will help with #23109 Wibbles Allow SelCo for newtype classes Experimental change Wibble Furher wibbles Further improvments Further wibbles esp exprIsConLike Run classop rule first Newtype classops are small needs comments - - - - - 41ec5dd0 by Simon Peyton Jones at 2024-04-17T11:08:15+01:00 Wibble imports - - - - - d5c5b53b by Simon Peyton Jones at 2024-04-17T11:08:15+01:00 Wibbles Notably: define and use mkNewTypeDictApp - - - - - f1e2ce82 by Simon Peyton Jones at 2024-04-17T11:08:15+01:00 Make newtype-class data constructors not inline This variant tries * Making the data constructor for a newtype class not inline * exprIsConApp_maybe treats it like a normal data constructor * CoreToStg discards it (perhaps CorePrep should do that instead) * Some as-it-turns-out unforced changes to corePrepPgm that makes it pass all TyCons, not just the data tycons * Significantly simpler story in mkNewTypeDictApp - - - - - 1ae368e5 by Simon Peyton Jones at 2024-04-17T11:08:15+01:00 Wibble - - - - - 9858b1d4 by Simon Peyton Jones at 2024-04-17T11:10:18+01:00 Get rid of newtype classes in CorePrep not CoreToStg - - - - - 0893dd69 by Simon Peyton Jones at 2024-04-17T11:10:18+01:00 SetLevels Experimental: don't float constants, except to top level - - - - - 4f68cc63 by Simon Peyton Jones at 2024-04-17T11:56:25+01:00 Comment out bits that I think are no longer necessary * Extra field in ClassOpId, and classOpDictApp_maybe in Simplify.Iteration * Newtype classes being injective * Don't preInlineUnconditionally Dfuns * mkNewTypeDictApp * Zonking of unfoldings (only necessary for those local dfuns) - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00d4ce0ac8bfc70c8b512995cd2caa71a9eb0542...4f68cc63bf34fc9c81bbfd75b47e39fe45355d87 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00d4ce0ac8bfc70c8b512995cd2caa71a9eb0542...4f68cc63bf34fc9c81bbfd75b47e39fe45355d87 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 11:45:21 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 17 Apr 2024 07:45:21 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hadrian-cabal-fixes Message-ID: <661fb65164c24_3e818f1e68a88120583@gitlab.mail> Matthew Pickering pushed new branch wip/hadrian-cabal-fixes at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hadrian-cabal-fixes You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 12:05:45 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 17 Apr 2024 08:05:45 -0400 Subject: [Git][ghc/ghc][wip/T23109] Wibble Message-ID: <661fbb19b8ce6_3e818f20c7a901222ea@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: d344c88e by Simon Peyton Jones at 2024-04-17T13:05:35+01:00 Wibble - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify/Iteration.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -16,7 +16,7 @@ import GHC.Prelude import GHC.Driver.Flags import GHC.Core -import GHC.Core.Class( Class, classArity ) +-- import GHC.Core.Class( Class, classArity ) import GHC.Core.Opt.Simplify.Monad import GHC.Core.Opt.ConstantFold import GHC.Core.Type hiding ( substCo, substTy, substTyVar, extendTvSubst, extendCvSubst ) @@ -65,7 +65,7 @@ import GHC.Builtin.Names( runRWKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString -import GHC.Data.List.SetOps( getNth ) +-- import GHC.Data.List.SetOps( getNth ) import GHC.Unit.Module ( moduleName ) import GHC.Utils.Outputable import GHC.Utils.Panic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d344c88ebc5d2fb245143d2aa6056e8f767d07be -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d344c88ebc5d2fb245143d2aa6056e8f767d07be You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 13:04:36 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 17 Apr 2024 09:04:36 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 5 commits: Add Eq and Ord instance to `IfaceType` Message-ID: <661fc8e48159a_3e818f29b0d8c1350a1@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 8dbbdbbc by Fendor at 2024-04-17T09:31:43+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - e927c278 by Fendor at 2024-04-17T10:09:52+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 96c88b75 by Matthew Pickering at 2024-04-17T10:30:02+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 1c5e7698 by Matthew Pickering at 2024-04-17T10:34:55+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 890e5b5a by Fendor at 2024-04-17T10:39:58+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/481d625b1a5fa5cd1ba9d0f4487b4a128badfa20...890e5b5a7d58793a7232bbf9f2eb44aae5e7f74a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/481d625b1a5fa5cd1ba9d0f4487b4a128badfa20...890e5b5a7d58793a7232bbf9f2eb44aae5e7f74a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 13:13:38 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 17 Apr 2024 09:13:38 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] 213 commits: rts: expose HeapAlloc.h as public header Message-ID: <661fcb0215f28_3e818f2b60e48135328@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 4c03f294 by Andreas Klebinger at 2024-04-17T14:58:39+02:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - f63fe011 by Andreas Klebinger at 2024-04-17T14:58:40+02:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/default.nix - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - + .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a90d1ba4341adc16c2a1804ebfea3fdd56298eb6...f63fe011548ea1d54ffcf77a6682ef91d3af778a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a90d1ba4341adc16c2a1804ebfea3fdd56298eb6...f63fe011548ea1d54ffcf77a6682ef91d3af778a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 13:41:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 17 Apr 2024 09:41:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <661fd176e9b66_3e818f3035e3c138916@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: 49e49baa by Fendor at 2024-04-17T14:28:17+02:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 19763aca by Fendor at 2024-04-17T14:28:21+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. - - - - - 3 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - testsuite/tests/perf/compiler/all.T Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,10 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesDefs + '$(TEST_HC)' $(TEST_HC_OPTS) -fwrite-if-simplified-core -v0 MultiLayerModules.hs + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['../../ghci/shell.hs', 'genMultiLayerModulesDefs', 'MultiLayerModulesDefsGhci.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core') + ], + ghci_script, + ['MultiLayerModulesDefsGhci.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/125db4c4624aa0904a66253864b538eecf5d6f3f...19763aca6f2ae3246f741647180b690a52ebc32d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/125db4c4624aa0904a66253864b538eecf5d6f3f...19763aca6f2ae3246f741647180b690a52ebc32d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 14:41:03 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 10:41:03 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <661fdf7fea062_3e818f3809c80150951@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 9753bd03 by Teo Camarasu at 2024-04-17T15:39:16+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. In particular `os-string` is a new package and hence isn't bundled with boot compilers. Once that becomes widespread we can remove even more! Resolves #24652 - - - - - 1 changed file: - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,31 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +135,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +152,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9753bd0395057f4a3b53c2b2475c2594c5e630d8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9753bd0395057f4a3b53c2b2475c2594c5e630d8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 14:49:40 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 17 Apr 2024 10:49:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: Make template-haskell a stage1 package Message-ID: <661fe1844ffa8_3e818f3980f001543ae@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - e35171ba by Alan Zimmerman at 2024-04-17T09:49:56+01:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 61fa7878 by Serge S. Gulin at 2024-04-17T10:49:33-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/ghc.cabal.in - distrib/mkDocs/mkDocs - docs/index.html.in - hadrian/src/Packages.hs - hadrian/src/Rules/Dependencies.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7d067fc444c4ef58cb2090450d992c5470b55b2a...61fa78789fd549e5bb282f9757e549209da3a366 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7d067fc444c4ef58cb2090450d992c5470b55b2a...61fa78789fd549e5bb282f9757e549209da3a366 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 14:59:56 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 17 Apr 2024 10:59:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24686 Message-ID: <661fe3ec24ea7_3e818f3c5ace41598a7@gitlab.mail> Simon Peyton Jones pushed new branch wip/T24686 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24686 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 15:01:58 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 17 Apr 2024 11:01:58 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] 27 commits: users-guide: Clarify language extension documentation Message-ID: <661fe466e6c4a_3e818f3cf6b1c1600e5@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 094524d7 by Simon Peyton Jones at 2024-04-17T13:07:39+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. I also found a big change in the (very delicate) test perf/should_run/T21839r when I was fiddling with something else; this MR made a big difference. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - ab4f78cd by Matthew Pickering at 2024-04-17T13:07:39+01:00 Simon patch test - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Module.hs - compiler/GHC/StgToCmm/Config.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bfd4ae4e616c374fe4981a5a61bfb9f9a51621f...ab4f78cd224b4c042cac8f5ef8d5a7db9b1f4a74 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bfd4ae4e616c374fe4981a5a61bfb9f9a51621f...ab4f78cd224b4c042cac8f5ef8d5a7db9b1f4a74 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 15:54:22 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 17 Apr 2024 11:54:22 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <661ff0aec7567_3e818f461e2d0170038@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: f503b3d2 by Sebastian Graf at 2024-04-17T17:53:59+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 27 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - + testsuite/tests/simplStg/should_compile/T24124.hs - + testsuite/tests/simplStg/should_compile/T24124.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2175,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2208,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2707,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2235,8 +2236,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,15 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -58,8 +60,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +81,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- tag inference should not insert an eval for x' in making the strict pair ===================================== testsuite/tests/simplStg/should_compile/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,7 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f503b3d2c75081c98cbd391fd51ab6b9ad5ebceb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f503b3d2c75081c98cbd391fd51ab6b9ad5ebceb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 16:41:44 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 17 Apr 2024 12:41:44 -0400 Subject: [Git][ghc/ghc][wip/fendor/iface-sharing] 8 commits: Refactor the Binary serialisation interface Message-ID: <661ffbc8b5502_3e818f4ce9ab01751d9@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/iface-sharing at Glasgow Haskell Compiler / GHC Commits: a46734e8 by Fendor at 2024-04-16T12:33:49+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - 442649b4 by Fendor at 2024-04-16T12:33:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 8dbbdbbc by Fendor at 2024-04-17T09:31:43+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - e927c278 by Fendor at 2024-04-17T10:09:52+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - 96c88b75 by Matthew Pickering at 2024-04-17T10:30:02+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 1c5e7698 by Matthew Pickering at 2024-04-17T10:34:55+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 890e5b5a by Fendor at 2024-04-17T10:39:58+02:00 Implement TrieMap for IfaceType - - - - - 578f15ac by Fendor at 2024-04-17T18:41:32+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5077818d5893f5ab5e58bd06306faa59b54c1c5...578f15ac1b3991706a55c717b8d9973409b695b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5077818d5893f5ab5e58bd06306faa59b54c1c5...578f15ac1b3991706a55c717b8d9973409b695b2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 17:12:43 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 17 Apr 2024 13:12:43 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <6620030af09c6_2112621c79ec41244@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 68660919 by Teo Camarasu at 2024-04-17T18:12:27+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. Resolves #24652 - - - - - 1 changed file: - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,26 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers , unlit - , hp2ps - , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +129,16 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq + , directory , exceptions + , filepath , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +148,18 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , osString + , parsec , pretty + , process , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68660919434500b90564e391f54af26808938a63 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68660919434500b90564e391f54af26808938a63 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 19:10:14 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 17 Apr 2024 15:10:14 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <66201e96df329_211262f8c0dc6658b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 68407bf5 by Matthew Pickering at 2024-04-17T15:09:56-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 0104eea4 by Alan Zimmerman at 2024-04-17T15:09:57-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 308b6351 by Serge S. Gulin at 2024-04-17T15:10:01-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 8 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Parser/PostProcess.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61fa78789fd549e5bb282f9757e549209da3a366...308b6351ae88af870fa4b1adbffbcc3ab5e25319 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61fa78789fd549e5bb282f9757e549209da3a366...308b6351ae88af870fa4b1adbffbcc3ab5e25319 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 19:34:18 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 17 Apr 2024 15:34:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-patbind-span Message-ID: <6620243a8843c_211262135dc9c7363b@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-patbind-span at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-patbind-span You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 19:38:53 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 17 Apr 2024 15:38:53 -0400 Subject: [Git][ghc/ghc][wip/az/epa-patbind-span] EPA: Provide correct span for PatBind Message-ID: <6620254dc530f_2112621435a0c7695d@gitlab.mail> Alan Zimmerman pushed to branch wip/az/epa-patbind-span at Glasgow Haskell Compiler / GHC Commits: c2df9183 by Alan Zimmerman at 2024-04-17T20:35:50+01:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 6 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2df9183d8ddd2184735d1ed3611460df1477790 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2df9183d8ddd2184735d1ed3611460df1477790 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 17 21:51:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 17 Apr 2024 17:51:00 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662044441f11_21126222d7b0093938@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2953909f by Matthew Pickering at 2024-04-17T17:50:39-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - b31f2675 by Alan Zimmerman at 2024-04-17T17:50:40-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 5a11fb07 by Serge S. Gulin at 2024-04-17T17:50:44-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 8 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Parser/PostProcess.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/308b6351ae88af870fa4b1adbffbcc3ab5e25319...5a11fb0789df91bfb52432ba313abb1fbd920d8e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/308b6351ae88af870fa4b1adbffbcc3ab5e25319...5a11fb0789df91bfb52432ba313abb1fbd920d8e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 00:41:24 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 17 Apr 2024 20:41:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <66206c345ddd4_1c3c808dee74219f4@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 715ffb80 by Matthew Pickering at 2024-04-17T20:41:02-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - b63e724c by Alan Zimmerman at 2024-04-17T20:41:02-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b38aa6a3 by Serge S. Gulin at 2024-04-17T20:41:06-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 8 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Parser/PostProcess.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5a11fb0789df91bfb52432ba313abb1fbd920d8e...b38aa6a35dabe1b37423d7938d3811cf40f956a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5a11fb0789df91bfb52432ba313abb1fbd920d8e...b38aa6a35dabe1b37423d7938d3811cf40f956a3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 06:42:24 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 18 Apr 2024 02:42:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <6620c0d02d3b9_1c3c803795394514aa@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3bc1a060 by Matthew Pickering at 2024-04-18T02:41:57-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 8329aeeb by Alan Zimmerman at 2024-04-18T02:41:58-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - d858d29d by Serge S. Gulin at 2024-04-18T02:42:02-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 8 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Parser/PostProcess.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b38aa6a35dabe1b37423d7938d3811cf40f956a3...d858d29de674dc3fedd505be23ffb6e42f646b77 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b38aa6a35dabe1b37423d7938d3811cf40f956a3...d858d29de674dc3fedd505be23ffb6e42f646b77 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 09:09:21 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 05:09:21 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <6620e341825d3_8f78a4ef5e86424c@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 10dc184c by Teo Camarasu at 2024-04-18T10:09:14+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,17 +132,9 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath - , osString -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot @@ -157,15 +149,10 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec - , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable - ] ++ if windowsHost then [ win32 ] else [ unix ] + ] -- | Create a mapping from files to which component it belongs to. dirMap :: Action [(FilePath, (Package, [String]))] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,26 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers , unlit - , hp2ps - , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +129,16 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq + , directory , exceptions + , filepath , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +148,18 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , osString + , parsec , pretty + , process , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10dc184cef5ed87137a234b2588192646e41c281 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10dc184cef5ed87137a234b2588192646e41c281 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 09:24:19 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 18 Apr 2024 05:24:19 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <6620e6c313101_8f78a8546fc7448e@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: b3fce09d by Sebastian Graf at 2024-04-18T11:23:56+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - + testsuite/tests/simplStg/should_compile/T24124.hs - + testsuite/tests/simplStg/should_compile/T24124.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2175,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2208,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2707,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2235,8 +2236,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,15 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -58,8 +60,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +81,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -4584,7 +4584,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- tag inference should not insert an eval for x' in making the strict pair ===================================== testsuite/tests/simplStg/should_compile/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,7 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3fce09d889e156d7ec83684bf7c9d298136bf9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3fce09d889e156d7ec83684bf7c9d298136bf9a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 10:22:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 18 Apr 2024 06:22:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <6620f47c251e9_8f78a12cb93c93796@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e1fbb34f by Matthew Pickering at 2024-04-18T06:22:25-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - b51469e3 by Jade at 2024-04-18T06:22:26-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - fad2bd46 by Alan Zimmerman at 2024-04-18T06:22:26-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - f58154ad by Serge S. Gulin at 2024-04-18T06:22:30-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 768d72be by Alan Zimmerman at 2024-04-18T06:22:31-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Logger.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T9140.stdout - testsuite/tests/layout/layout001.stdout - testsuite/tests/layout/layout003.stdout - testsuite/tests/layout/layout004.stdout - testsuite/tests/layout/layout006.stdout - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout - testsuite/tests/overloadedrecflds/ghci/T19314.stdout - testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/rename/should_compile/T13839.stdout - testsuite/tests/th/T7276a.stdout - testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3317,12 +3316,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3361,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== compiler/GHC/Utils/Logger.hs ===================================== @@ -417,14 +417,13 @@ defaultLogAction logflags msg_class srcSpan msg message = mkLocMessageWarningGroups (log_show_warn_groups logflags) msg_class srcSpan msg printDiagnostics = do - hPutChar stderr '\n' caretDiagnostic <- if log_show_caret logflags then getCaretDiagnostic msg_class srcSpan else pure empty printErrs $ getPprStyle $ \style -> withPprStyle (setStyleColoured True style) - (message $+$ caretDiagnostic) + (message $+$ caretDiagnostic $+$ blankLine) -- careful (#2302): printErrs prints in UTF-8, -- whereas converting to string first and using -- hPutStr would just emit the low 8 bits of ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/ghci/prog018/prog018.stdout ===================================== @@ -1,7 +1,6 @@ [1 of 3] Compiling A ( A.hs, interpreted ) [2 of 3] Compiling B ( B.hs, interpreted ) [3 of 3] Compiling C ( C.hs, interpreted ) - A.hs:5:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)] Pattern match(es) are non-exhaustive In an equation for ‘incompletePattern’: @@ -17,9 +16,10 @@ B.hs:7:1: warning: [GHC-66111] [-Wunused-imports (in -Wextra)] C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules loaded. [3 of 3] Compiling C ( C.hs, interpreted ) - C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules reloaded. ===================================== testsuite/tests/ghci/scripts/T9140.stdout ===================================== @@ -1,4 +1,3 @@ - :2:5: error: [GHC-20036] You can't mix polymorphic and unlifted bindings: a = (# 1 #) Suggested fix: Add a type signature. @@ -10,3 +9,4 @@ :1:1: error: [GHC-17999] GHCi can't bind a variable of unlifted type: a :: (# Integer, Integer #) + ===================================== testsuite/tests/layout/layout001.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout001.hs:6:3: error: [GHC-58481] parse error on input ‘where’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout001.hs:6:3: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `where' clause at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout003.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout003.hs:11:4: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout003.hs:11:4: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout004.stdout ===================================== @@ -1,7 +1,7 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ + ===================================== testsuite/tests/layout/layout006.stdout ===================================== @@ -1,13 +1,12 @@ Running with -XNoAlternativeLayoutRule - layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... -Running with -XAlternativeLayoutRule +Running with -XAlternativeLayoutRule layout006.hs:12:2: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block @@ -15,3 +14,4 @@ layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... + ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout ===================================== @@ -1,10 +1,10 @@ GHCiDRF.foo :: T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to either the field ‘bar’ of record ‘T’, defined at GHCiDRF.hs:3:28, or the field ‘bar’ of record ‘U’, defined at GHCiDRF.hs:4:16. + type T :: * data T = MkT {foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -16,7 +16,6 @@ type U :: * data U = MkU {bar :: Bool} -- Defined at GHCiDRF.hs:4:16 GHCiDRF.foo :: GHCiDRF.T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -26,6 +25,7 @@ GHCiDRF.foo :: GHCiDRF.T -> Int or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + type GHCiDRF.T :: * data GHCiDRF.T = GHCiDRF.MkT {GHCiDRF.foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -36,7 +36,6 @@ data GHCiDRF.T = GHCiDRF.MkT {..., GHCiDRF.bar :: Int} type GHCiDRF.U :: * data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} -- Defined at GHCiDRF.hs:4:16 - :11:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -46,3 +45,4 @@ data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + ===================================== testsuite/tests/overloadedrecflds/ghci/T19314.stdout ===================================== @@ -1,6 +1,5 @@ w :: [a] -> a x :: [a] -> a - :1:1: error: [GHC-88464] Variable not in scope: y Suggested fix: @@ -12,3 +11,4 @@ x :: [a] -> a Suggested fix: Notice that ‘z’ is a field selector that has been suppressed by NoFieldSelectors. + ===================================== testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout ===================================== @@ -7,7 +7,6 @@ type T :: * -> * data T a = MkT {foo :: Bool, ...} -- Defined at :4:18 True - :1:1: error: [GHC-87543] Ambiguous occurrence ‘foo’. It could refer to @@ -15,6 +14,7 @@ True defined at :3:16, or the field ‘foo’ of record ‘T’, defined at :4:18. + type U :: * data U = MkU {foo :: Int} -- Defined at :12:16 ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + ===================================== testsuite/tests/rename/should_compile/T13839.stdout ===================================== @@ -1,5 +1,5 @@ - T13839a.hs:10:1: warning: [GHC-40910] [-Wunused-top-binds (in -Wextra, -Wunused-binds)] Defined but not used: ‘nonUsed’ + nonUsed :: () nonUsed :: () ===================================== testsuite/tests/th/T7276a.stdout ===================================== @@ -1,4 +1,3 @@ - :3:9: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] • Couldn't match type ‘[Dec]’ with ‘Exp’ Expected: Q Exp @@ -17,3 +16,4 @@ (deferred type error) Code: x • In the untyped splice: $x + ===================================== testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr ===================================== @@ -1,4 +1,3 @@ - CaretDiagnostics1.hs:7:8-15: error: [GHC-83865] • Couldn't match expected type ‘IO a0’ with actual type ‘Int’ • In the second argument of ‘(+)’, namely ‘(3 :: Int)’ @@ -68,3 +67,4 @@ CaretDiagnostics1.hs:23:25-26: error: [GHC-83865] | 23 | tabby2 = () | ^^ + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d858d29de674dc3fedd505be23ffb6e42f646b77...768d72be838231114737a91f9aaa7c8481f2b895 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d858d29de674dc3fedd505be23ffb6e42f646b77...768d72be838231114737a91f9aaa7c8481f2b895 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 10:41:56 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 18 Apr 2024 06:41:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24436 Message-ID: <6620f8f4ad3d3_8f78a1610c28105191@gitlab.mail> Matthew Pickering pushed new branch wip/T24436 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24436 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 10:50:24 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 06:50:24 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <6620faf0f1533_8f78a1795f0811039d@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 673bb991 by Teo Camarasu at 2024-04-18T11:50:15+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,17 +132,9 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath - , osString -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot @@ -157,15 +149,12 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec - , time , templateHaskellNext - , text - , transformers , semaphoreCompat + , time -- depends on win32 , unlit -- # executable - ] ++ if windowsHost then [ win32 ] else [ unix ] + , if windowsHost then win32 else unix + ] -- | Create a mapping from files to which component it belongs to. dirMap :: Action [(FilePath, (Package, [String]))] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,27 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +131,16 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq + , directory , exceptions + , filepath , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +150,18 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , osString + , parsec , pretty + , process , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/673bb9916a84c5a451057ce7c81a12cb04e3056e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/673bb9916a84c5a451057ce7c81a12cb04e3056e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 11:09:49 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 18 Apr 2024 07:09:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hadrian-cabal-register Message-ID: <6620ff7da60a1_8f78a1a6350011111d@gitlab.mail> Matthew Pickering pushed new branch wip/hadrian-cabal-register at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hadrian-cabal-register You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 12:03:09 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 18 Apr 2024 08:03:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/arm_mem_model Message-ID: <66210bfd5dcd_8f78a211040c113737@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/arm_mem_model at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/arm_mem_model You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 12:41:42 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 18 Apr 2024 08:41:42 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <662115063080c_8f78a263b47c1203b4@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: 6e096064 by Sebastian Graf at 2024-04-18T14:41:20+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - + testsuite/tests/simplStg/should_compile/T24124.hs - + testsuite/tests/simplStg/should_compile/T24124.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) = False -- 3. in the Note + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,43 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. +Unfortunately, today it breaks T24124. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2175,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2208,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2707,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,11 +157,12 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The three remaining identifiers in GHC.Magic, runRW#, seq# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. + Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] inline: see Note [inlineId magic] -} @@ -2235,8 +2236,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,15 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate', but is subject to +-- breaking changes. For example, this magic Id used to live in "GHC.Prim". +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -58,8 +60,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +81,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,2 @@ +x eval'd +y eval'd ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6655,7 +6655,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -4584,7 +4584,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6835,7 +6835,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- tag inference should not insert an eval for x' in making the strict pair ===================================== testsuite/tests/simplStg/should_compile/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,7 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e0960648b9690814ab4d5d10b2d3021469290bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e0960648b9690814ab4d5d10b2d3021469290bd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 12:43:21 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 18 Apr 2024 08:43:21 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <662115693f157_8f78a2710280120934@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: c6e1bbf1 by Fendor at 2024-04-18T14:39:36+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - 6df52a0a by Fendor at 2024-04-18T14:39:59+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -81,7 +81,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -99,7 +99,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +103,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +141,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +174,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +277,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +301,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +363,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +400,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +416,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +437,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +459,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +497,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +510,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +522,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +543,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +569,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +594,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +618,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +646,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1065,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1129,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1147,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1168,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1400,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1434,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1481,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit edf742131e272fc29c6d6eae549b0fe37eea11b9 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/442649b4850b72557dff661089cf5c26bdc5a6fb...6df52a0a6b51fa42349855b6556162f2b9cadc1f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/442649b4850b72557dff661089cf5c26bdc5a6fb...6df52a0a6b51fa42349855b6556162f2b9cadc1f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 13:35:53 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Thu, 18 Apr 2024 09:35:53 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <662121b9876fb_8f78a3057820132686@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: dc750e4b by Fendor at 2024-04-18T15:32:17+02:00 Add performance regression test for '-fwrite-simplified-core' - - - - - fdfdbbf4 by Fendor at 2024-04-18T15:34:33+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. - - - - - 5 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of modules with $WIDTH modules on each layer +# Every module on layer N imports all the modules on layer N-1 +# Each module has $DEFS definitions in +# MultiLayerModules.hs imports all the modules from the last layer +WIDTH=10 +DEFS=100 +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + for k in $(seq -w 1 $DEFS); do + echo "a_${i}_${k} = ${i} + ${k}" >> DummyLevel$i.hs; + done +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19763aca6f2ae3246f741647180b690a52ebc32d...fdfdbbf49e1218cea5633ec76131c9072e957b48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19763aca6f2ae3246f741647180b690a52ebc32d...fdfdbbf49e1218cea5633ec76131c9072e957b48 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 13:40:53 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 18 Apr 2024 09:40:53 -0400 Subject: [Git][ghc/ghc][wip/T24686] Fix missing escaping-kind check in tcPatSynSig Message-ID: <662122e593b89_8f78a3198a7c13293f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24686 at Glasgow Haskell Compiler / GHC Commits: 094b31fa by Simon Peyton Jones at 2024-04-18T14:40:17+01:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. - - - - - 5 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - testsuite/tests/polykinds/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module RepPolyNoPanic where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined + ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,4 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/094b31fa22b76db258db1075b4e8bc44cd49f4fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/094b31fa22b76db258db1075b4e8bc44cd49f4fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 13:43:49 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 09:43:49 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <662123952cc56_8f78a327f88c1347d8@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 845e99bb by Teo Camarasu at 2024-04-18T14:43:42+01:00 Remove unecessary stage0 packages - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,17 +132,9 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath - , osString -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot @@ -157,12 +149,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,31 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +135,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +152,16 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/845e99bb83c3db4f7af83f314a64a4f105185f4e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/845e99bb83c3db4f7af83f314a64a4f105185f4e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 13:52:58 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 09:52:58 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <662125ba6f8f2_8f78a36694d41385d2@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 31a71e2e by Teo Camarasu at 2024-04-18T14:52:49+01:00 Remove unecessary stage0 packages - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,17 +132,9 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath - , osString -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot @@ -157,15 +149,10 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec - , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable - ] ++ if windowsHost then [ win32 ] else [ unix ] + ] ++ if windowsHost then [ time, win32 ] else [ ] -- | Create a mapping from files to which component it belongs to. dirMap :: Action [(FilePath, (Package, [String]))] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,43 +80,30 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers , unlit - , hp2ps - , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] - ++ [ timeout | windowsHost ] + ++ [ time | windowsHost ] + ++ [ timeout | windowsHost ] -- | Packages built in 'Stage1' by default. You can change this in "UserSettings". stage1Packages :: Action [Package] @@ -143,12 +130,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +147,16 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31a71e2e8999ecf39a210d0bd8dd48c9fbbae791 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31a71e2e8999ecf39a210d0bd8dd48c9fbbae791 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 13:58:17 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 18 Apr 2024 09:58:17 -0400 Subject: [Git][ghc/ghc][wip/set-levels-hnfs] Do not float HNFs out of lambdas Message-ID: <662126f92d6eb_8f78a37dac8c14068e@gitlab.mail> Simon Peyton Jones pushed to branch wip/set-levels-hnfs at Glasgow Haskell Compiler / GHC Commits: 1b04603e by Simon Peyton Jones at 2024-04-18T14:56:38+01:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - 3 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,105 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1, SW2). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top]. Bottom line (data from !12410): adding the + not.exprIsHNF test to `saves_work`: + - Decreases compiler allocations by 0.5% + - Occasionally decreases runtime allocation (T12996 -2.5%) + - Slightly mixed effect on nofib: (puzzle -10%, mate -5%, cichelli +5%) + but geometric mean is -0.09%. + Overall, a win. + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1200,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b04603e9d6a374a9828369ca2e1139e1c40ac68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b04603e9d6a374a9828369ca2e1139e1c40ac68 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 14:23:23 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 10:23:23 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <66212cdb69f3a_3750a1375168171bb@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: dbab59a6 by Teo Camarasu at 2024-04-18T15:23:12+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. In particular `os-string` is a new package and hence isn't bundled with boot compilers. Once that becomes widespread we can remove even more! Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,15 +132,11 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers , directory , process - , exceptions , filepath , osString -- , ghc -- # depends on ghc library @@ -157,12 +153,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,31 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec - , semaphoreCompat - , time + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc + , semaphoreCompat -- depends on win32 , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +135,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +152,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbab59a68521119831c63afa55056bead5adf67b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbab59a68521119831c63afa55056bead5adf67b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 14:24:53 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 18 Apr 2024 10:24:53 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <66212d3579499_3750a1431458177dd@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: eb140592 by Teo Camarasu at 2024-04-18T15:23:25+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,15 +132,11 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers , directory , process - , exceptions , filepath , osString -- , ghc -- # depends on ghc library @@ -157,12 +153,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,39 +80,31 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec - , semaphoreCompat - , time + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc + , semaphoreCompat -- depends on win32 , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] @@ -143,12 +135,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +152,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb1405923de55472e6c3b352249fe01caa3277fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb1405923de55472e6c3b352249fe01caa3277fe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 14:43:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 18 Apr 2024 10:43:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662131a167c5e_3750a170b78c203b6@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fa2afc44 by Matthew Pickering at 2024-04-18T10:43:18-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - c03cc26d by Jade at 2024-04-18T10:43:19-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - ea0bee47 by Alan Zimmerman at 2024-04-18T10:43:19-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 19bb3c2b by Serge S. Gulin at 2024-04-18T10:43:23-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 442955ca by Alan Zimmerman at 2024-04-18T10:43:24-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Logger.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T9140.stdout - testsuite/tests/layout/layout001.stdout - testsuite/tests/layout/layout003.stdout - testsuite/tests/layout/layout004.stdout - testsuite/tests/layout/layout006.stdout - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout - testsuite/tests/overloadedrecflds/ghci/T19314.stdout - testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/rename/should_compile/T13839.stdout - testsuite/tests/th/T7276a.stdout - testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3317,12 +3316,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3361,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== compiler/GHC/Utils/Logger.hs ===================================== @@ -417,14 +417,13 @@ defaultLogAction logflags msg_class srcSpan msg message = mkLocMessageWarningGroups (log_show_warn_groups logflags) msg_class srcSpan msg printDiagnostics = do - hPutChar stderr '\n' caretDiagnostic <- if log_show_caret logflags then getCaretDiagnostic msg_class srcSpan else pure empty printErrs $ getPprStyle $ \style -> withPprStyle (setStyleColoured True style) - (message $+$ caretDiagnostic) + (message $+$ caretDiagnostic $+$ blankLine) -- careful (#2302): printErrs prints in UTF-8, -- whereas converting to string first and using -- hPutStr would just emit the low 8 bits of ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/ghci/prog018/prog018.stdout ===================================== @@ -1,7 +1,6 @@ [1 of 3] Compiling A ( A.hs, interpreted ) [2 of 3] Compiling B ( B.hs, interpreted ) [3 of 3] Compiling C ( C.hs, interpreted ) - A.hs:5:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)] Pattern match(es) are non-exhaustive In an equation for ‘incompletePattern’: @@ -17,9 +16,10 @@ B.hs:7:1: warning: [GHC-66111] [-Wunused-imports (in -Wextra)] C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules loaded. [3 of 3] Compiling C ( C.hs, interpreted ) - C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules reloaded. ===================================== testsuite/tests/ghci/scripts/T9140.stdout ===================================== @@ -1,4 +1,3 @@ - :2:5: error: [GHC-20036] You can't mix polymorphic and unlifted bindings: a = (# 1 #) Suggested fix: Add a type signature. @@ -10,3 +9,4 @@ :1:1: error: [GHC-17999] GHCi can't bind a variable of unlifted type: a :: (# Integer, Integer #) + ===================================== testsuite/tests/layout/layout001.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout001.hs:6:3: error: [GHC-58481] parse error on input ‘where’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout001.hs:6:3: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `where' clause at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout003.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout003.hs:11:4: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout003.hs:11:4: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout004.stdout ===================================== @@ -1,7 +1,7 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ + ===================================== testsuite/tests/layout/layout006.stdout ===================================== @@ -1,13 +1,12 @@ Running with -XNoAlternativeLayoutRule - layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... -Running with -XAlternativeLayoutRule +Running with -XAlternativeLayoutRule layout006.hs:12:2: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block @@ -15,3 +14,4 @@ layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... + ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout ===================================== @@ -1,10 +1,10 @@ GHCiDRF.foo :: T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to either the field ‘bar’ of record ‘T’, defined at GHCiDRF.hs:3:28, or the field ‘bar’ of record ‘U’, defined at GHCiDRF.hs:4:16. + type T :: * data T = MkT {foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -16,7 +16,6 @@ type U :: * data U = MkU {bar :: Bool} -- Defined at GHCiDRF.hs:4:16 GHCiDRF.foo :: GHCiDRF.T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -26,6 +25,7 @@ GHCiDRF.foo :: GHCiDRF.T -> Int or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + type GHCiDRF.T :: * data GHCiDRF.T = GHCiDRF.MkT {GHCiDRF.foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -36,7 +36,6 @@ data GHCiDRF.T = GHCiDRF.MkT {..., GHCiDRF.bar :: Int} type GHCiDRF.U :: * data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} -- Defined at GHCiDRF.hs:4:16 - :11:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -46,3 +45,4 @@ data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + ===================================== testsuite/tests/overloadedrecflds/ghci/T19314.stdout ===================================== @@ -1,6 +1,5 @@ w :: [a] -> a x :: [a] -> a - :1:1: error: [GHC-88464] Variable not in scope: y Suggested fix: @@ -12,3 +11,4 @@ x :: [a] -> a Suggested fix: Notice that ‘z’ is a field selector that has been suppressed by NoFieldSelectors. + ===================================== testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout ===================================== @@ -7,7 +7,6 @@ type T :: * -> * data T a = MkT {foo :: Bool, ...} -- Defined at :4:18 True - :1:1: error: [GHC-87543] Ambiguous occurrence ‘foo’. It could refer to @@ -15,6 +14,7 @@ True defined at :3:16, or the field ‘foo’ of record ‘T’, defined at :4:18. + type U :: * data U = MkU {foo :: Int} -- Defined at :12:16 ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + ===================================== testsuite/tests/rename/should_compile/T13839.stdout ===================================== @@ -1,5 +1,5 @@ - T13839a.hs:10:1: warning: [GHC-40910] [-Wunused-top-binds (in -Wextra, -Wunused-binds)] Defined but not used: ‘nonUsed’ + nonUsed :: () nonUsed :: () ===================================== testsuite/tests/th/T7276a.stdout ===================================== @@ -1,4 +1,3 @@ - :3:9: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] • Couldn't match type ‘[Dec]’ with ‘Exp’ Expected: Q Exp @@ -17,3 +16,4 @@ (deferred type error) Code: x • In the untyped splice: $x + ===================================== testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr ===================================== @@ -1,4 +1,3 @@ - CaretDiagnostics1.hs:7:8-15: error: [GHC-83865] • Couldn't match expected type ‘IO a0’ with actual type ‘Int’ • In the second argument of ‘(+)’, namely ‘(3 :: Int)’ @@ -68,3 +67,4 @@ CaretDiagnostics1.hs:23:25-26: error: [GHC-83865] | 23 | tabby2 = () | ^^ + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/768d72be838231114737a91f9aaa7c8481f2b895...442955cae72c5e1b4985621ee2d2792868e3198f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/768d72be838231114737a91f9aaa7c8481f2b895...442955cae72c5e1b4985621ee2d2792868e3198f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 15:26:35 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 18 Apr 2024 11:26:35 -0400 Subject: [Git][ghc/ghc][wip/T23109] Allow pushDataCon on ClassTyCon newtypes Message-ID: <66213bab65326_3750a1d8b648298c@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 45c567cd by Simon Peyton Jones at 2024-04-18T16:24:35+01:00 Allow pushDataCon on ClassTyCon newtypes The fact that there is no *actual* data constructor in the end i kind-of-irrelevant, and we turn out to get quite a lot of class-op (d |> co) where co : C t1 ~R C t2 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Arity.hs Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -3065,6 +3065,8 @@ push_dc_gen dc dc_args co (Pair from_ty to_ty) -- where S is a type function. In fact, exprIsConApp -- will probably not be called in such circumstances, -- but there's nothing wrong with it + = Just (push_data_con to_tc to_tc_arg_tys dc dc_args co Representational) +{- = case isSubCo_maybe co of Just co' -> Just (push_data_con to_tc to_tc_arg_tys dc dc_args co' Nominal) _ | isInjectiveTyCon to_tc Representational @@ -3076,6 +3078,7 @@ push_dc_gen dc dc_args co (Pair from_ty to_ty) -- , text "of type:" <+> ppr (coercionType co) , text "role:" <+> ppr (coercionRole co) ]) Nothing +-} | otherwise = Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45c567cde6ccc0d22a706a427089c157add1949b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45c567cde6ccc0d22a706a427089c157add1949b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 19:44:16 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 18 Apr 2024 15:44:16 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662178101a258_33e8a687c4e054987@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 38e721fb by Matthew Pickering at 2024-04-18T15:43:49-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - d6298789 by Alan Zimmerman at 2024-04-18T15:43:50-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 380f08ab by Serge S. Gulin at 2024-04-18T15:43:55-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 92a14a49 by Alan Zimmerman at 2024-04-18T15:43:55-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 13 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3317,12 +3316,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3361,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/442955cae72c5e1b4985621ee2d2792868e3198f...92a14a49f94a0d6838617dd97668597b372653d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/442955cae72c5e1b4985621ee2d2792868e3198f...92a14a49f94a0d6838617dd97668597b372653d6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 21:15:23 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 18 Apr 2024 17:15:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T8671 Message-ID: <66218d6b18ad9_bfc5740dcec32930@gitlab.mail> Apoorv Ingle pushed new branch wip/T8671 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T8671 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 21:22:07 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 18 Apr 2024 17:22:07 -0400 Subject: [Git][ghc/ghc][wip/T8671] Suppresses spurious warnings generated for do-body statements that Message-ID: <66218effbccd5_bfc575c0cec347b1@gitlab.mail> Apoorv Ingle pushed to branch wip/T8671 at Glasgow Haskell Compiler / GHC Commits: 2ef26d79 by Apoorv Ingle at 2024-04-18T16:21:46-05:00 Suppresses spurious warnings generated for do-body statements that in really do not discard anything. This improves usability of RebindableSyntax and Qualified Do. Fixes: #8671 - - - - - 8 changed files: - compiler/GHC/HsToCore/Expr.hs - + testsuite/tests/qualifieddo/should_compile/T8671a.hs - + testsuite/tests/qualifieddo/should_compile/T8671adefs.hs - + testsuite/tests/qualifieddo/should_compile/T8671b.hs - + testsuite/tests/qualifieddo/should_compile/T8671bdefs.hs - testsuite/tests/qualifieddo/should_compile/all.T - + testsuite/tests/rebindable/T8671.hs - testsuite/tests/rebindable/all.T Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -978,8 +978,11 @@ warnDiscardedDoBindings rhs rhs_ty do { fam_inst_envs <- dsGetFamInstEnvs ; let norm_elt_ty = topNormaliseType fam_inst_envs elt_ty - -- Warn about discarding non-() things in 'monadic' binding - ; if warn_unused && not (isUnitTy norm_elt_ty) + -- Warn about discarding non-() things in 'monadic' binding + -- We also check that the type is not empty via `isEmptyTy` as + -- there may be non-unit but empty types which we can suppress spurious discard warnings + -- See #8671 and tests T8671.hs, T8671a.hs, T8671b.hs + ; if warn_unused && not (isUnitTy norm_elt_ty) && not (isEmptyTy norm_elt_ty) then diagnosticDs (DsUnusedDoBind rhs elt_ty) else ===================================== testsuite/tests/qualifieddo/should_compile/T8671a.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE QualifiedDo #-} +{-# OPTIONS_GHC "-Wunused-do-bind" #-} + +module Example where + +import T8671adefs qualified as Q + +example :: Q.NotMonad 2 +example = Q.do + Q.incr + Q.incr ===================================== testsuite/tests/qualifieddo/should_compile/T8671adefs.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE DataKinds #-} + +module T8671adefs where + +import GHC.TypeLits + +-- Not actually a useful thing, but illustrates the point +data NotMonad (t :: Nat) + +incr :: NotMonad 1 +incr = undefined + +(>>) :: NotMonad s -> NotMonad t -> NotMonad (s + t) +(>>) = undefined ===================================== testsuite/tests/qualifieddo/should_compile/T8671b.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE QualifiedDo #-} +{-# OPTIONS_GHC "-Wunused-do-bind" #-} + +module Example where + +import T8671bdefs qualified as Q + +example :: Q.NotMonad Bool +example = Q.do + Q.bool 1 2 + Q.bool 3 4 ===================================== testsuite/tests/qualifieddo/should_compile/T8671bdefs.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} + +module T8671bdefs where + + +data NotMonad t = NotMonad + {unNotMonad :: t -> Int} + +run :: t -> NotMonad t -> Int +run t (NotMonad f) = f t + +(>>) :: NotMonad t -> NotMonad t -> NotMonad t +NotMonad l >> NotMonad r = NotMonad $ \t -> l t + r t + +bool :: Int -> Int -> NotMonad Bool +bool t f = NotMonad (\b -> if b then t else f) ===================================== testsuite/tests/qualifieddo/should_compile/all.T ===================================== @@ -1,4 +1,7 @@ setTestOpts(only_ways(['normal'])); +# qextra_files = extra_files(['T8671adefs.hs', 'T8671bdefs.hs']) test('qdocompile001', normal, compile, ['-v0 -ddump-rn -dsuppress-uniques']) test('qdocompile002', normal, compile, ['-v0']) +test('T8671a', normal, compile, ['--make -v0 -Wall -Wunused-do-bind -i./']) +test('T8671b', normal, compile, ['--make -v0 -Wall -Wunused-do-bind -i./']) \ No newline at end of file ===================================== testsuite/tests/rebindable/T8671.hs ===================================== @@ -0,0 +1,26 @@ +{-# LANGUAGE RebindableSyntax #-} + +module T8671 where + +import Data.Void +import Prelude ((.), ($), Int, id, Num(..)) + + +(>>) :: (b -> c) -> (a -> b) -> (a -> c) +(>>) = (.) + + +return :: Void -> Void +return = absurd + + +run :: a -> (a -> b) -> b +run x f = f x + + +result :: Int +result = run 8 $ do + \n -> n * n + id + (+ 7) + (* 2) ===================================== testsuite/tests/rebindable/all.T ===================================== @@ -46,3 +46,4 @@ test('T20126', normal, compile_fail, ['']) test('T23147', normal, compile, ['']) test('pattern-fails', normal, compile_and_run, ['']) test('simple-rec', normal, compile_and_run, ['']) +test('T8671', normal, compile, ['-v0 -Wall -Wunused-do-bind']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ef26d79110b1ef614bb235c5e8c30e36ff337c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ef26d79110b1ef614bb235c5e8c30e36ff337c0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 21:23:09 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Thu, 18 Apr 2024 17:23:09 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] 2 commits: EPA: Fix span for PatBuilderAppType Message-ID: <66218f3d1aa08_bfc576af98c35092@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: c922221d by Alan Zimmerman at 2024-04-15T22:06:44+01:00 EPA: Fix span for PatBuilderAppType Note: tests still need to be updated - - - - - 397f549b by Alan Zimmerman at 2024-04-18T22:22:21+01:00 EPA: Avoid duplicated comments in splice decls - - - - - 8 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/rename/should_fail/T17594b.stderr - testsuite/tests/typecheck/should_fail/T17594c.stderr - testsuite/tests/typecheck/should_fail/T17594d.stderr - testsuite/tests/typecheck/should_fail/T17594g.stderr Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -219,7 +219,7 @@ type instance XHsPS GhcPs = EpAnnCO type instance XHsPS GhcRn = HsPSRn type instance XHsPS GhcTc = HsPSRn -type instance XHsTP GhcPs = EpAnnCO +type instance XHsTP GhcPs = NoExtField type instance XHsTP GhcRn = HsTyPatRn type instance XHsTP GhcTc = DataConCantHappen @@ -295,9 +295,9 @@ mkHsPatSigType :: EpAnnCO -> LHsType GhcPs -> HsPatSigType GhcPs mkHsPatSigType ann x = HsPS { hsps_ext = ann , hsps_body = x } -mkHsTyPat :: EpAnnCO -> LHsType GhcPs -> HsTyPat GhcPs -mkHsTyPat ann x = HsTP { hstp_ext = ann - , hstp_body = x } +mkHsTyPat :: LHsType GhcPs -> HsTyPat GhcPs +mkHsTyPat x = HsTP { hstp_ext = noExtField + , hstp_body = x } mkEmptyWildCardBndrs :: thing -> HsWildCardBndrs GhcRn thing mkEmptyWildCardBndrs x = HsWC { hswc_body = x @@ -589,7 +589,7 @@ mkHsAppTys = foldl' mkHsAppTy mkHsAppKindTy :: XAppKindTy (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -mkHsAppKindTy x ty k = addCLocA ty k (HsAppKindTy x ty k) +mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) {- ************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -3401,7 +3401,7 @@ bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parse argpat :: { LPat GhcPs } argpat : apat { $1 } - | PREFIX_AT atype { L (getLocAnn (reLoc $2)) (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } + | PREFIX_AT atype { sLLa $1 $> (InvisPat (epTok $1) (mkHsTyPat $2)) } argpats :: { [LPat GhcPs] } : argpat argpats { $1 : $2 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -398,17 +398,14 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan @@ -1458,9 +1455,12 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L loc _)))) es ops cps - = go pat (L loc (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat + anc' = case tok of + NoEpTok -> anc + EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] go _ _ _ _ = return Nothing data ArgPatBuilder p @@ -1920,8 +1920,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) mkHsAppTypePV l p at t = do !cs <- getCommentsFor (locA l) - let anns = EpAnn (spanAsAnchor (getLocA t)) NoEpAnns cs - return $ L l (PatBuilderAppType p at (mkHsTyPat anns t)) + return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t)) mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar) @@ -1978,7 +1977,7 @@ instance DisambECP (PatBuilder GhcPs) where mkSumOrTuplePV = mkSumOrTuplePat mkHsEmbTyPV l toktype ty = return $ L (noAnnSrcSpan l) $ - PatBuilderPat (EmbTyPat toktype (mkHsTyPat noAnn ty)) + PatBuilderPat (EmbTyPat toktype (mkHsTyPat ty)) rejectPragmaPV _ = return () -- | Ensure that a literal pattern isn't of type Addr#, Float#, Double#. ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1446,7 +1446,7 @@ cvtp (ConP s ts ps) = do { s' <- cNameN s ; ps' <- cvtPats ps ; ts' <- mapM cvtType ts ; let pps = map (parenthesizePat appPrec) ps' - pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat noAnn t)) ts' + pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat t)) ts' ; return $ ConPat { pat_con_ext = noAnn , pat_con = s' @@ -1489,9 +1489,9 @@ cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noAnn e' p'} cvtp (TypeP t) = do { t' <- cvtType t - ; return $ EmbTyPat noAnn (mkHsTyPat noAnn t') } + ; return $ EmbTyPat noAnn (mkHsTyPat t') } cvtp (InvisP t) = do { t' <- cvtType t - ; pure (InvisPat noAnn (mkHsTyPat noAnn t'))} + ; pure (InvisPat noAnn (mkHsTyPat t'))} cvtPatFld :: (TH.Name, TH.Pat) -> CvtM (LHsRecField GhcPs (LPat GhcPs)) cvtPatFld (s,p) ===================================== testsuite/tests/rename/should_fail/T17594b.stderr ===================================== @@ -1,84 +1,84 @@ -T17594b.hs:7:6: error: [GHC-78249] +T17594b.hs:7:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:10:6: error: [GHC-78249] +T17594b.hs:10:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:14:6: error: [GHC-78249] +T17594b.hs:14:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:6: error: [GHC-78249] +T17594b.hs:17:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:10: error: [GHC-78249] +T17594b.hs:17:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:14: error: [GHC-78249] +T17594b.hs:17:13: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:27: error: [GHC-78249] +T17594b.hs:17:26: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:31: error: [GHC-78249] +T17594b.hs:17:30: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:35: error: [GHC-78249] +T17594b.hs:17:34: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:20:11: error: [GHC-78249] +T17594b.hs:20:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:22:20: error: [GHC-78249] +T17594b.hs:22:19: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:25:10: error: [GHC-78249] +T17594b.hs:25:9: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:6: error: [GHC-78249] +T17594b.hs:28:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:10: error: [GHC-78249] +T17594b.hs:28:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:32: error: [GHC-78249] +T17594b.hs:28:31: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:58: error: [GHC-78249] +T17594b.hs:28:57: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:62: error: [GHC-78249] +T17594b.hs:28:61: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:71: error: [GHC-78249] +T17594b.hs:28:70: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:31:11: error: [GHC-78249] +T17594b.hs:31:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:34:11: error: [GHC-78249] +T17594b.hs:34:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:37:7: error: [GHC-78249] +T17594b.hs:37:6: error: [GHC-78249] Illegal invisible type pattern: ($(TH.varT (TH.mkName "t"))) Suggested fix: Perhaps you intended to use TypeAbstractions ===================================== testsuite/tests/typecheck/should_fail/T17594c.stderr ===================================== @@ -1,5 +1,5 @@ -T17594c.hs:5:11: error: [GHC-14964] +T17594c.hs:5:10: error: [GHC-14964] • Invisible type pattern t has no associated forall • In the expression: \ @t -> undefined :: t In the expression: [\ @t -> undefined :: t] ===================================== testsuite/tests/typecheck/should_fail/T17594d.stderr ===================================== @@ -1,4 +1,4 @@ -T17594d.hs:8:6: error: [GHC-14964] +T17594d.hs:8:5: error: [GHC-14964] • Invisible type pattern t has no associated forall • In an equation for ‘id'’: id' @t x = x :: t ===================================== testsuite/tests/typecheck/should_fail/T17594g.stderr ===================================== @@ -1,4 +1,4 @@ -T17594g.hs:6:6: error: [GHC-14964] +T17594g.hs:6:5: error: [GHC-14964] • Invisible type pattern a has no associated forall • In an equation for ‘id'’: id' @a x = x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1eb1a5ae98ab32439870867dfd39d38b64bd6a6d...397f549b18ccfa679161fea7555afe519131e15c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1eb1a5ae98ab32439870867dfd39d38b64bd6a6d...397f549b18ccfa679161fea7555afe519131e15c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 22:27:55 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Thu, 18 Apr 2024 18:27:55 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-patbuilderapptype-span Message-ID: <66219e6b35ba5_bfc57ef7cd4415c2@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-patbuilderapptype-span at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-patbuilderapptype-span You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 23:17:53 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 18 Apr 2024 19:17:53 -0400 Subject: [Git][ghc/ghc][wip/T24676] First attempt at #24676 Message-ID: <6621aa2199ffc_bfc57156c7cc54114@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: 297971de by Simon Peyton Jones at 2024-04-19T00:17:26+01:00 First attempt at #24676 - - - - - 2 changed files: - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Tc/Gen/App.hs Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -29,6 +29,7 @@ module GHC.Core.TyCo.FVs -- Any and No Free vars anyFreeVarsOfType, anyFreeVarsOfTypes, anyFreeVarsOfCo, noFreeVarsOfType, noFreeVarsOfTypes, noFreeVarsOfCo, + anyFreeVarsOfTypeM, -- * Free type constructors tyConsOfType, tyConsOfTypes, @@ -58,7 +59,7 @@ import {-# SOURCE #-} GHC.Core.Coercion( coercionLKind ) import GHC.Builtin.Types.Prim( funTyFlagTyCon ) -import Data.Monoid as DM ( Endo(..), Any(..) ) +import Data.Monoid as DM ( Any(..) ) import GHC.Core.TyCo.Rep import GHC.Core.TyCon import GHC.Core.Coercion.Axiom( coAxiomTyCon ) @@ -74,6 +75,8 @@ import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Data.Pair +import Data.Semigroup + {- %************************************************************************ %* * @@ -974,6 +977,36 @@ noFreeVarsOfCo co = not $ DM.getAny (f co) where (_, _, f, _) = foldTyCo (afvFolder (const True)) emptyVarSet +{- ********************************************************************* +* * + Folding over free vars +* * +********************************************************************* -} + +newtype AnyM m = AM { unAnyM :: m Bool } + +instance Monad m => Semigroup (AnyM m) where + AM ml <> AM mr = AM (do { l <- ml; if l then return True else mr }) + +instance Monad m => Monoid (AnyM m) where + mempty = AM (return False) + +{-# INLINE afvFolderM #-} -- so that specialization to (const True) works +afvFolderM :: Monad m => (TyCoVar -> m Bool) -> TyCoFolder TyCoVarSet (AnyM m) +afvFolderM check_fv = TyCoFolder { tcf_view = noView + , tcf_tyvar = do_tv, tcf_covar = mempty + , tcf_hole = mempty, tcf_tycobinder = do_bndr } + where + do_bndr is tcv _ = extendVarSet is tcv + do_tv is tv | tv `elemVarSet` is = AM (return False) + | otherwise = AM (check_fv tv) + +anyFreeVarsOfTypeM :: Monad m => (TyCoVar -> m Bool) -> Type -> m Bool +-- Returns True if check_fv returns True of any free var of the type +anyFreeVarsOfTypeM check_fv ty = unAnyM (f ty) + where (f, _, _, _) = foldTyCo (afvFolderM check_fv) emptyVarSet + + {- ********************************************************************* * * scopedSort ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1472,7 +1472,7 @@ quickLookArg delta larg (Scaled _ arg_ty) where guarded = isGuardedTy arg_ty -- NB: guardedness is computed based on the original, - -- unzonked arg_ty (before calling `go`, so that we deliberately do + -- unzonked arg_ty (before calling `go`), so that we deliberately do -- not exploit guardedness that emerges a result of QL on earlier args go arg_ty | not (isRhoTy arg_ty) @@ -1499,11 +1499,15 @@ isGuardedTy ty quickLookArg1 :: Bool -> Delta -> LHsExpr GhcRn -> TcSigmaTypeFRR -> TcM (Delta, EValArg 'TcpInst) +-- quickLookArg1 implements the "QL Argument" judgement in Fig 5 of the paper quickLookArg1 guarded delta larg@(L _ arg) arg_ty = do { ((rn_fun, fun_ctxt), rn_args) <- splitHsApps arg + + -- Step 1: get the type of the head of the argument ; mb_fun_ty <- tcInferAppHead_maybe rn_fun ; traceTc "quickLookArg 1" $ vcat [ text "arg:" <+> ppr arg + , text "arg_ty:" <+> ppr arg_ty , text "head:" <+> ppr rn_fun <+> dcolon <+> ppr mb_fun_ty , text "args:" <+> ppr rn_args ] @@ -1511,8 +1515,10 @@ quickLookArg1 guarded delta larg@(L _ arg) arg_ty Nothing -> skipQuickLook delta larg ; -- fun is too complicated Just (tc_fun, fun_sigma) -> + -- Step 2: use |-inst to instantiate the head applied to the arguments do { do_ql <- wantQuickLook rn_fun ; (delta_app, inst_args, app_res_rho) <- tcInstFun do_ql True (tc_fun, fun_ctxt) fun_sigma rn_args + ; traceTc "quickLookArg 2" $ vcat [ text "arg:" <+> ppr arg , text "delta:" <+> ppr delta @@ -1520,36 +1526,44 @@ quickLookArg1 guarded delta larg@(L _ arg) arg_ty , text "arg_ty:" <+> ppr arg_ty , text "app_res_rho:" <+> ppr app_res_rho ] - -- Now check whether arg_ty is guar - ; let do_one :: TcTyVar -> TcM Bool -> TcM Bool - do_one tv do_rest = do { unfilled <- isUnfilledMetaTyVar tv - ; if unfilled then return False - else do_rest } - check_no_free_kappas :: Delta -> TcM Bool - check_no_free_kappas delta - = nonDetStrictFoldVarSet do_one (return True) delta - - ; can_do_ql <- if guarded + -- Step 3: check the two other premises of APP-lightning-bolt (Fig 5 in the paper) + -- Namely: (A) is rho guarded, and (B) fiv(rho_r) = emptyset + ; can_do_ql <- if guarded -- (A) then return True - else check_no_free_kappas delta_app + else not <$> anyFreeKappa delta_app app_res_rho -- (B) + -- For (B) see Note [The fiv test in quickLookArg] - ; if not can_do_ql then skipQuickLook delta larg - else + -- Step 4: do quick-look unification if either (A) or (B) hold + -- NB: arg_ty may not be zonked, but that's ok + ; let delta' = delta `unionVarSet` delta_app + ; when can_do_ql $ + qlUnify delta' arg_ty app_res_rho - do { traceTc "quickLookArg 3" $ + ; traceTc "quickLookArg 3" $ vcat [ text "tc_fun:" <+> ppr tc_fun , text "fun_sigma:" <+> ppr fun_sigma ] - -- Do quick-look unification - -- NB: arg_ty may not be zonked, but that's ok - ; let delta' = delta `unionVarSet` delta_app - ; qlUnify delta' arg_ty app_res_rho - - ; let ql_arg = ValArgQL { va_expr = larg - , va_fun = (tc_fun, fun_ctxt) - , va_args = inst_args - , va_ty = app_res_rho } - ; return (delta', ql_arg) } } } } + ; let ql_arg = ValArgQL { va_expr = larg + , va_fun = (tc_fun, fun_ctxt) + , va_args = inst_args + , va_ty = app_res_rho } + ; return (delta', ql_arg) } } } + +anyFreeKappa :: Delta -> TcType -> TcM Bool +-- True if there is a free instantiation variable (member of Delta) +-- in the argument type, after zonking +-- See Note [The fiv test in quickLookArg] +anyFreeKappa delta ty + = anyFreeVarsOfTypeM is_free_kappa ty + where + is_free_kappa :: TcTyVar -> TcM Bool + is_free_kappa tv | tv `elemVarSet` delta + = do { info <- readMetaTyVar tv + ; case info of + Indirect ty -> anyFreeKappa delta ty + Flexi -> return True } + | otherwise + = return False skipQuickLook :: Delta -> LHsExpr GhcRn -> TcM (Delta, EValArg 'TcpInst) skipQuickLook delta larg = return (delta, ValArg larg) @@ -1578,6 +1592,20 @@ quickLookResultType _ app_res_rho (Infer {}) -- generator. The safe thing to do is to zonk any instantiation -- variables away. See Note [Instantiation variables are short lived] +{- Note [The fiv test in quickLookArg] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In rule APP-lightning-bolt in Fig 5 of the paper, we have to test rho_r +for having no free instantiation variables. We do this in Step 3 of quickLookArg1, +using anyFreeKappa. Example: + Suppose ids :: [forall a. a->a] + and consider Just (ids++ids) +We will instantiate Just with kappa, say, and then call + quickLookArg1 False {kappa} (ids ++ ids) kappa +The call to tcInstFun will return with app_res_rho = [forall a. a->a] +which has no free instantiation variables, so we can QL-unify + kappa ~ [Forall a. a->a] +-} + --------------------- qlUnify :: Delta -> TcType -> TcType -> TcM () -- Unify ty1 with ty2, unifying only variables in delta View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/297971defa05c370e528ad452f2f8d2a21ccf78d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/297971defa05c370e528ad452f2f8d2a21ccf78d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 18 23:45:09 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 18 Apr 2024 19:45:09 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <6621b085153c_bfc5718aaf9c593f2@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ea0d50ab by Matthew Pickering at 2024-04-18T19:44:37-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - e87772da by Simon Peyton Jones at 2024-04-18T19:44:38-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - e344def5 by Alan Zimmerman at 2024-04-18T19:44:38-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 00c14e8a by Serge S. Gulin at 2024-04-18T19:44:44-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 2e42e6e0 by Alan Zimmerman at 2024-04-18T19:44:44-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 16 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,105 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1, SW2). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top]. Bottom line (data from !12410): adding the + not.exprIsHNF test to `saves_work`: + - Decreases compiler allocations by 0.5% + - Occasionally decreases runtime allocation (T12996 -2.5%) + - Slightly mixed effect on nofib: (puzzle -10%, mate -5%, cichelli +5%) + but geometric mean is -0.09%. + Overall, a win. + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1200,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3317,12 +3316,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3361,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92a14a49f94a0d6838617dd97668597b372653d6...2e42e6e0d79b39ad8f611b61e1fae0934c5589b8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92a14a49f94a0d6838617dd97668597b372653d6...2e42e6e0d79b39ad8f611b61e1fae0934c5589b8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 03:33:45 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Thu, 18 Apr 2024 23:33:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/clyring/mhu-perf-fragility Message-ID: <6621e619205c0_bfc5734782c4724bb@gitlab.mail> Matthew Craven pushed new branch wip/clyring/mhu-perf-fragility at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/clyring/mhu-perf-fragility You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:15:44 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 02:15:44 -0400 Subject: [Git][ghc/ghc][master] testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <66220c109861d_bfc57484d128798a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 2 changed files: - testsuite/driver/testglobals.py - testsuite/driver/testlib.py Changes: ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5eaa46e76b6693e480f297a5851b0bdca5830ff6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5eaa46e76b6693e480f297a5851b0bdca5830ff6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:16:22 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 02:16:22 -0400 Subject: [Git][ghc/ghc][master] Do not float HNFs out of lambdas Message-ID: <66220c36c26d8_bfc5749fd1bc834c3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - 3 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,105 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1, SW2). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top]. Bottom line (data from !12410): adding the + not.exprIsHNF test to `saves_work`: + - Decreases compiler allocations by 0.5% + - Occasionally decreases runtime allocation (T12996 -2.5%) + - Slightly mixed effect on nofib: (puzzle -10%, mate -5%, cichelli +5%) + but geometric mean is -0.09%. + Overall, a win. + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1200,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55a9d69933cc76a65ade52ab5815e47d2b07de32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55a9d69933cc76a65ade52ab5815e47d2b07de32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:17:10 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 02:17:10 -0400 Subject: [Git][ghc/ghc][master] EPA: Fix comments in mkListSyntaxTy0 Message-ID: <66220c6675d2_bfc574be1eb0889de@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - 3 changed files: - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3317,12 +3317,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3362,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f07015858fd79dca41983dbf3a249dfecd8d2eea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f07015858fd79dca41983dbf3a249dfecd8d2eea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:18:21 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 02:18:21 -0400 Subject: [Git][ghc/ghc][master] JS: set image `x86_64-linux-deb11-emsdk-closure` for build Message-ID: <66220cad24440_bfc574eb19c49543d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - 3 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b01c01d4c4dd4c3dc92f09917790531867d3d88d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b01c01d4c4dd4c3dc92f09917790531867d3d88d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:18:42 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 02:18:42 -0400 Subject: [Git][ghc/ghc][master] EPA: Provide correct span for PatBind Message-ID: <66220cc2277e9_bfc574f342849569a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 6 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c90c60390aa3949b400f26ee0534273c56e19005 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c90c60390aa3949b400f26ee0534273c56e19005 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 06:59:01 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 19 Apr 2024 02:59:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ghc-iface-sharing-avoid-reserialisation Message-ID: <662216358f673_15a431bc00c46751@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ghc-iface-sharing-avoid-reserialisation You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 09:15:22 2024 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Fri, 19 Apr 2024 05:15:22 -0400 Subject: [Git][ghc/ghc][wip/T23764] Fix quantification order for a `op` b and a %m -> b Message-ID: <6622362a46c98_15a431f8640c6593@gitlab.mail> Vladislav Zavialov pushed to branch wip/T23764 at Glasgow Haskell Compiler / GHC Commits: a1c4819d by Krzysztof Gogolewski at 2024-04-19T11:14:41+02:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 8 changed files: - compiler/GHC/Rename/HsType.hs - docs/users_guide/9.12.1-notes.rst - testsuite/tests/linear/should_compile/MultConstructor.hs - testsuite/tests/linear/should_fail/LinearErrOrigin.stderr - testsuite/tests/linear/should_fail/LinearVar.stderr - + testsuite/tests/typecheck/should_compile/T23764.hs - testsuite/tests/typecheck/should_compile/all.T - utils/haddock Changes: ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1731,6 +1731,9 @@ FreeKiTyVars, which notably includes the `extract-` family of functions (extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.). These functions thus promise to keep left-to-right ordering. +Note that for 'HsFunTy m ty1 ty2', we quantify in the order ty1, m, ty2, +since this type is written ty1 %m -> ty2 in the source syntax. + Note [Implicit quantification in type synonyms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We typically bind type/kind variables implicitly when they are in a kind @@ -2056,12 +2059,12 @@ extract_lty (L _ ty) acc HsListTy _ ty -> extract_lty ty acc HsTupleTy _ _ tys -> extract_ltys tys acc HsSumTy _ tys -> extract_ltys tys acc - HsFunTy _ w ty1 ty2 -> extract_lty ty1 $ - extract_lty ty2 $ - extract_hs_arrow w acc + HsFunTy _ m ty1 ty2 -> extract_lty ty1 $ + extract_hs_arrow m $ -- See Note [Ordering of implicit variables] + extract_lty ty2 acc HsIParamTy _ _ ty -> extract_lty ty acc - HsOpTy _ _ ty1 tv ty2 -> extract_tv tv $ - extract_lty ty1 $ + HsOpTy _ _ ty1 tv ty2 -> extract_lty ty1 $ + extract_tv tv $ extract_lty ty2 acc HsParTy _ ty -> extract_lty ty acc HsSpliceTy {} -> acc -- Type splices mention no tvs ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -12,6 +12,17 @@ Language ~~~~~~~~ +- The ordering of variables used for visible type application has been changed in two cases. + It is supposed to be left-to-right, but due to an oversight, it was wrong: + + - in an infix application ``f :: a `op` b``, it is now ``forall a op b.`` rather than + ``forall op a b.`` + - in a linear type ``f :: a %m -> b``, it is now ``forall a m b.`` rather than + ``forall a b m.``. + + This change is backwards-incompatible, although in practice we don't expect it + to cause significant disruption. + Compiler ~~~~~~~~ ===================================== testsuite/tests/linear/should_compile/MultConstructor.hs ===================================== @@ -26,3 +26,9 @@ g2 (MkE x) = x vta :: Int %1 -> Existential Int vta x = MkE @Int @'One x + +h :: a %m -> b +h = h + +vta2 :: Int %1 -> Bool -- see #23764 +vta2 = h @Int @One @Bool ===================================== testsuite/tests/linear/should_fail/LinearErrOrigin.stderr ===================================== @@ -3,13 +3,13 @@ LinearErrOrigin.hs:7:7: error: [GHC-25897] • Couldn't match type ‘p’ with ‘q’ arising from multiplicity of ‘x’ ‘p’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ‘q’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ===================================== testsuite/tests/linear/should_fail/LinearVar.stderr ===================================== @@ -5,7 +5,7 @@ LinearVar.hs:5:5: error: [GHC-25897] Actual: a -> b ‘m’ is a rigid type variable bound by the type signature for: - f :: forall a b (m :: GHC.Types.Multiplicity). a %m -> b + f :: forall a (m :: GHC.Types.Multiplicity) b. a %m -> b at LinearVar.hs:4:1-14 • In the expression: undefined :: a -> b In an equation for ‘f’: f = undefined :: a -> b ===================================== testsuite/tests/typecheck/should_compile/T23764.hs ===================================== @@ -0,0 +1,7 @@ +module T23764 where + +f :: a `op` b +f = f + +g :: (Int, Bool) +g = f @Int @(,) @Bool ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -914,3 +914,4 @@ test('T17594f', normal, compile, ['']) test('WarnDefaultedExceptionContext', normal, compile, ['-Wdefaulted-exception-context']) test('T24470b', normal, compile, ['']) test('T24566', [], makefile_test, []) +test('T23764', normal, compile, ['']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit c6fc9c4b79a8490966e9f45f3d3bcd5ad6c28865 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c4819d7729b1c5e29933c29ac7e9a17397c726 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1c4819d7729b1c5e29933c29ac7e9a17397c726 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 09:18:52 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 19 Apr 2024 05:18:52 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <662236fc6e4f1_15a431109b5b8685e7@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 290143b6 by Teo Camarasu at 2024-04-19T10:18:45+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,15 +132,11 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers , directory , process - , exceptions , filepath , osString -- , ghc -- # depends on ghc library @@ -157,12 +153,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,38 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec - , semaphoreCompat - , time + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc + , semaphoreCompat -- depends on , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix + -- We must use the in-tree `Win32` as the version + -- bundled with GHC 9.6 is too old for `semaphore-compat`. + -- Once 9.6 is no longer a boot compiler, we can drop win32/unix. + -- These depend on `filepath`/`os-string` through an automatic flag + -- that confused Hadrian, so we must make those a stage0 package as well. + -- Once we drop `Win32`/`unix` it should be possible to drop those too. ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +141,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +158,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/290143b660beb1b602065a880cda116f8a3afe30 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/290143b660beb1b602065a880cda116f8a3afe30 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 11:21:52 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 19 Apr 2024 07:21:52 -0400 Subject: [Git][ghc/ghc][wip/T24652] 2 commits: Remove unecessary stage0 packages Message-ID: <662253d03f4e_15a431221ded0986e7@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 10dc184c by Teo Camarasu at 2024-04-18T10:09:14+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. Resolves #24652 - - - - - 160cfe77 by Teo Camarasu at 2024-04-19T12:21:40+01:00 bump index state - - - - - 4 changed files: - .gitlab/ci.sh - hadrian/cabal.project - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== .gitlab/ci.sh ===================================== @@ -7,7 +7,7 @@ set -Eeuo pipefail # Configuration: -HACKAGE_INDEX_STATE="2023-10-05T11:38:51Z" +HACKAGE_INDEX_STATE="2024-04-03T11:41:05Z" MIN_HAPPY_VERSION="1.20" MIN_ALEX_VERSION="3.2.6" ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in ci.sh -index-state: 2023-10-05T11:38:51Z +index-state: 2024-04-03T11:41:05Z -- N.B. Compile with -O0 since this is not a performance-critical executable -- and the Cabal takes nearly twice as long to build with -O1. See #16817. ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,17 +132,9 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath - , osString -- , ghc -- # depends on ghc library -- , runGhc -- # depends on ghc library , ghcBoot @@ -157,15 +149,10 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec - , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable - ] ++ if windowsHost then [ win32 ] else [ unix ] + ] -- | Create a mapping from files to which component it belongs to. dirMap :: Action [(FilePath, (Package, [String]))] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,26 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec + , hsc2hs + , runGhc , semaphoreCompat - , time , templateHaskellNext - , text - , transformers , unlit - , hp2ps - , if windowsHost then win32 else unix ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +129,16 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq + , directory , exceptions + , filepath , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +148,18 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , osString + , parsec , pretty + , process , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , time + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/290143b660beb1b602065a880cda116f8a3afe30...160cfe77c323796dc5b55dbd6840a5afd48eb4cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/290143b660beb1b602065a880cda116f8a3afe30...160cfe77c323796dc5b55dbd6840a5afd48eb4cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 11:36:05 2024 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Fri, 19 Apr 2024 07:36:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/bump-haddock Message-ID: <66225725847c2_15a43124948f810243e@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/bump-haddock at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/bump-haddock You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 12:45:21 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 19 Apr 2024 08:45:21 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <662267611891b_15a431313768c14112f@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: c42f9035 by Fendor at 2024-04-19T14:43:48+02:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 21495663 by Fendor at 2024-04-19T14:43:51+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. - - - - - 5 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $DEPTH layers of modules with $WIDTH modules on each layer +# Every module on layer N imports all the modules on layer N-1 +# Each module has $DEFS definitions in +# MultiLayerModules.hs imports all the modules from the last layer +WIDTH=10 +FIELDS=10 +CONSTRS=20 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdfdbbf49e1218cea5633ec76131c9072e957b48...21495663d5d0e37e9329fefc4e8a1b31ce6d2352 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdfdbbf49e1218cea5633ec76131c9072e957b48...21495663d5d0e37e9329fefc4e8a1b31ce6d2352 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 12:46:28 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 19 Apr 2024 08:46:28 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <662267a43806d_15a431320602c1414e9@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: c0a7f78b by Sebastian Graf at 2024-04-19T14:45:58+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Magic` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) - = False -- 3. in the Note + = False -- 4. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,42 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2174,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2207,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2706,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,12 +157,15 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The two remaining identifiers in GHC.Magic, runRW# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. - runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. - inline: see Note [inlineId magic] + Similarly for GHC.Internal.IO.seq# and GHC.Internal.Exts.considerAccessible. + runRW#: see Note [Simplification of runRW#] in Prep, + runRW# code in Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] + inline: see Note [inlineId magic] + considerAccessible: see Note [considerAccessible] -} wiredInIds :: [Id] @@ -2235,8 +2238,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a' #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,14 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate'. +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -58,8 +58,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +79,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- This MkStrictPair application should not result in a thunk at run-time ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,4 +4,5 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) test('T24463', normal, compile, ['-O']) ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6655,7 +6655,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -4584,7 +4584,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6835,7 +6835,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,6 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c0a7f78b066c53d40f9316f1bbeb099dc9216219 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c0a7f78b066c53d40f9316f1bbeb099dc9216219 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 12:47:59 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 19 Apr 2024 08:47:59 -0400 Subject: [Git][ghc/ghc][wip/T24124] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <662267ffa4270_15a43132e7f5414832b@gitlab.mail> Sebastian Graf pushed to branch wip/T24124 at Glasgow Haskell Compiler / GHC Commits: 8fc6abd1 by Sebastian Graf at 2024-04-19T14:47:27+02:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) - = False -- 3. in the Note + = False -- 4. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,42 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2174,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2207,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2706,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,12 +157,15 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The two remaining identifiers in GHC.Magic, runRW# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. - runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. - inline: see Note [inlineId magic] + Similarly for GHC.Internal.IO.seq# and GHC.Internal.Exts.considerAccessible. + runRW#: see Note [Simplification of runRW#] in Prep, + runRW# code in Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] + inline: see Note [inlineId magic] + considerAccessible: see Note [considerAccessible] -} wiredInIds :: [Id] @@ -2235,8 +2238,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a' #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,14 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate'. +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -58,8 +58,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +79,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- This MkStrictPair application should not result in a thunk at run-time ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,4 +4,5 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) test('T24463', normal, compile, ['-O']) ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6655,7 +6655,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -4584,7 +4584,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6835,7 +6835,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,6 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8fc6abd13c1f772440744a3d2793293e1c6b30b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8fc6abd13c1f772440744a3d2793293e1c6b30b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 12:51:54 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 19 Apr 2024 08:51:54 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <662268eaedfd7_15a4313460d541528e1@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: 1117df41 by Fendor at 2024-04-19T14:51:45+02:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 96061301 by Fendor at 2024-04-19T14:51:45+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. - - - - - 5 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=20 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21495663d5d0e37e9329fefc4e8a1b31ce6d2352...96061301595b4efd079c34a18e119a654bc7b690 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21495663d5d0e37e9329fefc4e8a1b31ce6d2352...96061301595b4efd079c34a18e119a654bc7b690 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 12:55:00 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Fri, 19 Apr 2024 08:55:00 -0400 Subject: [Git][ghc/ghc][wip/T24652] Remove unecessary stage0 packages Message-ID: <662269a3f0b76_15a43135bf31c158912@gitlab.mail> Teo Camarasu pushed to branch wip/T24652 at Glasgow Haskell Compiler / GHC Commits: 290143b6 by Teo Camarasu at 2024-04-19T10:18:45+01:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,15 +132,11 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers , directory , process - , exceptions , filepath , osString -- , ghc -- # depends on ghc library @@ -157,12 +153,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,38 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec - , semaphoreCompat - , time + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc + , semaphoreCompat -- depends on , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix + -- We must use the in-tree `Win32` as the version + -- bundled with GHC 9.6 is too old for `semaphore-compat`. + -- Once 9.6 is no longer a boot compiler, we can drop win32/unix. + -- These depend on `filepath`/`os-string` through an automatic flag + -- that confused Hadrian, so we must make those a stage0 package as well. + -- Once we drop `Win32`/`unix` it should be possible to drop those too. ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +141,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +158,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/290143b660beb1b602065a880cda116f8a3afe30 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/290143b660beb1b602065a880cda116f8a3afe30 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 13:21:29 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 09:21:29 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <66226fd937a71_31a43f119f402796@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 97bebf4b by Alan Zimmerman at 2024-04-19T09:21:01-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - ec6c99b8 by Matthew Craven at 2024-04-19T09:21:02-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - 22 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/rename/should_fail/T17594b.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs - testsuite/tests/typecheck/should_fail/T17594c.stderr - testsuite/tests/typecheck/should_fail/T17594d.stderr - testsuite/tests/typecheck/should_fail/T17594g.stderr Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,105 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1, SW2). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top]. Bottom line (data from !12410): adding the + not.exprIsHNF test to `saves_work`: + - Decreases compiler allocations by 0.5% + - Occasionally decreases runtime allocation (T12996 -2.5%) + - Slightly mixed effect on nofib: (puzzle -10%, mate -5%, cichelli +5%) + but geometric mean is -0.09%. + Overall, a win. + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1200,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -219,7 +219,7 @@ type instance XHsPS GhcPs = EpAnnCO type instance XHsPS GhcRn = HsPSRn type instance XHsPS GhcTc = HsPSRn -type instance XHsTP GhcPs = EpAnnCO +type instance XHsTP GhcPs = NoExtField type instance XHsTP GhcRn = HsTyPatRn type instance XHsTP GhcTc = DataConCantHappen @@ -295,9 +295,9 @@ mkHsPatSigType :: EpAnnCO -> LHsType GhcPs -> HsPatSigType GhcPs mkHsPatSigType ann x = HsPS { hsps_ext = ann , hsps_body = x } -mkHsTyPat :: EpAnnCO -> LHsType GhcPs -> HsTyPat GhcPs -mkHsTyPat ann x = HsTP { hstp_ext = ann - , hstp_body = x } +mkHsTyPat :: LHsType GhcPs -> HsTyPat GhcPs +mkHsTyPat x = HsTP { hstp_ext = noExtField + , hstp_body = x } mkEmptyWildCardBndrs :: thing -> HsWildCardBndrs GhcRn thing mkEmptyWildCardBndrs x = HsWC { hswc_body = x @@ -589,7 +589,7 @@ mkHsAppTys = foldl' mkHsAppTy mkHsAppKindTy :: XAppKindTy (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -mkHsAppKindTy x ty k = addCLocA ty k (HsAppKindTy x ty k) +mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) {- ************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig @@ -3401,7 +3401,7 @@ bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parse argpat :: { LPat GhcPs } argpat : apat { $1 } - | PREFIX_AT atype { L (getLocAnn (reLoc $2)) (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } + | PREFIX_AT atype { sLLa $1 $> (InvisPat (epTok $1) (mkHsTyPat $2)) } argpats :: { [LPat GhcPs] } : argpat argpats { $1 : $2 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -1458,9 +1457,12 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L loc _)))) es ops cps - = go pat (L loc (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat + anc' = case tok of + NoEpTok -> anc + EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] go _ _ _ _ = return Nothing data ArgPatBuilder p @@ -1920,8 +1922,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) mkHsAppTypePV l p at t = do !cs <- getCommentsFor (locA l) - let anns = EpAnn (spanAsAnchor (getLocA t)) NoEpAnns cs - return $ L l (PatBuilderAppType p at (mkHsTyPat anns t)) + return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t)) mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar) @@ -1978,7 +1979,7 @@ instance DisambECP (PatBuilder GhcPs) where mkSumOrTuplePV = mkSumOrTuplePat mkHsEmbTyPV l toktype ty = return $ L (noAnnSrcSpan l) $ - PatBuilderPat (EmbTyPat toktype (mkHsTyPat noAnn ty)) + PatBuilderPat (EmbTyPat toktype (mkHsTyPat ty)) rejectPragmaPV _ = return () -- | Ensure that a literal pattern isn't of type Addr#, Float#, Double#. @@ -3317,12 +3318,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3363,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } @@ -1446,7 +1446,7 @@ cvtp (ConP s ts ps) = do { s' <- cNameN s ; ps' <- cvtPats ps ; ts' <- mapM cvtType ts ; let pps = map (parenthesizePat appPrec) ps' - pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat noAnn t)) ts' + pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat t)) ts' ; return $ ConPat { pat_con_ext = noAnn , pat_con = s' @@ -1489,9 +1489,9 @@ cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noAnn e' p'} cvtp (TypeP t) = do { t' <- cvtType t - ; return $ EmbTyPat noAnn (mkHsTyPat noAnn t') } + ; return $ EmbTyPat noAnn (mkHsTyPat t') } cvtp (InvisP t) = do { t' <- cvtType t - ; pure (InvisPat noAnn (mkHsTyPat noAnn t'))} + ; pure (InvisPat noAnn (mkHsTyPat t'))} cvtPatFld :: (TH.Name, TH.Pat) -> CvtM (LHsRecField GhcPs (LPat GhcPs)) cvtPatFld (s,p) ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -450,6 +448,7 @@ class TestOptions: self.combined_output = False # How should the timeout be adjusted on this test? + self.pre_cmd_timeout_multiplier = 1.0 self.compile_timeout_multiplier = 1.0 self.run_timeout_multiplier = 1.0 @@ -460,12 +459,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -560,6 +559,12 @@ def signal_exit_code( val: int ): # ----- +def pre_cmd_timeout_multiplier( val: float ): + return lambda name, opts, v=val: _pre_cmd_timeout_multiplier(name, opts, v) + +def _pre_cmd_timeout_multiplier( name, opts, v ): + opts.pre_cmd_timeout_multiplier = v + def compile_timeout_multiplier( val: float ): return lambda name, opts, v=val: _compile_timeout_multiplier(name, opts, v) @@ -1290,21 +1295,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) @@ -1473,7 +1475,9 @@ async def do_test(name: TestName, exit_code = await runCmd('cd "{0}" && {1}'.format(opts.testdir, override_options(opts.pre_cmd)), stdout = stdout_path, stderr = stderr_path, - print_output = config.verbose >= 3) + print_output = config.verbose >= 3, + timeout_multiplier = opts.pre_cmd_timeout_multiplier, + ) # If user used expect_broken then don't record failures of pre_cmd if exit_code != 0 and opts.expect not in ['fail']: ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -4,7 +4,8 @@ test('mhu-perf', pre_cmd('$MAKE -s --no-print-directory mhu-perf'), js_broken(22349), when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests - compile_timeout_multiplier(5) + pre_cmd_timeout_multiplier(2), + compile_timeout_multiplier(5), ], multiunit_compile, [['unitTop1', 'unitTop2'], '-fhide-source-paths']) ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + ===================================== testsuite/tests/rename/should_fail/T17594b.stderr ===================================== @@ -1,84 +1,84 @@ -T17594b.hs:7:6: error: [GHC-78249] +T17594b.hs:7:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:10:6: error: [GHC-78249] +T17594b.hs:10:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:14:6: error: [GHC-78249] +T17594b.hs:14:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:6: error: [GHC-78249] +T17594b.hs:17:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:10: error: [GHC-78249] +T17594b.hs:17:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:14: error: [GHC-78249] +T17594b.hs:17:13: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:27: error: [GHC-78249] +T17594b.hs:17:26: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:31: error: [GHC-78249] +T17594b.hs:17:30: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:35: error: [GHC-78249] +T17594b.hs:17:34: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:20:11: error: [GHC-78249] +T17594b.hs:20:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:22:20: error: [GHC-78249] +T17594b.hs:22:19: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:25:10: error: [GHC-78249] +T17594b.hs:25:9: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:6: error: [GHC-78249] +T17594b.hs:28:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:10: error: [GHC-78249] +T17594b.hs:28:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:32: error: [GHC-78249] +T17594b.hs:28:31: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:58: error: [GHC-78249] +T17594b.hs:28:57: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:62: error: [GHC-78249] +T17594b.hs:28:61: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:71: error: [GHC-78249] +T17594b.hs:28:70: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:31:11: error: [GHC-78249] +T17594b.hs:31:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:34:11: error: [GHC-78249] +T17594b.hs:34:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:37:7: error: [GHC-78249] +T17594b.hs:37:6: error: [GHC-78249] Illegal invisible type pattern: ($(TH.varT (TH.mkName "t"))) Suggested fix: Perhaps you intended to use TypeAbstractions ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- ===================================== testsuite/tests/typecheck/should_fail/T17594c.stderr ===================================== @@ -1,5 +1,5 @@ -T17594c.hs:5:11: error: [GHC-14964] +T17594c.hs:5:10: error: [GHC-14964] • Invisible type pattern t has no associated forall • In the expression: \ @t -> undefined :: t In the expression: [\ @t -> undefined :: t] ===================================== testsuite/tests/typecheck/should_fail/T17594d.stderr ===================================== @@ -1,4 +1,4 @@ -T17594d.hs:8:6: error: [GHC-14964] +T17594d.hs:8:5: error: [GHC-14964] • Invisible type pattern t has no associated forall • In an equation for ‘id'’: id' @t x = x :: t ===================================== testsuite/tests/typecheck/should_fail/T17594g.stderr ===================================== @@ -1,4 +1,4 @@ -T17594g.hs:6:6: error: [GHC-14964] +T17594g.hs:6:5: error: [GHC-14964] • Invisible type pattern a has no associated forall • In an equation for ‘id'’: id' @a x = x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e42e6e0d79b39ad8f611b61e1fae0934c5589b8...ec6c99b8751726aa6824e31584bfa259e636556d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e42e6e0d79b39ad8f611b61e1fae0934c5589b8...ec6c99b8751726aa6824e31584bfa259e636556d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 14:00:31 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 19 Apr 2024 10:00:31 -0400 Subject: [Git][ghc/ghc][wip/or-pats] 32 commits: users-guide: Clarify language extension documentation Message-ID: <662278ffbcdc5_31a43f657638783b@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - d3d8e477 by Sebastian Graf at 2024-04-19T14:00:22+00:00 Parser: Remove unused `apats` rule - - - - - 3abaf022 by David Knothe at 2024-04-19T14:00:22+00:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Pat.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a441c15ec45b6f0a8b9837e30081b452e28b4f2...3abaf0223ef561d62f1bf42465cf76a6f4b3557f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a441c15ec45b6f0a8b9837e30081b452e28b4f2...3abaf0223ef561d62f1bf42465cf76a6f4b3557f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 15:03:14 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 19 Apr 2024 11:03:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/trace-foreign-calls Message-ID: <662287b2c4b01_31a43fe8416c204a@gitlab.mail> Matthew Pickering pushed new branch wip/trace-foreign-calls at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/trace-foreign-calls You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 16:50:34 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 19 Apr 2024 12:50:34 -0400 Subject: [Git][ghc/ghc][wip/T24686] 6 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <6622a0dad26f2_3975ee45d1843690@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24686 at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - dcc785af by Simon Peyton Jones at 2024-04-19T17:49:46+01:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 24 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/ThToHs.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_run/simplrun009.hs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a9297a370025101b479cfd4977f8f910814e03ab + DOCKER_REV: 064e90c26dffe5709bd5b87dbd211b9a8b21fc5b # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -107,6 +107,7 @@ data Opsys data LinuxDistro = Debian12 | Debian11 + | Debian11Js | Debian10 | Debian9 | Fedora33 @@ -285,12 +286,13 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use -- These names are used to find the docker image so they have to match what is -- in the docker registry. distroName :: LinuxDistro -> String -distroName Debian12 = "deb12" -distroName Debian11 = "deb11" +distroName Debian12 = "deb12" +distroName Debian11 = "deb11" +distroName Debian11Js = "deb11-emsdk-closure" distroName Debian10 = "deb10" -distroName Debian9 = "deb9" -distroName Fedora33 = "fedora33" -distroName Fedora38 = "fedora38" +distroName Debian9 = "deb9" +distroName Fedora33 = "fedora33" +distroName Fedora38 = "fedora38" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" @@ -1009,7 +1011,7 @@ job_groups = , fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt))) , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) - , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig) + , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) , make_wasm_jobs wasm_build_config , modifyValidateJobs manual $ ===================================== .gitlab/jobs.yaml ===================================== @@ -1706,7 +1706,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "nightly-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -1717,7 +1717,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -1727,14 +1727,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -1760,14 +1760,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "XZ_OPT": "-9" } }, @@ -5087,7 +5087,7 @@ "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" } }, - "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate": { + "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -5098,7 +5098,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", + "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -5108,14 +5108,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-deb11-$CACHE_REV", + "key": "x86_64-linux-deb11-emsdk-closure-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11-emsdk-closure:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -5141,14 +5141,14 @@ ], "variables": { "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CONFIGURE_WRAPPER": "emconfigure", "CROSS_EMULATOR": "js-emulator", "CROSS_TARGET": "javascript-unknown-ghcjs", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-deb11-int_native-cross_javascript-unknown-ghcjs-validate" + "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate" } }, "x86_64-linux-deb11-validate+boot_nonmoving_gc": { ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -700,15 +700,13 @@ lvlMFE env strict_ctxt ann_expr -- that if we'll escape a value lambda, or will go to the top level. float_me = saves_work || saves_alloc || is_mk_static - -- We can save work if we can move a redex outside a value lambda - -- But if float_is_new_lam is True, then the redex is wrapped in a - -- a new lambda, so no work is saved - saves_work = escapes_value_lam && not float_is_new_lam - + -- See Note [Saving work] + saves_work = escapes_value_lam -- (a) + && not (exprIsHNF expr) -- (b) + && not float_is_new_lam -- (c) escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env) - -- See Note [Escaping a value lambda] - -- See Note [Floating to the top] + -- See Note [Saving allocation] and Note [Floating to the top] saves_alloc = isTopLvl dest_lvl && floatConsts env && ( not strict_ctxt -- (a) @@ -723,30 +721,105 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool hasFreeJoin env fvs = not (maxFvLevel isJoinId env fvs == tOP_LEVEL) -{- Note [Floating to the top] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose saves_work is False, i.e. - - 'e' does not escape a value lambda (escapes_value_lam), or - - 'e' would have added value lambdas if floated (float_is_new_lam) -Then we may still be keen to float a sub-expression 'e' to the top level, -for two reasons: - - (i) Doing so makes the function smaller, by floating out - bottoming expressions, or integer or string literals. That in - turn makes it easier to inline, with less duplication. - This only matters if the floated sub-expression is inside a - value-lambda, which in turn may be easier to inline. - - (ii) (Minor) Doing so may turn a dynamic allocation (done by machine - instructions) into a static one. Minor because we are assuming - we are not escaping a value lambda. - -But only do so if (saves_alloc): - (a) the context is lazy (so we get allocation), or - (b) the expression is a HNF (so we get allocation), or - (c) the expression is bottoming and (i) applies - (NB: if the expression is a lambda, (b) will apply; - so this case only catches bottoming thunks) +{- Note [Saving work] +~~~~~~~~~~~~~~~~~~~~~ +The key idea in let-floating is to + * float a redex out of a (value) lambda +Doing so can save an unbounded amount of work. +But see also Note [Saving allocation]. + +So we definitely float an expression out if +(a) It will escape a value lambda (escapes_value_lam) +(b) The expression is not a head-normal form (exprIsHNF); see (SW1, SW2). +(c) Floating does not require wrapping it in value lambdas (float_is_new_lam). + See (SW3) below + +Wrinkles: + +(SW1) Concerning (b) I experimented with using `exprIsCheap` rather than + `exprIsHNF` but the latter seems better, according to nofib + (`spectral/mate` got 10% worse with exprIsCheap). It's really a bit of a + heuristic. + +(SW2) What about omitting (b), and hence floating HNFs as well? The danger of + doing so is that we end up floating out a HNF from a cold path (where it + might never get allocated at all) and allocating it all the time + regardless. Example + f xs = case xs of + [x] | x>3 -> (y,y) + | otherwise -> (x,y) + (x:xs) -> ...f xs... + We can float (y,y) out, but in a particular call to `f` that path might + not be taken, so allocating it before the definition of `f` is a waste. + + See !12410 for some data comparing the effect of omitting (b) altogether, + This doesn't apply, though, if we float the thing to the top level; see + Note [Floating to the top]. Bottom line (data from !12410): adding the + not.exprIsHNF test to `saves_work`: + - Decreases compiler allocations by 0.5% + - Occasionally decreases runtime allocation (T12996 -2.5%) + - Slightly mixed effect on nofib: (puzzle -10%, mate -5%, cichelli +5%) + but geometric mean is -0.09%. + Overall, a win. + +(SW3) Concerning (c), if we are wrapping the thing in extra value lambdas (in + abs_vars), then nothing is saved. E.g. + f = \xyz. ...(e1[y],e2).... + If we float + lvl = \y. (e1[y],e2) + f = \xyz. ...(lvl y)... + we have saved nothing: one pair will still be allocated for each + call of `f`. Hence the (not float_is_new_lam) in saves_work. + +Note [Saving allocation] +~~~~~~~~~~~~~~~~~~~~~~~~ +Even if `saves_work` is false, we we may want to float even cheap/HNF +expressions out of value lambdas, for several reasons: + +* Doing so may save allocation. Consider + f = \x. .. (\y.e) ... + Then we'd like to avoid allocating the (\y.e) every time we call f, + (assuming e does not mention x). An example where this really makes a + difference is simplrun009. + +* It may allow SpecContr to fire on functions. Consider + f = \x. ....(f (\y.e)).... + After floating we get + lvl = \y.e + f = \x. ....(f lvl)... + Now it's easier for SpecConstr to generate a robust specialisation for f. + +* It makes the function smaller, and hence more likely to inline. This can make + a big difference for string literals and bottoming expressions: see Note + [Floating to the top] + +Data suggests, however, that it is better /only/ to float HNFS, /if/ they can go +to top level. See (SW2) of Note [Saving work]. If the expression goes to top +level we don't pay the cost of allocating cold-path thunks described in (SW2). + +Hence `isTopLvl dest_lvl` in `saves_alloc`. + +Note [Floating to the top] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Even though Note [Saving allocation] suggests that we should not, in +general, float HNFs, the balance change if it goes to the top: + +* We don't pay an allocation cost for the floated expression; it + just becomes static data. + +* Floating string literal is valuable -- no point in duplicating the + at each call site! + +* Floating bottoming expressions is valuable: they are always cold + paths; we don't want to duplicate them at each call site; and they + can be quite big, inhibiting inlining. See Note [Bottoming floats] + +So we float an expression to the top if: + (a) the context is lazy (so we get allocation), or + (b) the expression is a HNF (so we get allocation), or + (c) the expression is bottoming and floating would escape a + value lambda (NB: if the expression itself is a lambda, (b) + will apply; so this case only catches bottoming thunks) Examples: @@ -1127,33 +1200,6 @@ But *coercion* arguments aren’t (see Note [Coercion tokens] in "GHC.Core.Unfold"), so we still want to float out variables applied only to coercion arguments. -Note [Escaping a value lambda] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We want to float even cheap expressions out of value lambdas, -because that saves allocation. Consider - f = \x. .. (\y.e) ... -Then we'd like to avoid allocating the (\y.e) every time we call f, -(assuming e does not mention x). An example where this really makes a -difference is simplrun009. - -Another reason it's good is because it makes SpecContr fire on functions. -Consider - f = \x. ....(f (\y.e)).... -After floating we get - lvl = \y.e - f = \x. ....(f lvl)... -and that is much easier for SpecConstr to generate a robust -specialisation for. - -However, if we are wrapping the thing in extra value lambdas (in -abs_vars), then nothing is saved. E.g. - f = \xyz. ...(e1[y],e2).... -If we float - lvl = \y. (e1[y],e2) - f = \xyz. ...(lvl y)... -we have saved nothing: one pair will still be allocated for each -call of 'f'. Hence the (not float_is_lam) in float_me. - ************************************************************************ * * ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1322,7 +1322,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1333,12 +1333,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1376,15 +1376,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1393,8 +1392,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) @@ -3317,12 +3316,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3362,15 +3361,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/driver/testglobals.py ===================================== @@ -182,8 +182,6 @@ class TestConfig: self.threads = 1 # An optional executable used to wrap target code execution - # When set tests which aren't marked with TestConfig.cross_okay - # are skipped. self.target_wrapper = None # tests which should be considered to be broken during this testsuite @@ -460,12 +458,6 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False - # Should the test be run in a cross-compiled tree? - # None: infer from test function - # True: run when --target-wrapper is set - # False: do not run in cross-compiled trees - self.cross_okay = None # type: Optional[bool] - # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -91,8 +91,8 @@ def setLocalTestOpts(opts: TestOptions) -> None: global testopts_ctx_var testopts_ctx_var.set(opts) -def isCross() -> bool: - """ Are we testing a cross-compiler? """ +def needsTargetWrapper() -> bool: + """ Do we need to use a target wrapper? """ return config.target_wrapper is not None def isCompilerStatsTest() -> bool: @@ -240,7 +240,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp or isCross(): + if not config.have_interp or needsTargetWrapper(): opts.expect = 'fail' # skip on wasm32, otherwise they show up as unexpected passes if arch('wasm32'): @@ -346,11 +346,10 @@ def req_host_target_ghc( name, opts ): """ When testing a cross GHC, some test cases require a host GHC as well (e.g. for compiling custom Setup.hs). This is not supported yet (#23236), so for - the time being we skip them when testing cross GHCs. However, this is not - the case for the JS backend. The JS backend is a cross-compiler that - produces code that the host can run. + the time being we skip them when testing cross GHCs. However, for cross targets + which don't need a target wrapper (e.g. javascript), we can still run these testcases. """ - if isCross() and not js_arch(): + if needsTargetWrapper(): opts.skip = True has_ls_files = None @@ -1290,21 +1289,18 @@ async def test_common_work(name: TestName, opts, all_ways = [WayName('ghci'), WayName('ghci-opt')] else: all_ways = [] - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways - if isCross(): - opts.cross_okay = False + if needsTargetWrapper(): + opts.skip = True else: all_ways = [WayName('normal')] - if isCross() and opts.cross_okay is False: - opts.skip = True - # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -131,9 +131,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 38, types: 90, coercions: 17, joins: 0/1} + = {terms: 36, types: 86, coercions: 17, joins: 0/0} --- RHS size: {terms: 37, types: 78, coercions: 17, joins: 0/1} +-- RHS size: {terms: 35, types: 74, coercions: 17, joins: 0/0} mapMaybeRule [InlPrag=[2]] :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, @@ -182,12 +182,6 @@ mapMaybeRule [InlPrag=[2]] mapMaybeRule = \ (@a) (@b) (f :: Rule IO a b) -> case f of { Rule @s ww ww1 -> - let { - lvl :: Result s (Maybe b) - [LclId, Unf=OtherCon []] - lvl - = T18013a.Result - @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) } in T18013a.Rule @IO @(Maybe a) @@ -198,7 +192,9 @@ mapMaybeRule (a1 :: Maybe a) (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case a1 of { - Nothing -> (# s1, lvl #); + Nothing -> + (# s1, + T18013a.Result @s @(Maybe b) ww (GHC.Internal.Maybe.Nothing @b) #); Just x -> case ((ww1 s2 x) `cast` :: IO (Result s b) ===================================== testsuite/tests/simplCore/should_run/simplrun009.hs ===================================== @@ -6,7 +6,7 @@ -- It produces a nested unfold that should look something -- like the code below. Note the 'lvl1_shW'. It is BAD -- if this is a lambda instead; you get a lot more allocation --- See Note [Escaping a value lambda] in GHC.Core.Opt.SetLevels +-- See Note [Saving allocation] in GHC.Core.Opt.SetLevels {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/094b31fa22b76db258db1075b4e8bc44cd49f4fb...dcc785afe3841138b79e5ca47c205ba58607fa95 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/094b31fa22b76db258db1075b4e8bc44cd49f4fb...dcc785afe3841138b79e5ca47c205ba58607fa95 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 16:57:48 2024 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Fri, 19 Apr 2024 12:57:48 -0400 Subject: [Git][ghc/ghc][wip/T23764] Fix quantification order for a `op` b and a %m -> b Message-ID: <6622a28c79c02_3975ee5b11d4745d@gitlab.mail> Vladislav Zavialov pushed to branch wip/T23764 at Glasgow Haskell Compiler / GHC Commits: 61f4bebd by Krzysztof Gogolewski at 2024-04-19T18:57:37+02:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 8 changed files: - compiler/GHC/Rename/HsType.hs - docs/users_guide/9.12.1-notes.rst - testsuite/tests/linear/should_compile/MultConstructor.hs - testsuite/tests/linear/should_fail/LinearErrOrigin.stderr - testsuite/tests/linear/should_fail/LinearVar.stderr - + testsuite/tests/typecheck/should_compile/T23764.hs - testsuite/tests/typecheck/should_compile/all.T - utils/haddock Changes: ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1731,6 +1731,9 @@ FreeKiTyVars, which notably includes the `extract-` family of functions (extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.). These functions thus promise to keep left-to-right ordering. +Note that for 'HsFunTy m ty1 ty2', we quantify in the order ty1, m, ty2, +since this type is written ty1 %m -> ty2 in the source syntax. + Note [Implicit quantification in type synonyms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We typically bind type/kind variables implicitly when they are in a kind @@ -2056,12 +2059,12 @@ extract_lty (L _ ty) acc HsListTy _ ty -> extract_lty ty acc HsTupleTy _ _ tys -> extract_ltys tys acc HsSumTy _ tys -> extract_ltys tys acc - HsFunTy _ w ty1 ty2 -> extract_lty ty1 $ - extract_lty ty2 $ - extract_hs_arrow w acc + HsFunTy _ m ty1 ty2 -> extract_lty ty1 $ + extract_hs_arrow m $ -- See Note [Ordering of implicit variables] + extract_lty ty2 acc HsIParamTy _ _ ty -> extract_lty ty acc - HsOpTy _ _ ty1 tv ty2 -> extract_tv tv $ - extract_lty ty1 $ + HsOpTy _ _ ty1 tv ty2 -> extract_lty ty1 $ + extract_tv tv $ extract_lty ty2 acc HsParTy _ ty -> extract_lty ty acc HsSpliceTy {} -> acc -- Type splices mention no tvs ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -12,6 +12,17 @@ Language ~~~~~~~~ +- The ordering of variables used for visible type application has been changed in two cases. + It is supposed to be left-to-right, but due to an oversight, it was wrong: + + - in an infix application ``f :: a `op` b``, it is now ``forall a op b.`` rather than + ``forall op a b.`` + - in a linear type ``f :: a %m -> b``, it is now ``forall a m b.`` rather than + ``forall a b m.``. + + This change is backwards-incompatible, although in practice we don't expect it + to cause significant disruption. + Compiler ~~~~~~~~ ===================================== testsuite/tests/linear/should_compile/MultConstructor.hs ===================================== @@ -26,3 +26,9 @@ g2 (MkE x) = x vta :: Int %1 -> Existential Int vta x = MkE @Int @'One x + +h :: a %m -> b +h = h + +vta2 :: Int %1 -> Bool -- see #23764 +vta2 = h @Int @One @Bool ===================================== testsuite/tests/linear/should_fail/LinearErrOrigin.stderr ===================================== @@ -3,13 +3,13 @@ LinearErrOrigin.hs:7:7: error: [GHC-25897] • Couldn't match type ‘p’ with ‘q’ arising from multiplicity of ‘x’ ‘p’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ‘q’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ===================================== testsuite/tests/linear/should_fail/LinearVar.stderr ===================================== @@ -5,7 +5,7 @@ LinearVar.hs:5:5: error: [GHC-25897] Actual: a -> b ‘m’ is a rigid type variable bound by the type signature for: - f :: forall a b (m :: GHC.Types.Multiplicity). a %m -> b + f :: forall a (m :: GHC.Types.Multiplicity) b. a %m -> b at LinearVar.hs:4:1-14 • In the expression: undefined :: a -> b In an equation for ‘f’: f = undefined :: a -> b ===================================== testsuite/tests/typecheck/should_compile/T23764.hs ===================================== @@ -0,0 +1,7 @@ +module T23764 where + +f :: a `op` b +f = f + +g :: (Int, Bool) +g = f @Int @(,) @Bool ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -914,3 +914,4 @@ test('T17594f', normal, compile, ['']) test('WarnDefaultedExceptionContext', normal, compile, ['-Wdefaulted-exception-context']) test('T24470b', normal, compile, ['']) test('T24566', [], makefile_test, []) +test('T23764', normal, compile, ['']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61f4bebd4780be190b8a8df4019b3a4bee8d18ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61f4bebd4780be190b8a8df4019b3a4bee8d18ce You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 17:11:40 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 13:11:40 -0400 Subject: [Git][ghc/ghc][master] EPA: Fix span for PatBuilderAppType Message-ID: <6622a5cc69211_3975ee8cab2c132d5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - 8 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/rename/should_fail/T17594b.stderr - testsuite/tests/typecheck/should_fail/T17594c.stderr - testsuite/tests/typecheck/should_fail/T17594d.stderr - testsuite/tests/typecheck/should_fail/T17594g.stderr Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -219,7 +219,7 @@ type instance XHsPS GhcPs = EpAnnCO type instance XHsPS GhcRn = HsPSRn type instance XHsPS GhcTc = HsPSRn -type instance XHsTP GhcPs = EpAnnCO +type instance XHsTP GhcPs = NoExtField type instance XHsTP GhcRn = HsTyPatRn type instance XHsTP GhcTc = DataConCantHappen @@ -295,9 +295,9 @@ mkHsPatSigType :: EpAnnCO -> LHsType GhcPs -> HsPatSigType GhcPs mkHsPatSigType ann x = HsPS { hsps_ext = ann , hsps_body = x } -mkHsTyPat :: EpAnnCO -> LHsType GhcPs -> HsTyPat GhcPs -mkHsTyPat ann x = HsTP { hstp_ext = ann - , hstp_body = x } +mkHsTyPat :: LHsType GhcPs -> HsTyPat GhcPs +mkHsTyPat x = HsTP { hstp_ext = noExtField + , hstp_body = x } mkEmptyWildCardBndrs :: thing -> HsWildCardBndrs GhcRn thing mkEmptyWildCardBndrs x = HsWC { hswc_body = x @@ -589,7 +589,7 @@ mkHsAppTys = foldl' mkHsAppTy mkHsAppKindTy :: XAppKindTy (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -mkHsAppKindTy x ty k = addCLocA ty k (HsAppKindTy x ty k) +mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) {- ************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -3401,7 +3401,7 @@ bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parse argpat :: { LPat GhcPs } argpat : apat { $1 } - | PREFIX_AT atype { L (getLocAnn (reLoc $2)) (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } + | PREFIX_AT atype { sLLa $1 $> (InvisPat (epTok $1) (mkHsTyPat $2)) } argpats :: { [LPat GhcPs] } : argpat argpats { $1 : $2 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1457,9 +1457,12 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L loc _)))) es ops cps - = go pat (L loc (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat + anc' = case tok of + NoEpTok -> anc + EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] go _ _ _ _ = return Nothing data ArgPatBuilder p @@ -1919,8 +1922,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) mkHsAppTypePV l p at t = do !cs <- getCommentsFor (locA l) - let anns = EpAnn (spanAsAnchor (getLocA t)) NoEpAnns cs - return $ L l (PatBuilderAppType p at (mkHsTyPat anns t)) + return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t)) mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar) @@ -1977,7 +1979,7 @@ instance DisambECP (PatBuilder GhcPs) where mkSumOrTuplePV = mkSumOrTuplePat mkHsEmbTyPV l toktype ty = return $ L (noAnnSrcSpan l) $ - PatBuilderPat (EmbTyPat toktype (mkHsTyPat noAnn ty)) + PatBuilderPat (EmbTyPat toktype (mkHsTyPat ty)) rejectPragmaPV _ = return () -- | Ensure that a literal pattern isn't of type Addr#, Float#, Double#. ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1446,7 +1446,7 @@ cvtp (ConP s ts ps) = do { s' <- cNameN s ; ps' <- cvtPats ps ; ts' <- mapM cvtType ts ; let pps = map (parenthesizePat appPrec) ps' - pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat noAnn t)) ts' + pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat t)) ts' ; return $ ConPat { pat_con_ext = noAnn , pat_con = s' @@ -1489,9 +1489,9 @@ cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noAnn e' p'} cvtp (TypeP t) = do { t' <- cvtType t - ; return $ EmbTyPat noAnn (mkHsTyPat noAnn t') } + ; return $ EmbTyPat noAnn (mkHsTyPat t') } cvtp (InvisP t) = do { t' <- cvtType t - ; pure (InvisPat noAnn (mkHsTyPat noAnn t'))} + ; pure (InvisPat noAnn (mkHsTyPat t'))} cvtPatFld :: (TH.Name, TH.Pat) -> CvtM (LHsRecField GhcPs (LPat GhcPs)) cvtPatFld (s,p) ===================================== testsuite/tests/rename/should_fail/T17594b.stderr ===================================== @@ -1,84 +1,84 @@ -T17594b.hs:7:6: error: [GHC-78249] +T17594b.hs:7:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:10:6: error: [GHC-78249] +T17594b.hs:10:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:14:6: error: [GHC-78249] +T17594b.hs:14:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:6: error: [GHC-78249] +T17594b.hs:17:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:10: error: [GHC-78249] +T17594b.hs:17:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:14: error: [GHC-78249] +T17594b.hs:17:13: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:27: error: [GHC-78249] +T17594b.hs:17:26: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:31: error: [GHC-78249] +T17594b.hs:17:30: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:35: error: [GHC-78249] +T17594b.hs:17:34: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:20:11: error: [GHC-78249] +T17594b.hs:20:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:22:20: error: [GHC-78249] +T17594b.hs:22:19: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:25:10: error: [GHC-78249] +T17594b.hs:25:9: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:6: error: [GHC-78249] +T17594b.hs:28:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:10: error: [GHC-78249] +T17594b.hs:28:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:32: error: [GHC-78249] +T17594b.hs:28:31: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:58: error: [GHC-78249] +T17594b.hs:28:57: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:62: error: [GHC-78249] +T17594b.hs:28:61: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:71: error: [GHC-78249] +T17594b.hs:28:70: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:31:11: error: [GHC-78249] +T17594b.hs:31:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:34:11: error: [GHC-78249] +T17594b.hs:34:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:37:7: error: [GHC-78249] +T17594b.hs:37:6: error: [GHC-78249] Illegal invisible type pattern: ($(TH.varT (TH.mkName "t"))) Suggested fix: Perhaps you intended to use TypeAbstractions ===================================== testsuite/tests/typecheck/should_fail/T17594c.stderr ===================================== @@ -1,5 +1,5 @@ -T17594c.hs:5:11: error: [GHC-14964] +T17594c.hs:5:10: error: [GHC-14964] • Invisible type pattern t has no associated forall • In the expression: \ @t -> undefined :: t In the expression: [\ @t -> undefined :: t] ===================================== testsuite/tests/typecheck/should_fail/T17594d.stderr ===================================== @@ -1,4 +1,4 @@ -T17594d.hs:8:6: error: [GHC-14964] +T17594d.hs:8:5: error: [GHC-14964] • Invisible type pattern t has no associated forall • In an equation for ‘id'’: id' @t x = x :: t ===================================== testsuite/tests/typecheck/should_fail/T17594g.stderr ===================================== @@ -1,4 +1,4 @@ -T17594g.hs:6:6: error: [GHC-14964] +T17594g.hs:6:5: error: [GHC-14964] • Invisible type pattern a has no associated forall • In an equation for ‘id'’: id' @a x = x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26036f96919b1a8b99715dd99724163012c719fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26036f96919b1a8b99715dd99724163012c719fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 17:12:20 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 13:12:20 -0400 Subject: [Git][ghc/ghc][master] testsuite: Give the pre_cmd for mhu-perf more time Message-ID: <6622a5f3f18de_3975eea7af08165c0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - 3 changed files: - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T Changes: ===================================== testsuite/driver/testglobals.py ===================================== @@ -448,6 +448,7 @@ class TestOptions: self.combined_output = False # How should the timeout be adjusted on this test? + self.pre_cmd_timeout_multiplier = 1.0 self.compile_timeout_multiplier = 1.0 self.run_timeout_multiplier = 1.0 ===================================== testsuite/driver/testlib.py ===================================== @@ -559,6 +559,12 @@ def signal_exit_code( val: int ): # ----- +def pre_cmd_timeout_multiplier( val: float ): + return lambda name, opts, v=val: _pre_cmd_timeout_multiplier(name, opts, v) + +def _pre_cmd_timeout_multiplier( name, opts, v ): + opts.pre_cmd_timeout_multiplier = v + def compile_timeout_multiplier( val: float ): return lambda name, opts, v=val: _compile_timeout_multiplier(name, opts, v) @@ -1469,7 +1475,9 @@ async def do_test(name: TestName, exit_code = await runCmd('cd "{0}" && {1}'.format(opts.testdir, override_options(opts.pre_cmd)), stdout = stdout_path, stderr = stderr_path, - print_output = config.verbose >= 3) + print_output = config.verbose >= 3, + timeout_multiplier = opts.pre_cmd_timeout_multiplier, + ) # If user used expect_broken then don't record failures of pre_cmd if exit_code != 0 and opts.expect not in ['fail']: ===================================== testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T ===================================== @@ -4,7 +4,8 @@ test('mhu-perf', pre_cmd('$MAKE -s --no-print-directory mhu-perf'), js_broken(22349), when(arch('wasm32'), skip), # wasm32 doesn't like running Setup/Makefile tests - compile_timeout_multiplier(5) + pre_cmd_timeout_multiplier(2), + compile_timeout_multiplier(5), ], multiunit_compile, [['unitTop1', 'unitTop2'], '-fhide-source-paths']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dba03aababff057c03e2d92677de02d8375cd23a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dba03aababff057c03e2d92677de02d8375cd23a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 18:37:50 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 19 Apr 2024 14:37:50 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Increase Clang happiness Message-ID: <6622b9fee3666_3975ee142af5831496@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: b268fc4c by Sven Tennie at 2024-04-19T20:36:22+02:00 Increase Clang happiness Otherwise, it newer versions refuse to build. - - - - - 7 changed files: - rts/linker/Elf.c - rts/linker/elf_reloc.c - rts/linker/elf_reloc.h - rts/linker/elf_reloc_aarch64.c - rts/linker/elf_reloc_aarch64.h - rts/linker/elf_reloc_riscv64.c - rts/linker/elf_reloc_riscv64.h Changes: ===================================== rts/linker/Elf.c ===================================== @@ -2015,8 +2015,8 @@ ocResolve_ELF ( ObjectCode* oc ) #if defined(powerpc_HOST_ARCH) ocFlushInstructionCache( oc ); -#elseif defined(riscv64_HOST_ARCH) - flushInstructionCache(); +#elif defined(riscv64_HOST_ARCH) + flushInstructionCache( oc ); #endif return ocMprotect_Elf(oc); ===================================== rts/linker/elf_reloc.c ===================================== @@ -13,8 +13,8 @@ relocateObjectCode(ObjectCode * oc) { } -void flushInstructionCache(){ - return ADD_SUFFIX(flushInstructionCache)(); +void flushInstructionCache(ObjectCode * oc){ + return ADD_SUFFIX(flushInstructionCache)(oc); } #endif ===================================== rts/linker/elf_reloc.h ===================================== @@ -10,5 +10,5 @@ bool relocateObjectCode(ObjectCode * oc); -void flushInstructionCache(); +void flushInstructionCache(ObjectCode *oc); #endif /* OBJETFORMAT_ELF */ ===================================== rts/linker/elf_reloc_aarch64.c ===================================== @@ -339,7 +339,7 @@ relocateObjectCodeAarch64(ObjectCode * oc) { return EXIT_SUCCESS; } -void flushInstructionCacheAarch64() { +void flushInstructionCacheAarch64(ObjectCode * oc) { // Looks like we don't need this on Aarch64. /* no-op */ } ===================================== rts/linker/elf_reloc_aarch64.h ===================================== @@ -7,5 +7,5 @@ bool relocateObjectCodeAarch64(ObjectCode * oc); -void flushInstructionCacheAarch64(); +void flushInstructionCacheAarch64(ObjectCode *oc); #endif /* OBJETFORMAT_ELF */ ===================================== rts/linker/elf_reloc_riscv64.c ===================================== @@ -16,6 +16,43 @@ #if defined(OBJFORMAT_ELF) +typedef uint64_t addr_t; + +/* regular instructions are 32bit */ +typedef uint32_t inst_t; + +/* compressed instructions are 16bit */ +typedef uint16_t cinst_t; + +// TODO: These instances could be static. They are not yet, because we might +// need their debugging symbols. +char *relocationTypeToString(Elf64_Xword type); +int32_t decodeAddendRISCV64(Section *section, Elf_Rel *rel); +bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int32_t addend); +int32_t SignExtend32(uint32_t X, unsigned B); +void write8le(uint8_t *p, uint8_t v); +uint8_t read8le(const uint8_t *P); +void write16le(cinst_t *p, uint16_t v); +uint16_t read16le(const cinst_t *P); +uint32_t read32le(const inst_t *P); +void write32le(inst_t *p, uint32_t v); +uint64_t read64le(const uint64_t *P); +void write64le(uint64_t *p, uint64_t v); +uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end); +void setCJType(cinst_t *loc, uint32_t val); +void setCBType(cinst_t *loc, uint32_t val); +void setBType(inst_t *loc, uint32_t val); +void setSType(inst_t *loc, uint32_t val); +int32_t computeAddend(ElfRelocationATable * relaTab, unsigned relNo, Elf_Rel *rel, ElfSymbol *symbol, + int64_t addend, ObjectCode *oc); +void setJType(inst_t *loc, uint32_t val); +void setIType(inst_t *loc, int32_t val); +void checkInt(inst_t *loc, int32_t v, int n); +uint32_t setLO12_I(uint32_t insn, uint32_t imm); +uint32_t setLO12_S(uint32_t insn, uint32_t imm); +void setUType(inst_t *loc, int32_t val); + + char *relocationTypeToString(Elf64_Xword type) { switch (ELF64_R_TYPE(type)) { case R_RISCV_NONE: @@ -77,18 +114,6 @@ char *relocationTypeToString(Elf64_Xword type) { #define Page(x) ((x) & ~0xFFF) -typedef uint64_t addr_t; - -int32_t decodeAddendRISCV64(Section *section, Elf_Rel *rel) STG_NORETURN; -bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int32_t addend); - -/* regular instructions are 32bit */ -typedef uint32_t inst_t; - -/* compressed instructions are 16bit */ -typedef uint16_t cinst_t; - -// TODO: Decide which functions should be static and/or inlined. int32_t decodeAddendRISCV64(Section *section STG_UNUSED, Elf_Rel *rel STG_UNUSED) { debugBelch("decodeAddendRISCV64: Relocations with explicit addend are not " @@ -469,7 +494,7 @@ int32_t computeAddend(ElfRelocationATable * relaTab, unsigned relNo, Elf_Rel *re IF_DEBUG(linker, debugBelch("R_RISCV_CALL_PLT w/ SymbolExtra = %p , " "entry = 0x%lx\n", symbolExtra, FAKE_GOT_S)); - GOT_Target = FAKE_GOT_S; + GOT_Target = (addr_t) FAKE_GOT_S; } if (findStub(section, (void **)&S, 0)) { ===================================== rts/linker/elf_reloc_riscv64.h ===================================== @@ -7,5 +7,5 @@ bool relocateObjectCodeRISCV64(ObjectCode * oc); -void flushInstructionCacheRISCV64(); +void flushInstructionCacheRISCV64(ObjectCode *oc); #endif /* OBJETFORMAT_ELF */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b268fc4c044af12fd3cd028751129cf59bb6a359 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b268fc4c044af12fd3cd028751129cf59bb6a359 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 19:43:48 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 15:43:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: EPA: Fix span for PatBuilderAppType Message-ID: <6622c974683ae_3aeed63469e47368f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - 17eb00e2 by Krzysztof Gogolewski at 2024-04-19T15:43:38-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 4761f05d by Sebastian Graf at 2024-04-19T15:43:38-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/9.12.1-notes.rst - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec6c99b8751726aa6824e31584bfa259e636556d...4761f05dc25d5511f00f07051c546e36fd01eb71 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec6c99b8751726aa6824e31584bfa259e636556d...4761f05dc25d5511f00f07051c546e36fd01eb71 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 20:03:18 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Fri, 19 Apr 2024 16:03:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-splicedecl-comments Message-ID: <6622ce0632e6c_3aeed668c89c789ae@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-splicedecl-comments at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-splicedecl-comments You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 22:24:12 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 18:24:12 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Fix quantification order for a `op` b and a %m -> b Message-ID: <6622ef0cbf681_3aeed61884cac927b9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 500ea395 by Krzysztof Gogolewski at 2024-04-19T18:24:02-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - a4eb0225 by Sebastian Graf at 2024-04-19T18:24:03-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/9.12.1-notes.rst - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/linear/should_compile/MultConstructor.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4761f05dc25d5511f00f07051c546e36fd01eb71...a4eb0225f4c0d25dfeb86d334be6bcd4a0e7f64f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4761f05dc25d5511f00f07051c546e36fd01eb71...a4eb0225f4c0d25dfeb86d334be6bcd4a0e7f64f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 19 23:55:40 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Fri, 19 Apr 2024 19:55:40 -0400 Subject: [Git][ghc/ghc][wip/T8671] Suppresses spurious warnings generated for do-body statements that Message-ID: <6623047ca057d_263dd780073c602b7@gitlab.mail> Apoorv Ingle pushed to branch wip/T8671 at Glasgow Haskell Compiler / GHC Commits: 831effee by Apoorv Ingle at 2024-04-19T18:55:17-05:00 Suppresses spurious warnings generated for do-body statements that in really do not discard anything. This improves usability of RebindableSyntax and Qualified Do. Fixes: #8671 - - - - - 8 changed files: - compiler/GHC/HsToCore/Expr.hs - + testsuite/tests/qualifieddo/should_compile/T8671a.hs - + testsuite/tests/qualifieddo/should_compile/T8671adefs.hs - + testsuite/tests/qualifieddo/should_compile/T8671b.hs - + testsuite/tests/qualifieddo/should_compile/T8671bdefs.hs - testsuite/tests/qualifieddo/should_compile/all.T - + testsuite/tests/rebindable/T8671.hs - testsuite/tests/rebindable/all.T Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -978,8 +978,11 @@ warnDiscardedDoBindings rhs rhs_ty do { fam_inst_envs <- dsGetFamInstEnvs ; let norm_elt_ty = topNormaliseType fam_inst_envs elt_ty - -- Warn about discarding non-() things in 'monadic' binding - ; if warn_unused && not (isUnitTy norm_elt_ty) + -- Warn about discarding non-() and non-Empty things in 'monadic' binding + -- We want to suppress spurious value discarded warnings for empty types + -- as the suggestions given in the warnings are wrong. + -- See #8671 and tests T8671.hs, T8671a.hs, T8671b.hs + ; if warn_unused && not (isUnitTy norm_elt_ty) && not (isEmptyTy norm_elt_ty) then diagnosticDs (DsUnusedDoBind rhs elt_ty) else ===================================== testsuite/tests/qualifieddo/should_compile/T8671a.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE QualifiedDo #-} +{-# OPTIONS_GHC "-Wunused-do-bind" #-} + +module Example where + +import T8671adefs qualified as Q + +example :: Q.NotMonad 2 +example = Q.do + Q.incr + Q.incr ===================================== testsuite/tests/qualifieddo/should_compile/T8671adefs.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE DataKinds #-} + +module T8671adefs where + +import GHC.TypeLits + +-- Not actually a useful thing, but illustrates the point +data NotMonad (t :: Nat) + +incr :: NotMonad 1 +incr = undefined + +(>>) :: NotMonad s -> NotMonad t -> NotMonad (s + t) +(>>) = undefined ===================================== testsuite/tests/qualifieddo/should_compile/T8671b.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE QualifiedDo #-} +{-# OPTIONS_GHC "-Wunused-do-bind" #-} + +module Example where + +import T8671bdefs qualified as Q + +example :: Q.NotMonad Bool +example = Q.do + Q.bool 1 2 + Q.bool 3 4 ===================================== testsuite/tests/qualifieddo/should_compile/T8671bdefs.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} + +module T8671bdefs where + + +data NotMonad t = NotMonad + {unNotMonad :: t -> Int} + +run :: t -> NotMonad t -> Int +run t (NotMonad f) = f t + +(>>) :: NotMonad t -> NotMonad t -> NotMonad t +NotMonad l >> NotMonad r = NotMonad $ \t -> l t + r t + +bool :: Int -> Int -> NotMonad Bool +bool t f = NotMonad (\b -> if b then t else f) ===================================== testsuite/tests/qualifieddo/should_compile/all.T ===================================== @@ -2,3 +2,5 @@ setTestOpts(only_ways(['normal'])); test('qdocompile001', normal, compile, ['-v0 -ddump-rn -dsuppress-uniques']) test('qdocompile002', normal, compile, ['-v0']) +test('T8671a', normal, compile, ['--make -v0 -Wall -Wunused-do-bind']) +test('T8671b', normal, compile, ['--make -v0 -Wall -Wunused-do-bind']) \ No newline at end of file ===================================== testsuite/tests/rebindable/T8671.hs ===================================== @@ -0,0 +1,26 @@ +{-# LANGUAGE RebindableSyntax #-} + +module T8671 where + +import Data.Void +import Prelude ((.), ($), Int, id, Num(..)) + + +(>>) :: (b -> c) -> (a -> b) -> (a -> c) +(>>) = (.) + + +return :: Void -> Void +return = absurd + + +run :: a -> (a -> b) -> b +run x f = f x + + +result :: Int +result = run 8 $ do + \n -> n * n + id + (+ 7) + (* 2) ===================================== testsuite/tests/rebindable/all.T ===================================== @@ -46,3 +46,4 @@ test('T20126', normal, compile_fail, ['']) test('T23147', normal, compile, ['']) test('pattern-fails', normal, compile_and_run, ['']) test('simple-rec', normal, compile_and_run, ['']) +test('T8671', normal, compile, ['-v0 -Wall -Wunused-do-bind']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/831effeed06a1ca355ee04cc2ae528f7edee2e4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/831effeed06a1ca355ee04cc2ae528f7edee2e4d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 01:04:40 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 21:04:40 -0400 Subject: [Git][ghc/ghc][master] Fix quantification order for a `op` b and a %m -> b Message-ID: <662314a8adad0_263dd711edce068793@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 8 changed files: - compiler/GHC/Rename/HsType.hs - docs/users_guide/9.12.1-notes.rst - testsuite/tests/linear/should_compile/MultConstructor.hs - testsuite/tests/linear/should_fail/LinearErrOrigin.stderr - testsuite/tests/linear/should_fail/LinearVar.stderr - + testsuite/tests/typecheck/should_compile/T23764.hs - testsuite/tests/typecheck/should_compile/all.T - utils/haddock Changes: ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1731,6 +1731,9 @@ FreeKiTyVars, which notably includes the `extract-` family of functions (extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.). These functions thus promise to keep left-to-right ordering. +Note that for 'HsFunTy m ty1 ty2', we quantify in the order ty1, m, ty2, +since this type is written ty1 %m -> ty2 in the source syntax. + Note [Implicit quantification in type synonyms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We typically bind type/kind variables implicitly when they are in a kind @@ -2056,12 +2059,12 @@ extract_lty (L _ ty) acc HsListTy _ ty -> extract_lty ty acc HsTupleTy _ _ tys -> extract_ltys tys acc HsSumTy _ tys -> extract_ltys tys acc - HsFunTy _ w ty1 ty2 -> extract_lty ty1 $ - extract_lty ty2 $ - extract_hs_arrow w acc + HsFunTy _ m ty1 ty2 -> extract_lty ty1 $ + extract_hs_arrow m $ -- See Note [Ordering of implicit variables] + extract_lty ty2 acc HsIParamTy _ _ ty -> extract_lty ty acc - HsOpTy _ _ ty1 tv ty2 -> extract_tv tv $ - extract_lty ty1 $ + HsOpTy _ _ ty1 tv ty2 -> extract_lty ty1 $ + extract_tv tv $ extract_lty ty2 acc HsParTy _ ty -> extract_lty ty acc HsSpliceTy {} -> acc -- Type splices mention no tvs ===================================== docs/users_guide/9.12.1-notes.rst ===================================== @@ -12,6 +12,17 @@ Language ~~~~~~~~ +- The ordering of variables used for visible type application has been changed in two cases. + It is supposed to be left-to-right, but due to an oversight, it was wrong: + + - in an infix application ``f :: a `op` b``, it is now ``forall a op b.`` rather than + ``forall op a b.`` + - in a linear type ``f :: a %m -> b``, it is now ``forall a m b.`` rather than + ``forall a b m.``. + + This change is backwards-incompatible, although in practice we don't expect it + to cause significant disruption. + Compiler ~~~~~~~~ ===================================== testsuite/tests/linear/should_compile/MultConstructor.hs ===================================== @@ -26,3 +26,9 @@ g2 (MkE x) = x vta :: Int %1 -> Existential Int vta x = MkE @Int @'One x + +h :: a %m -> b +h = h + +vta2 :: Int %1 -> Bool -- see #23764 +vta2 = h @Int @One @Bool ===================================== testsuite/tests/linear/should_fail/LinearErrOrigin.stderr ===================================== @@ -3,13 +3,13 @@ LinearErrOrigin.hs:7:7: error: [GHC-25897] • Couldn't match type ‘p’ with ‘q’ arising from multiplicity of ‘x’ ‘p’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ‘q’ is a rigid type variable bound by the type signature for: - foo :: forall a b (p :: GHC.Types.Multiplicity) + foo :: forall a (p :: GHC.Types.Multiplicity) b (q :: GHC.Types.Multiplicity). (a %p -> b) -> a %q -> b at LinearErrOrigin.hs:6:1-31 ===================================== testsuite/tests/linear/should_fail/LinearVar.stderr ===================================== @@ -5,7 +5,7 @@ LinearVar.hs:5:5: error: [GHC-25897] Actual: a -> b ‘m’ is a rigid type variable bound by the type signature for: - f :: forall a b (m :: GHC.Types.Multiplicity). a %m -> b + f :: forall a (m :: GHC.Types.Multiplicity) b. a %m -> b at LinearVar.hs:4:1-14 • In the expression: undefined :: a -> b In an equation for ‘f’: f = undefined :: a -> b ===================================== testsuite/tests/typecheck/should_compile/T23764.hs ===================================== @@ -0,0 +1,7 @@ +module T23764 where + +f :: a `op` b +f = f + +g :: (Int, Bool) +g = f @Int @(,) @Bool ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -914,3 +914,4 @@ test('T17594f', normal, compile, ['']) test('WarnDefaultedExceptionContext', normal, compile, ['-Wdefaulted-exception-context']) test('T24470b', normal, compile, ['']) test('T24566', [], makefile_test, []) +test('T23764', normal, compile, ['']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 504d4c1842db93704b4c5e158ecc3af7050ba9fe +Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d31fbf6c75440ec99c8bf47c592a10778a226957 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d31fbf6c75440ec99c8bf47c592a10778a226957 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 01:05:50 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 19 Apr 2024 21:05:50 -0400 Subject: [Git][ghc/ghc][master] Make `seq#` a magic Id and inline it in CorePrep (#24124) Message-ID: <662314ee8347f_263dd713a786074855@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/simplStg/should_compile/T15226b.hs - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/simplStg/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -273,6 +273,9 @@ basicKnownKeyNames -- DataToTag dataToTagClassName, + -- seq# + seqHashName, + -- Dynamic toDynName, @@ -1419,6 +1422,10 @@ nonEmptyTyConName = tcQual gHC_INTERNAL_BASE (fsLit "NonEmpty") nonEmptyTyConKey dataToTagClassName :: Name dataToTagClassName = clsQual gHC_MAGIC (fsLit "DataToTag") dataToTagClassKey +-- seq# +seqHashName :: Name +seqHashName = varQual gHC_INTERNAL_IO (fsLit "seq#") seqHashKey + -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName @@ -2373,7 +2380,7 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, seqHashKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 @@ -2408,6 +2415,8 @@ rationalToFloatIdKey, rationalToDoubleIdKey :: Unique rationalToFloatIdKey = mkPreludeMiscIdUnique 132 rationalToDoubleIdKey = mkPreludeMiscIdUnique 133 +seqHashKey = mkPreludeMiscIdUnique 134 + coerceKey :: Unique coerceKey = mkPreludeMiscIdUnique 157 ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -920,11 +920,10 @@ instance Outputable PrimCall where = text "__primcall" <+> ppr pkgId <+> ppr lbl -- | Indicate if a primop is really inline: that is, it isn't out-of-line and it --- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument +-- isn't DataToTagOp which are two primops that evaluate their argument -- hence induce thread/stack/heap changes. primOpIsReallyInline :: PrimOp -> Bool primOpIsReallyInline = \case - SeqOp -> False DataToTagSmallOp -> False DataToTagLargeOp -> False - p -> not (primOpOutOfLine p) + p -> not (primOpOutOfLine p) ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3656,13 +3656,6 @@ primop SparkOp "spark#" GenPrimOp with effect = ReadWriteEffect code_size = { primOpCodeSizeForeignCall } --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -primop SeqOp "seq#" GenPrimOp - a -> State# s -> (# State# s, a #) - with - effect = ThrowsException - work_free = True -- seq# does work iff its lifted arg does work - primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -855,7 +855,6 @@ primOpRules nm = \case AddrAddOp -> mkPrimOpRule nm 2 [ rightIdentityPlatform zeroi ] - SeqOp -> mkPrimOpRule nm 4 [ seqRule ] SparkOp -> mkPrimOpRule nm 4 [ sparkRule ] _ -> Nothing @@ -2072,60 +2071,6 @@ unsafeEqualityProofRule * * ********************************************************************* -} -{- Note [seq# magic] -~~~~~~~~~~~~~~~~~~~~ -The primop - seq# :: forall a s . a -> State# s -> (# State# s, a #) - -is /not/ the same as the Prelude function seq :: a -> b -> b -as you can see from its type. In fact, seq# is the implementation -mechanism for 'evaluate' - - evaluate :: a -> IO a - evaluate a = IO $ \s -> seq# a s - -The semantics of seq# is - * evaluate its first argument - * and return it - -Things to note - -* Why do we need a primop at all? That is, instead of - case seq# x s of (# x, s #) -> blah - why not instead say this? - case x of { DEFAULT -> blah } - - Reason (see #5129): if we saw - catch# (\s -> case x of { DEFAULT -> raiseIO# exn s }) handler - - then we'd drop the 'case x' because the body of the case is bottom - anyway. But we don't want to do that; the whole /point/ of - seq#/evaluate is to evaluate 'x' first in the IO monad. - - In short, we /always/ evaluate the first argument and never - just discard it. - -* Why return the value? So that we can control sharing of seq'd - values: in - let x = e in x `seq` ... x ... - We don't want to inline x, so better to represent it as - let x = e in case seq# x RW of (# _, x' #) -> ... x' ... - also it matches the type of rseq in the Eval monad. - -Implementing seq#. The compiler has magic for SeqOp in - -- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) - -- GHC.StgToCmm.Expr.cgExpr, and cgCase: special case for seq# - -- Simplify.addEvals records evaluated-ness for the result; see - Note [Adding evaluatedness info to pattern-bound variables] - in GHC.Core.Opt.Simplify.Iteration - -- Likewise, GHC.Stg.InferTags.inferTagExpr knows that seq# returns a - properly-tagged pointer inside of its unboxed-tuple result. --} - seqRule :: RuleM CoreExpr seqRule = do [Type _ty_a, Type _ty_s, a, s] <- getArgs @@ -2213,7 +2158,9 @@ builtinRules platform <- getPlatform return $ Var (primOpId IntAndOp) `App` arg `App` mkIntVal platform (d - 1) - ] + ], + + mkBasicRule seqHashName 4 seqRule ] ++ builtinBignumRules {-# NOINLINE builtinRules #-} ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.FamInstEnv import GHC.Core.Opt.Arity ( typeArity ) import GHC.Core.Opt.WorkWrap.Utils +import GHC.Builtin.Names import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) @@ -602,16 +603,21 @@ exprMayThrowPreciseException :: FamInstEnvs -> CoreExpr -> Bool exprMayThrowPreciseException envs e | not (forcesRealWorld envs (exprType e)) = False -- 1. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn , Just op <- isPrimOpId_maybe f , op /= RaiseIOOp = False -- 2. in the Note - | (Var f, _) <- collectArgs e + | Var f <- fn + , f `hasKey` seqHashKey + = False -- 3. in the Note + | Var f <- fn , Just fcall <- isFCallId_maybe f , not (isSafeForeignCall fcall) - = False -- 3. in the Note + = False -- 4. in the Note | otherwise = True -- _. in the Note + where + (fn, _) = collectArgs e -- | Recognises types that are -- * @State# RealWorld@ @@ -799,14 +805,18 @@ For an expression @f a1 ... an :: ty@ we determine that (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# - 3. False If f is an unsafe FFI call ('PlayRisky') + 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. + 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. - 3. Unsafe FFI calls may not interact with the RTS (to throw, for example). + 3. `seq#` used to be a primop that did not throw a precise exception. + We keep it that way for back-compat. + See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. + 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because @@ -814,7 +824,8 @@ We *need* to return False in those cases, because 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. - 3. We would lose strictness for code like GHC.Fingerprint.fingerprintData, + 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. + 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -58,9 +58,8 @@ import GHC.Types.Unique ( hasKey ) import GHC.Types.Basic import GHC.Types.Tickish import GHC.Types.Var ( isTyCoVar ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Names( runRWKey, seqHashKey ) import GHC.Data.Maybe ( isNothing, orElse, mapMaybe ) import GHC.Data.FastString @@ -3427,7 +3426,7 @@ NB: simplLamBndrs preserves this eval info In addition to handling data constructor fields with !s, addEvals also records the fact that the result of seq# is always in WHNF. -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. Example (#15226): +See Note [seq# magic] in GHC.Types.Id.Make. Example (#15226): case seq# v s of (# s', v' #) -> E @@ -3449,7 +3448,7 @@ addEvals scrut con vs -- Use stripNArgs rather than collectArgsTicks to avoid building -- a list of arguments only to throw it away immediately. , Just (Var f) <- stripNArgs 4 scr - , Just SeqOp <- isPrimOpId_maybe f + , f `hasKey` seqHashKey , let x' = zapIdOccInfoAndSetEvald MarkedStrict x = [s, x'] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -141,19 +141,19 @@ Note [CorePrep invariants] Here is the syntax of the Core produced by CorePrep: Trivial expressions - arg ::= lit | var - | arg ty | /\a. arg - | truv co | /\c. arg | arg |> co + arg ::= lit | var + | arg ty | /\a. arg + | co | arg |> co Applications - app ::= lit | var | app arg | app ty | app co | app |> co + app ::= lit | var | app arg | app ty | app co | app |> co Expressions body ::= app - | let(rec) x = rhs in body -- Boxed only - | case app of pat -> body - | /\a. body | /\c. body - | body |> co + | let(rec) x = rhs in body -- Boxed only + | case body of pat -> body + | /\a. body | /\c. body + | body |> co Right hand sides (only place where value lambdas can occur) rhs ::= /\a.rhs | \x.rhs | body @@ -347,6 +347,13 @@ There are 3 main categories of floats, encoded in the `FloatingBind` type: bind the unsafe coercion field of the Refl constructor. * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep]. +It is quite essential that CorePrep *does not* rearrange the order in which +evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers +the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does +not attempt to reorder the telescope of Floats or float out out of non-floated +binding sites (such as Case alts) in the first place; for that it would have to +do some kind of data dependency analysis. + Note [Floating out of top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NB: we do need to float out of top-level bindings @@ -637,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env dmd is_unlifted bndr1 rhs1 + new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -690,7 +697,7 @@ cpeBind top_lvl env (Rec pairs) -- group into a single giant Rec add_float (Float bind bound _) prs2 | bound /= CaseBound - || all (definitelyLiftedType . idType) (bindersOf bind) + || all (not . isUnliftedType . idType) (bindersOf bind) -- The latter check is hit in -O0 (i.e., flavours quick, devel2) -- for dictionary args which haven't been floated out yet, #24102. -- They are preferably CaseBound, but since they are lifted we may @@ -722,7 +729,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env topDmd False v rhs2 + ; let float = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -888,13 +895,23 @@ cpeRhsE env (Case scrut bndr ty alts) ; (env', bndr2) <- cpCloneBndr env bndr ; let alts' | cp_catchNonexhaustiveCases $ cpe_config env + -- Suppose the alternatives do not cover all the data constructors of the type. + -- That may be fine: perhaps an earlier case has dealt with the missing cases. + -- But this is a relatively sophisticated property, so we provide a GHC-debugging flag + -- `-fcatch-nonexhaustive-cases` which adds a DEFAULT alternative to such cases + -- (This alternative will only be taken if there is a bug in GHC.) , not (altsAreExhaustive alts) = addDefault alts (Just err) | otherwise = alts where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative" ; alts'' <- mapM (sat_alt env') alts' - ; return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } + ; case alts'' of + [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] + | let is_unlifted = isUnliftedType (idType bndr2) + , let float = mkCaseFloat is_unlifted bndr2 scrut' + -> return (snocFloat floats float, rhs) + _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) = do { (env2, bs') <- cpCloneBndrs env bs @@ -983,14 +1000,14 @@ and it's extra work. -- CpeApp: produces a result satisfying CpeApp -- --------------------------------------------------------------------------- -data ArgInfo = CpeApp CoreArg - | CpeCast Coercion - | CpeTick CoreTickish +data ArgInfo = AIApp CoreArg -- NB: Not a CpeApp yet + | AICast Coercion + | AITick CoreTickish instance Outputable ArgInfo where - ppr (CpeApp arg) = text "app" <+> ppr arg - ppr (CpeCast co) = text "cast" <+> ppr co - ppr (CpeTick tick) = text "tick" <+> ppr tick + ppr (AIApp arg) = text "app" <+> ppr arg + ppr (AICast co) = text "cast" <+> ppr co + ppr (AITick tick) = text "tick" <+> ppr tick {- Note [Ticks and mandatory eta expansion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,7 +1049,7 @@ cpe_app filters out the tick as a underscoped tick on the expression body of the eta-expansion lambdas. Giving us `\x -> Tick (tagToEnum# @Bool x)`. -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) --- May return a CpeRhs because of saturating primops +-- May return a CpeRhs (instead of CpeApp) because of saturating primops cpeApp top_env expr = do { let (terminal, args) = collect_args expr -- ; pprTraceM "cpeApp" $ (ppr expr) @@ -1051,9 +1068,9 @@ cpeApp top_env expr collect_args e = go e [] where go (App fun arg) as - = go fun (CpeApp arg : as) + = go fun (AIApp arg : as) go (Cast fun co) as - = go fun (CpeCast co : as) + = go fun (AICast co : as) go (Tick tickish fun) as -- Profiling ticks are slightly less strict so we expand their scope -- if they cover partial applications of things like primOps. @@ -1066,7 +1083,7 @@ cpeApp top_env expr , etaExpansionTick head' tickish = (head,as') where - (head,as') = go fun (CpeTick tickish : as) + (head,as') = go fun (AITick tickish : as) -- Terminal could still be an app if it's wrapped by a tick. -- E.g. Tick (f x) can give us (f x) as terminal. @@ -1076,7 +1093,7 @@ cpeApp top_env expr -> CoreExpr -- The thing we are calling -> [ArgInfo] -> UniqSM (Floats, CpeRhs) - cpe_app env (Var f) (CpeApp Type{} : CpeApp arg : args) + cpe_app env (Var f) (AIApp Type{} : AIApp arg : args) | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and -- See Note [lazyId magic] in GHC.Types.Id.Make || f `hasKey` noinlineIdKey || f `hasKey` noinlineConstraintIdKey @@ -1102,24 +1119,39 @@ cpeApp top_env expr in cpe_app env terminal (args' ++ args) -- runRW# magic - cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) + cpe_app env (Var f) (AIApp _runtimeRep at Type{} : AIApp _type at Type{} : AIApp arg : rest) | f `hasKey` runRWKey -- N.B. While it may appear that n == 1 in the case of runRW# -- applications, keep in mind that we may have applications that return - , has_value_arg (CpeApp arg : rest) + , has_value_arg (AIApp arg : rest) -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest - _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) + _ -> cpe_app env arg (AIApp (Var realWorldPrimId) : rest) -- TODO: What about casts? where has_value_arg [] = False - has_value_arg (CpeApp arg:_rest) + has_value_arg (AIApp arg:_rest) | not (isTyCoArg arg) = True has_value_arg (_:rest) = has_value_arg rest + -- See Note [seq# magic]. This is the step for CorePrep + cpe_app env (Var f) [AIApp (Type ty), AIApp _st_ty at Type{}, AIApp thing, AIApp token] + | f `hasKey` seqHashKey + -- seq# thing token + -- ==> case token of s { __DEFAULT -> + -- case thing of res { __DEFAULT -> (# token, res#) } }, + -- allocating CaseBound Floats for token and thing as needed + = do { (floats1, token) <- cpeArg env topDmd token + ; (floats2, thing) <- cpeBody env thing + ; case_bndr <- newVar ty + ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] + ; let is_unlifted = False -- otherwise seq# would not type-check + ; let float = mkCaseFloat is_unlifted case_bndr thing + ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } + cpe_app env (Var v) args = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -1166,13 +1198,13 @@ cpeApp top_env expr go [] !n = n go (info:infos) n = case info of - CpeCast {} -> go infos n - CpeTick tickish + AICast {} -> go infos n + AITick tickish | tickishFloatable tickish -> go infos n -- If we can't guarantee a tick will be floated out of the application -- we can't guarantee the value args following it will be applied. | otherwise -> n - CpeApp e -> go infos n' + AIApp e -> go infos n' where !n' | isTypeArg e = n @@ -1228,17 +1260,17 @@ cpeApp top_env expr let tick_fun = foldr mkTick fun' rt_ticks in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) + AIApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) + AIApp (Coercion co) -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - CpeApp arg -> do + AIApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) @@ -1247,13 +1279,13 @@ cpeApp top_env expr (fs, arg') <- cpeArg top_env ss1 arg rebuild_app' env as (App fun' arg') (fs `zipFloats` floats) ss_rest rt_ticks (req_depth-1) - CpeCast co + AICast co -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co -- See Note [Ticks and mandatory eta expansion] - CpeTick tickish + AITick tickish | tickishPlace tickish == PlaceRuntime , req_depth > 0 -> assert (isProfTick tickish) $ @@ -1533,20 +1565,26 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- newVar arg_ty - -- See Note [Eta expansion of arguments in CorePrep] - ; let arity = cpeArgArity env dec arg2 + else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + -- See Note [Pin demand info on floats] + ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 - arg_float = mkNonRecFloat env dmd is_unlifted v arg3 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg_float = mkNonRecFloat env is_unlifted v arg3 ; return (snocFloat floats2 arg_float, varToCoreExpr v) } } -cpeArgArity :: CorePrepEnv -> FloatDecision -> CoreArg -> Arity +cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity -- ^ See Note [Eta expansion of arguments in CorePrep] -- Returning 0 means "no eta-expansion"; see cpeEtaExpand -cpeArgArity env float_decision arg +cpeArgArity env float_decision floats1 arg | FloatNone <- float_decision - = 0 -- Crucial short-cut + -- If we did not float + , not (isEmptyFloats floats1) + -- ... but there was something to float + , fs_info floats1 `floatsAtLeastAsFarAs` LazyContextFloatable + -- ... and we could have floated it out of a lazy arg + = 0 -- ... then short-cut, because floats1 is likely expensive! -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep] | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2 @@ -1724,7 +1762,7 @@ There is a nasty Wrinkle: The alternative would be to fix Note [Eta expansion for join points], but that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like +(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like let in rhs where is non-empty and can't be floated out of a lazy context (see `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0 @@ -1756,6 +1794,51 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pin demand info on floated lets, so that we can see the one-shot thunks. +For example, + f (g x) +where `f` uses its argument at least once, creates a Float for `y = g x` and we +should better pin appropriate demand info on `y`. + +Note [Flatten case-binds] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have the following call, where f is strict: + f (case x of DEFAULT -> blah) +(For the moment, ignore the fact that the Simplifier will have floated that +`case` out because `f` is strict.) +In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` + + Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + +with the call `f a`. When we wrap that `Float` we will get + + case (case x of y { DEFAULT -> blah }) of a { DEFAULT -> f a } + +which is a bit silly. Actually the rest of the back end can cope with nested +cases like this, but it is harder to read and we'd prefer the more direct: + + case x of y { DEFAULT -> + case blah of a { DEFAULT -> f a }} + +This is easy to avoid: turn that + + case x of DEFAULT -> blah + +into a FloatingBind of its own. This is easily done in the Case +equation for `cpsRhsE`. Then our example will generate /two/ floats: + + Float (y = x) CaseBound top_lvl + Float (a = blah) CaseBound top_lvl + +and we'll end up with nested cases. + +Of course, the Simplifier never leaves us with an argument like this, but we +/can/ see + + data T a = T !a + ... case seq# (case x of y { __DEFAULT -> T y }) s of (# s', x' #) -> rhs + +and the above footwork in cpsRhsE avoids generating a nested case. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1869,6 +1952,9 @@ The `FloatInfo` of a `Float` describes how far it can float without * Any binding is at least `StrictContextFloatable`, meaning we may float it out of a strict context such as `f <>` where `f` is strict. + We may never float out of a Case alternative `case e of p -> <>`, though, + even if we made sure that `p` does not capture any variables of the float, + because that risks sequencing guarantees of Note [seq# magic]. * A binding is `LazyContextFloatable` if we may float it out of a lazy context such as `let x = <> in Just x`. @@ -2035,23 +2121,42 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkNonRecFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env dmd is_unlifted bndr rhs +mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind +mkCaseFloat is_unlifted bndr scrut + = Float (NonRec bndr scrut) bound info + where + (bound, info) +{- +Eventually we want the following code, when #20749 is fixed. + | is_lifted, is_hnf = (LetBound, TopLvlFloatable) + -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should + -- let-bind `StrictBox x'` after Note [Flatten case-binds]. +-} + | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | otherwise = (CaseBound, StrictContextFloatable) + -- For a Case, we never want to drop the eval; hence no need to test + -- for ok-for-spec-eval + _is_lifted = not is_unlifted + _is_hnf = exprIsHNF scrut + +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) -- <+> ppr is_lifted <+> ppr is_strict -- <+> ppr ok_for_spec -- $$ ppr rhs) $ - Float (NonRec bndr' rhs) bound info + Float (NonRec bndr rhs) bound info where - bndr' = setIdDemandInfo bndr dmd -- See Note [Pin demand info on floats] - (bound,info) + (bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs -- (but SG thinks that in principle, we should) | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for unlifted DataCon workers/wrappers - -- until #17521 is fixed + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2069,6 +2174,7 @@ mkNonRecFloat env dmd is_unlifted bndr rhs is_lifted = not is_unlifted is_hnf = exprIsHNF rhs + dmd = idDemandInfo bndr is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) @@ -2101,7 +2207,7 @@ deFloatTop floats where get (Float b _ TopLvlFloatable) bs = get_bind b : bs - get b _ = pprPanic "corePrepPgm" (ppr b) + get b _ = pprPanic "deFloatTop" (ppr b) -- See Note [Dead code in CorePrep] get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) @@ -2600,7 +2706,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs + litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -19,7 +19,6 @@ import GHC.Types.Basic ( CbvMark (..) ) import GHC.Types.Unique.Supply (mkSplitUniqSupply) import GHC.Types.RepType (dataConRuntimeRepStrictness) import GHC.Core (AltCon(..)) -import GHC.Builtin.PrimOps ( PrimOp(..) ) import Data.List (mapAccumL) import GHC.Utils.Outputable import GHC.Utils.Misc( zipWithEqual, zipEqual, notNull ) @@ -333,21 +332,10 @@ inferTagExpr env (StgTick tick body) (info, body') = inferTagExpr env body inferTagExpr _ (StgOpApp op args ty) - | StgPrimOp SeqOp <- op - -- Recall seq# :: a -> State# s -> (# State# s, a #) - -- However the output State# token has been unarised away, - -- so we now effectively have - -- seq# :: a -> State# s -> (# a #) - -- The key point is the result of `seq#` is guaranteed evaluated and properly - -- tagged (because that result comes directly from evaluating the arg), - -- and we want tag inference to reflect that knowledge (#15226). - -- Hence `TagTuple [TagProper]`. - -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold - = (TagTuple [TagProper], StgOpApp op args ty) - -- Do any other primops guarantee to return a properly tagged value? - -- Probably not, and that is the conservative assumption anyway. + -- Which primops guarantee to return a properly tagged value? + -- Probably none, and that is the conservative assumption anyway. -- (And foreign calls definitely need not make promises.) - | otherwise = (TagDunno, StgOpApp op args ty) + = (TagDunno, StgOpApp op args ty) inferTagExpr env (StgLet ext bind body) = (info, StgLet ext bind' body') ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -498,7 +498,7 @@ So for these we should call `rewriteArgs`. rewriteOpApp :: InferStgExpr -> RM TgStgExpr rewriteOpApp (StgOpApp op args res_ty) = case op of op@(StgPrimOp primOp) - | primOp == SeqOp || primOp == DataToTagSmallOp || primOp == DataToTagLargeOp + | primOp == DataToTagSmallOp || primOp == DataToTagLargeOp -- see Note [Rewriting primop arguments] -> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty _ -> pure $! StgOpApp op args res_ty ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -67,11 +67,6 @@ cgExpr :: CgStgExpr -> FCode ReturnKind cgExpr (StgApp fun args) = cgIdApp fun args --- seq# a s ==> a --- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = - cgIdApp a [] - -- dataToTagSmall# :: a_levpoly -> Int# -- See Note [DataToTag overview] in GHC.Tc.Instance.Class, -- particularly wrinkles H3 and DTW4 @@ -550,27 +545,6 @@ cgCase scrut@(StgApp v []) _ (PrimAlt _) _ ; return AssignedDirectly } -{- Note [Handle seq#] -~~~~~~~~~~~~~~~~~~~~~ -See Note [seq# magic] in GHC.Core.Opt.ConstantFold. -The special case for seq# in cgCase does this: - - case seq# a s of v - (# s', a' #) -> e -==> - case a of v - (# s', a' #) -> e - -(taking advantage of the fact that the return convention for (# State#, a #) -is the same as the return convention for just 'a') --} - -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts - = -- Note [Handle seq#] - -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold - -- Use the same return convention as vanilla 'a'. - cgCase (StgApp a []) bndr alt_type alts - {- Note [Eliminate trivial Solo# continuations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1729,7 +1729,6 @@ emitPrimOp cfg primop = CompactAdd -> alwaysExternal CompactAddWithSharing -> alwaysExternal CompactSize -> alwaysExternal - SeqOp -> alwaysExternal GetSparkOp -> alwaysExternal NumSparks -> alwaysExternal DataToTagSmallOp -> alwaysExternal ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1012,7 +1012,6 @@ genPrim prof bound ty op = case op of ParOp -> \[r] [_a] -> pure $ PrimInline $ r |= zero_ SparkOp -> \[r] [a] -> pure $ PrimInline $ r |= a - SeqOp -> \[_r] [e] -> pure $ PRPrimCall $ returnS (app "h$e" [e]) NumSparks -> \[r] [] -> pure $ PrimInline $ r |= zero_ ------------------------------ Tag to enum stuff -------------------------------- ===================================== compiler/GHC/StgToJS/Utils.hs ===================================== @@ -61,7 +61,7 @@ import GHC.Stg.Syntax import GHC.Tc.Utils.TcType import GHC.Builtin.Names -import GHC.Builtin.PrimOps (PrimOp(SeqOp), primOpIsReallyInline) +import GHC.Builtin.PrimOps (primOpIsReallyInline) import GHC.Types.RepType import GHC.Types.Var @@ -437,8 +437,6 @@ isInlineExpr = \case -> True StgOpApp (StgFCallOp f _) _ _ -> isInlineForeignCall f - StgOpApp (StgPrimOp SeqOp) [StgVarArg e] t - -> ctxIsEvaluated e || isStrictType t StgOpApp (StgPrimOp op) _ _ -> primOpIsReallyInline op StgOpApp (StgPrimCallOp _c) _ _ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -157,12 +157,15 @@ The magicIds * May have IdInfo that differs from what would be imported from GHC.Magic.hi. For example, 'lazy' gets a lazy strictness signature, per Note [lazyId magic]. - The two remaining identifiers in GHC.Magic, runRW# and inline, are not listed - in magicIds: they have special behavior but they can be known-key and + The two remaining identifiers in GHC.Magic, runRW# and inline, are not + listed in magicIds: they have special behavior but they can be known-key and not wired-in. - runRW#: see Note [Simplification of runRW#] in Prep, runRW# code in - Simplifier, Note [Linting of runRW#]. - inline: see Note [inlineId magic] + Similarly for GHC.Internal.IO.seq# and GHC.Internal.Exts.considerAccessible. + runRW#: see Note [Simplification of runRW#] in Prep, + runRW# code in Simplifier, Note [Linting of runRW#]. + seq#: see Note [seq# magic] + inline: see Note [inlineId magic] + considerAccessible: see Note [considerAccessible] -} wiredInIds :: [Id] @@ -2235,8 +2238,99 @@ This is crucial: otherwise, we could import an unfolding in which * To defeat the specialiser when we have incoherent instances. See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. +Note [seq# magic] +~~~~~~~~~~~~~~~~~ +The purpose of the magic Id (See Note [magicIds]) + + seq# :: forall a s . a -> State# s -> (# State# s, a #) + +is to elevate evaluation of its argument `a` into an observable side effect. +This implies that GHC's optimisations must preserve the evaluation "exactly +here", in the state thread. + +The main use of seq# is to implement `evaluate` + + evaluate :: a -> IO a + evaluate a = IO $ \s -> seq# a s + +Its (NOINLINE) definition in GHC.Magic is simply + + seq# a s = let !a' = lazy a in (# s, a' #) + +Things to note + +(SEQ1) + It must be NOINLINE, because otherwise the eval !a' would be decoupled from + the state token s, and GHC's optimisations, in particular strictness analysis, + would happily move the eval around. + + However, we *do* inline saturated applications of seq# in CorePrep, where + evaluation order is fixed; see the implementation notes below. + This is one reason why we need seq# to be known-key. + +(SEQ2) + The use of `lazy` ensures that strictness analysis does not see the eval + that takes place, so the final demand signature is , not <1L>. + This is important for a definition like + + foo x y = evaluate y >> evaluate x + + Although both y and x are ultimately evaluated, the user made it clear + they want to evaluate y *before* x. + But if strictness analysis sees the evals, it infers foo as strict in + both parameters. This strictness would be exploited in the backend by + picking a call-by-value calling convention for foo, one that would evaluate + x *before* y. Nononono! + + Because the definition of seq# uses `lazy`, it must live in a different module + (GHC.Internal.IO); otherwise strictness analysis uses its own strictness + signature for the definition of `lazy` instead of the one we wire in. + +(SEQ3) + Why does seq# return the value? Consider + let x = e in + case seq# x s of (# _, x' #) -> ... x' ... case x' of __DEFAULT -> ... + Here, we could simply use x instead of x', but doing so would + introduce an unnecessary indirection and tag check at runtime; + also we can attach an evaldUnfolding to x' to discard any + subsequent evals such as the `case x' of __DEFAULT`. + +Implementing seq#. The compiler has magic for `seq#` in + +- GHC.Core.Opt.ConstantFold.seqRule: eliminate (seq# s) + +- Simplify.addEvals records evaluated-ness for the result (cf. (SEQ3)); see + Note [Adding evaluatedness info to pattern-bound variables] + in GHC.Core.Opt.Simplify.Iteration + +- GHC.Core.Opt.DmdAnal.exprMayThrowPreciseException: + Historically, seq# used to be a primop, and the majority of primops + should return False in exprMayThrowPreciseException, so we do the same + for seq# for back compat. + +- GHC.CoreToStg.Prep: Inline saturated applications to a Case, e.g., + + seq# (f 13) s + ==> + case f 13 of sat of __DEFAULT -> (# s, sat #) + + This is implemented in `cpeApp`, not unlike Note [runRW magic]. + We are only inlining seq#, leaving opportunities for case-of-known-con + behind that are easily picked up by Unarise: + + case seq# f 13 s of (# s', r #) -> rhs + ==> {Prep} + case f 13 of sat of __DEFAULT -> case (# s, sat #) of (# s', r #) -> rhs + ==> {Unarise} + case f 13 of sat of __DEFAULT -> rhs[s/s',sat/r] + + Note that CorePrep really allocates a CaseBound FloatingBind for `f 13`. + That's OK, because the telescope of Floats always stays in the same order + and won't be floated out of binders, so all guarantees of evaluation order + provided by seq# are upheld. + Note [oneShot magic] -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ In the context of making left-folds fuse somewhat okish (see ticket #7994 and Note [Left folds via right fold]) it was determined that it would be useful if library authors could explicitly tell the compiler that a certain lambda is ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Base , unpackNBytes# -- * Magic combinators - , inline, noinline, lazy, oneShot, runRW#, DataToTag(..) + , inline, noinline, lazy, oneShot, runRW#, seq#, DataToTag(..) , WithDict(withDict) -- * Functions over 'Bool' @@ -148,6 +148,7 @@ import GHC.Prim hiding (dataToTagLarge#, dataToTagSmall#, whereFrom#) import GHC.Prim.Ext import GHC.Prim.PtrEq import GHC.Internal.Err +import GHC.Internal.IO (seq#) import GHC.Internal.Maybe import GHC.Types hiding ( Unit#, ===================================== libraries/base/src/GHC/Exts.hs ===================================== @@ -90,6 +90,7 @@ module GHC.Exts lazy, oneShot, considerAccessible, + seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC(..), ===================================== libraries/ghc-internal/src/GHC/Internal/Exts.hs ===================================== @@ -105,7 +105,7 @@ module GHC.Internal.Exts currentCallStack, -- * Ids with special behaviour - inline, noinline, lazy, oneShot, considerAccessible, + inline, noinline, lazy, oneShot, considerAccessible, seq#, -- * SpecConstr annotations SpecConstrAnnotation(..), SPEC (..), @@ -278,6 +278,7 @@ import GHC.Types import qualified GHC.Prim.Ext import GHC.Internal.ArrayArray import GHC.Internal.Base hiding ( coerce ) +import GHC.Internal.IO (seq#) import GHC.Internal.Ptr import GHC.Internal.Stack import GHC.Internal.IsList (IsList(..)) -- for re-export ===================================== libraries/ghc-internal/src/GHC/Internal/IO.hs ===================================== @@ -44,7 +44,7 @@ module GHC.Internal.IO ( mask, mask_, uninterruptibleMask, uninterruptibleMask_, MaskingState(..), getMaskingState, unsafeUnmask, interruptible, - onException, bracket, finally, evaluate, + onException, bracket, finally, evaluate, seq#, mkUserError ) where @@ -440,6 +440,14 @@ a `finally` sequel = _ <- sequel return r + +-- | The primitive used to implement 'GHC.IO.evaluate'. +-- Prefer to use 'GHC.IO.evaluate' whenever possible! +seq# :: forall a s. a -> State# s -> (# State# s, a #) +-- See Note [seq# magic] in GHC.Types.Id.Make +{-# NOINLINE seq# #-} -- seq# is inlined manually in CorePrep +seq# a s = let !a' = lazy a in (# s, a' #) + -- | Evaluate the argument to weak head normal form. -- -- 'evaluate' is typically used to uncover any exceptions that a lazy value ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -58,8 +58,8 @@ inline x = x -- | The call @noinline f@ arranges that @f@ will not be inlined. -- It is removed during CorePrep so that its use imposes no overhead -- (besides the fact that it blocks inlining.) -{-# NOINLINE noinline #-} noinline :: a -> a +{-# NOINLINE noinline #-} -- noinline is inlined manually in CorePrep noinline x = x -- | The 'lazy' function restrains strictness analysis a little. The @@ -79,6 +79,7 @@ noinline x = x -- If 'lazy' were not lazy, 'Control.Parallel.par' would look strict in -- @y@ which would defeat the whole purpose of 'Control.Parallel.par'. lazy :: a -> a +{-# NOINLINE lazy #-} -- lazy is inlined manually in CorePrep lazy x = x -- Implementation note: its strictness and unfolding are over-ridden -- by the definition in GHC.Types.Id.Make; in both cases to nothing at all. ===================================== testsuite/tests/core-to-stg/T24124.hs ===================================== @@ -0,0 +1,11 @@ +module T15226b where + +import Control.Exception + +data StrictPair a b = MkStrictPair !a !b + +testFun :: a -> b -> IO (StrictPair a b) +testFun x y = do + x' <- evaluate x + evaluate (MkStrictPair x' y) + -- This MkStrictPair application should not result in a thunk at run-time ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -0,0 +1,46 @@ + +==================== Final STG: ==================== +T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] + :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = + {} \r [conrep conrep1] + case conrep of conrep2 { + __DEFAULT -> + case conrep1 of conrep3 { + __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; + }; + }; + +T15226b.testFun1 + :: forall a b. + a + -> b + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [x y void] + case x of sat { + __DEFAULT -> + case y of conrep { + __DEFAULT -> + case T15226b.MkStrictPair [sat conrep] of sat { + __DEFAULT -> (# #) [sat]; + }; + }; + }; + +T15226b.testFun + :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) +[GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = + {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; + +T15226b.MkStrictPair [InlPrag=CONLIKE] + :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b +[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta eta] + case eta of eta { + __DEFAULT -> + case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; + }; + + ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -4,4 +4,5 @@ test('T19700', normal, compile, ['-O']) test('T23270', [grep_errmsg(r'patError')], compile, ['-O0 -dsuppress-uniques -ddump-prep']) test('T23914', normal, compile, ['-O']) test('T14895', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) +test('T24124', normal, compile, ['-O -ddump-stg-final -dno-typeable-binds -dsuppress-uniques']) test('T24463', normal, compile, ['-O']) ===================================== testsuite/tests/ghci.debugger/scripts/T19394.stdout ===================================== @@ -7,5 +7,5 @@ Identifier ‘void#’ is not eligible for the :print, :sprint or :force command error = (_t1::GHC.Internal.Stack.Types.HasCallStack => [Char] -> a) oneShot = (_t2::(a -> b) -> a -> b) xor# = (_t3::Word# -> Word# -> Word#) -seq# = (_t4::a -> State# d -> (# State# d, a #)) +seq# = (_t4::a -> State# s -> (# State# s, a #)) lazy = (_t5::a -> a) ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6655,7 +6655,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -4584,7 +4584,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6835,7 +6835,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -4581,7 +4581,7 @@ module GHC.Base where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) sequence :: forall (m :: * -> *) a. Monad m => [m a] -> m [a] setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d @@ -6686,7 +6686,7 @@ module GHC.Exts where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a d. a -> State# d -> (# State# d, a #) + seq# :: forall a s. a -> State# s -> (# State# s, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld ===================================== testsuite/tests/simplStg/should_compile/T15226b.hs ===================================== @@ -2,10 +2,9 @@ module T15226b where import Control.Exception -data StrictPair a b = MkStrictPair !a !b +data Str a = Str !a -testFun :: a -> b -> IO (StrictPair a b) -testFun x y = do +bar :: Maybe a -> IO (Str (Maybe a)) +bar x = do x' <- evaluate x - evaluate (MkStrictPair x' y) - -- tag inference should not insert an eval for x' in making the strict pair + pure (Str x') ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -1,48 +1,37 @@ ==================== Final STG: ==================== -T15226b.$WMkStrictPair [InlPrag=INLINE[final] CONLIKE] - :: forall a b. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataConWrapper], Arity=2, Str=, Unf=OtherCon []] = - {} \r [conrep conrep1] - case conrep of conrep2 { - __DEFAULT -> - case conrep1 of conrep3 { - __DEFAULT -> T15226b.MkStrictPair [conrep2 conrep3]; - }; - }; +T15226b.$WStr [InlPrag=INLINE[final] CONLIKE] + :: forall a. a %1 -> T15226b.Str a +[GblId[DataConWrapper], Arity=1, Str=, Unf=OtherCon []] = + {} \r [conrep] + case conrep of conrep1 { __DEFAULT -> T15226b.Str [conrep1]; }; -T15226b.testFun1 - :: forall a b. - a - -> b +T15226b.bar1 + :: forall a. + GHC.Internal.Maybe.Maybe a -> GHC.Prim.State# GHC.Prim.RealWorld - -> (# GHC.Prim.State# GHC.Prim.RealWorld, T15226b.StrictPair a b #) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [x y void] - case seq# [x GHC.Prim.void#] of ds1 { - (# #) ipv1 [Occ=Once1] -> + -> (# GHC.Prim.State# GHC.Prim.RealWorld, + T15226b.Str (GHC.Internal.Maybe.Maybe a) #) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [x void] + case x of sat { + __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.StrictPair a b + sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = - {ipv1, y} \u [] - case y of conrep { - __DEFAULT -> T15226b.MkStrictPair [ipv1 conrep]; - }; - } in seq# [sat GHC.Prim.void#]; + T15226b.Str! [sat]; + } in (# #) [sat]; }; -T15226b.testFun - :: forall a b. a -> b -> GHC.Types.IO (T15226b.StrictPair a b) -[GblId, Arity=3, Str=, Unf=OtherCon []] = - {} \r [eta eta void] T15226b.testFun1 eta eta GHC.Prim.void#; +T15226b.bar + :: forall a. + GHC.Internal.Maybe.Maybe a + -> GHC.Types.IO (T15226b.Str (GHC.Internal.Maybe.Maybe a)) +[GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = + {} \r [eta void] T15226b.bar1 eta GHC.Prim.void#; -T15226b.MkStrictPair [InlPrag=CONLIKE] - :: forall {a} {b}. a %1 -> b %1 -> T15226b.StrictPair a b -[GblId[DataCon], Arity=2, Caf=NoCafRefs, Unf=OtherCon []] = - {} \r [eta eta] - case eta of eta { - __DEFAULT -> - case eta of eta { __DEFAULT -> T15226b.MkStrictPair [eta eta]; }; - }; +T15226b.Str [InlPrag=CONLIKE] :: forall {a}. a %1 -> T15226b.Str a +[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] = + {} \r [eta] case eta of eta { __DEFAULT -> T15226b.Str [eta]; }; ===================================== testsuite/tests/simplStg/should_compile/all.T ===================================== @@ -10,6 +10,7 @@ def f( name, opts ): setTestOpts(f) test('T13588', [ grep_errmsg('case') ] , compile, ['-dverbose-stg2stg -fno-worker-wrapper']) +test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('T19717', normal, compile, ['-ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags002', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1])], compile, ['-ddump-cmm -dsuppress-uniques -dno-typeable-binds -O']) @@ -18,7 +19,6 @@ test('T22840', [extra_files( [ 'T22840A.hs' , 'T22840B.hs' ]), when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks']) -test('T15226b', normal, compile, ['-O -ddump-stg-final -dsuppress-uniques -dno-typeable-binds']) test('inferTags003', [ only_ways(['optasm']), grep_errmsg(r'(call stg\_ap\_0)', [1]) ], compile, ['-ddump-cmm -dno-typeable-binds -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/385cd1c42ead591a448b921b9aee0d6424b82dd0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/385cd1c42ead591a448b921b9aee0d6424b82dd0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 10:28:51 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sat, 20 Apr 2024 06:28:51 -0400 Subject: [Git][ghc/ghc][wip/az/epa-splicedecl-comments] EPA: Avoid duplicated comments in splice decls Message-ID: <662398e32adf4_1e4dc1f9e2c829252@gitlab.mail> Alan Zimmerman pushed to branch wip/az/epa-splicedecl-comments at Glasgow Haskell Compiler / GHC Commits: 8c709e82 by Alan Zimmerman at 2024-04-20T11:28:39+01:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - 1 changed file: - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -397,17 +397,14 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + return $ L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c709e821ff568ab55b1684936d215f0a22515ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c709e821ff568ab55b1684936d215f0a22515ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 10:29:07 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sat, 20 Apr 2024 06:29:07 -0400 Subject: [Git][ghc/ghc][wip/az/epa-splicedecl-comments] EPA: Avoid duplicated comments in splice decls Message-ID: <662398f3eab41_1e4dc110436b0298bd@gitlab.mail> Alan Zimmerman pushed to branch wip/az/epa-splicedecl-comments at Glasgow Haskell Compiler / GHC Commits: 0bdf4efc by Alan Zimmerman at 2024-04-20T11:28:57+01:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - 2 changed files: - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -1257,8 +1257,7 @@ topdecl :: { LHsDecl GhcPs } -- but we treat an arbitrary expression just as if -- it had a $(..) wrapped around it | infixexp {% runPV (unECP $1) >>= \ $1 -> - do { d <- mkSpliceDecl $1 - ; commentsPA d }} + commentsPA $ mkSpliceDecl $1 } -- Type classes -- @@ -2603,7 +2602,7 @@ decl :: { LHsDecl GhcPs } -- Why do we only allow naked declaration splices in top-level -- declarations and not here? Short answer: because readFail009 -- fails terribly with a panic in cvBindsAndSigs otherwise. - | splice_exp {% mkSpliceDecl $1 } + | splice_exp { mkSpliceDecl $1 } rhs :: { Located (GRHSs GhcPs (LHsExpr GhcPs)) } : '=' exp wherebinds {% runPV (unECP $2) >>= \ $2 -> ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -385,7 +385,7 @@ mkFamDecl loc info topLevel lhs ksig injAnn annsIn OpenTypeFamily -> empty ClosedTypeFamily {} -> whereDots -mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) +mkSpliceDecl :: LHsExpr GhcPs -> (LHsDecl GhcPs) -- If the user wrote -- [pads| ... ] then return a QuasiQuoteD -- $(e) then return a SpliceD @@ -396,18 +396,15 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- Typed splices are not allowed at the top level, thus we do not represent them -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) - | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | otherwise + = L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bdf4efcabe6739b68da65182c566938a30f9da5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bdf4efcabe6739b68da65182c566938a30f9da5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 12:40:42 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 20 Apr 2024 08:40:42 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Fix quantification order for a `op` b and a %m -> b Message-ID: <6623b7cacf920_22cfcf161ed02707f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - b1c7e01a by Jade at 2024-04-20T08:40:33-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - 9a2fba2f by Teo Camarasu at 2024-04-20T08:40:34-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 94b2c22e by Alan Zimmerman at 2024-04-20T08:40:35-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Logger.hs - docs/users_guide/9.12.1-notes.rst - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T - testsuite/tests/ghci.debugger/scripts/T19394.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4eb0225f4c0d25dfeb86d334be6bcd4a0e7f64f...94b2c22e652a540f6d437473e72107d0f54ebbe1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4eb0225f4c0d25dfeb86d334be6bcd4a0e7f64f...94b2c22e652a540f6d437473e72107d0f54ebbe1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 15:11:48 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 20 Apr 2024 11:11:48 -0400 Subject: [Git][ghc/ghc][master] Put the newline after errors instead of before them Message-ID: <6623db3419b18_22cfcf13f1640427dc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - 13 changed files: - compiler/GHC/Utils/Logger.hs - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T9140.stdout - testsuite/tests/layout/layout001.stdout - testsuite/tests/layout/layout003.stdout - testsuite/tests/layout/layout004.stdout - testsuite/tests/layout/layout006.stdout - testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout - testsuite/tests/overloadedrecflds/ghci/T19314.stdout - testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout - testsuite/tests/rename/should_compile/T13839.stdout - testsuite/tests/th/T7276a.stdout - testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr Changes: ===================================== compiler/GHC/Utils/Logger.hs ===================================== @@ -417,14 +417,13 @@ defaultLogAction logflags msg_class srcSpan msg message = mkLocMessageWarningGroups (log_show_warn_groups logflags) msg_class srcSpan msg printDiagnostics = do - hPutChar stderr '\n' caretDiagnostic <- if log_show_caret logflags then getCaretDiagnostic msg_class srcSpan else pure empty printErrs $ getPprStyle $ \style -> withPprStyle (setStyleColoured True style) - (message $+$ caretDiagnostic) + (message $+$ caretDiagnostic $+$ blankLine) -- careful (#2302): printErrs prints in UTF-8, -- whereas converting to string first and using -- hPutStr would just emit the low 8 bits of ===================================== testsuite/tests/ghci/prog018/prog018.stdout ===================================== @@ -1,7 +1,6 @@ [1 of 3] Compiling A ( A.hs, interpreted ) [2 of 3] Compiling B ( B.hs, interpreted ) [3 of 3] Compiling C ( C.hs, interpreted ) - A.hs:5:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)] Pattern match(es) are non-exhaustive In an equation for ‘incompletePattern’: @@ -17,9 +16,10 @@ B.hs:7:1: warning: [GHC-66111] [-Wunused-imports (in -Wextra)] C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules loaded. [3 of 3] Compiling C ( C.hs, interpreted ) - C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules reloaded. ===================================== testsuite/tests/ghci/scripts/T9140.stdout ===================================== @@ -1,4 +1,3 @@ - :2:5: error: [GHC-20036] You can't mix polymorphic and unlifted bindings: a = (# 1 #) Suggested fix: Add a type signature. @@ -10,3 +9,4 @@ :1:1: error: [GHC-17999] GHCi can't bind a variable of unlifted type: a :: (# Integer, Integer #) + ===================================== testsuite/tests/layout/layout001.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout001.hs:6:3: error: [GHC-58481] parse error on input ‘where’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout001.hs:6:3: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `where' clause at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout003.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout003.hs:11:4: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout003.hs:11:4: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout004.stdout ===================================== @@ -1,7 +1,7 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ + ===================================== testsuite/tests/layout/layout006.stdout ===================================== @@ -1,13 +1,12 @@ Running with -XNoAlternativeLayoutRule - layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... -Running with -XAlternativeLayoutRule +Running with -XAlternativeLayoutRule layout006.hs:12:2: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block @@ -15,3 +14,4 @@ layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... + ===================================== testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout ===================================== @@ -1,10 +1,10 @@ GHCiDRF.foo :: T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to either the field ‘bar’ of record ‘T’, defined at GHCiDRF.hs:3:28, or the field ‘bar’ of record ‘U’, defined at GHCiDRF.hs:4:16. + type T :: * data T = MkT {foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -16,7 +16,6 @@ type U :: * data U = MkU {bar :: Bool} -- Defined at GHCiDRF.hs:4:16 GHCiDRF.foo :: GHCiDRF.T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -26,6 +25,7 @@ GHCiDRF.foo :: GHCiDRF.T -> Int or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + type GHCiDRF.T :: * data GHCiDRF.T = GHCiDRF.MkT {GHCiDRF.foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -36,7 +36,6 @@ data GHCiDRF.T = GHCiDRF.MkT {..., GHCiDRF.bar :: Int} type GHCiDRF.U :: * data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} -- Defined at GHCiDRF.hs:4:16 - :11:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -46,3 +45,4 @@ data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + ===================================== testsuite/tests/overloadedrecflds/ghci/T19314.stdout ===================================== @@ -1,6 +1,5 @@ w :: [a] -> a x :: [a] -> a - :1:1: error: [GHC-88464] Variable not in scope: y Suggested fix: @@ -12,3 +11,4 @@ x :: [a] -> a Suggested fix: Notice that ‘z’ is a field selector that has been suppressed by NoFieldSelectors. + ===================================== testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout ===================================== @@ -7,7 +7,6 @@ type T :: * -> * data T a = MkT {foo :: Bool, ...} -- Defined at :4:18 True - :1:1: error: [GHC-87543] Ambiguous occurrence ‘foo’. It could refer to @@ -15,6 +14,7 @@ True defined at :3:16, or the field ‘foo’ of record ‘T’, defined at :4:18. + type U :: * data U = MkU {foo :: Int} -- Defined at :12:16 ===================================== testsuite/tests/rename/should_compile/T13839.stdout ===================================== @@ -1,5 +1,5 @@ - T13839a.hs:10:1: warning: [GHC-40910] [-Wunused-top-binds (in -Wextra, -Wunused-binds)] Defined but not used: ‘nonUsed’ + nonUsed :: () nonUsed :: () ===================================== testsuite/tests/th/T7276a.stdout ===================================== @@ -1,4 +1,3 @@ - :3:9: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] • Couldn't match type ‘[Dec]’ with ‘Exp’ Expected: Q Exp @@ -17,3 +16,4 @@ (deferred type error) Code: x • In the untyped splice: $x + ===================================== testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr ===================================== @@ -1,4 +1,3 @@ - CaretDiagnostics1.hs:7:8-15: error: [GHC-83865] • Couldn't match expected type ‘IO a0’ with actual type ‘Int’ • In the second argument of ‘(+)’, namely ‘(3 :: Int)’ @@ -68,3 +67,4 @@ CaretDiagnostics1.hs:23:25-26: error: [GHC-83865] | 23 | tabby2 = () | ^^ + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/275e41a902f4aec8552707ec9924f2d0a20346d0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/275e41a902f4aec8552707ec9924f2d0a20346d0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 15:12:41 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 20 Apr 2024 11:12:41 -0400 Subject: [Git][ghc/ghc][master] Remove unecessary stage0 packages Message-ID: <6623db69aebf3_22cfcf16990644785d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2 changed files: - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs Changes: ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -132,15 +132,11 @@ mkToolTarget es p = do -- critically the `exe:ghc` component as that depends on the GHC library -- which takes a while to compile. toolTargets :: [Package] -toolTargets = [ binary - , bytestring - , cabalSyntax +toolTargets = [ cabalSyntax , cabal , compiler - , containers , directory , process - , exceptions , filepath , osString -- , ghc -- # depends on ghc library @@ -157,12 +153,8 @@ toolTargets = [ binary , hsc2hs -- # executable , hpc , hpcBin -- # executable - , mtl - , parsec , time , templateHaskellNext - , text - , transformers , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -80,40 +80,38 @@ stageBootPackages = return stage0Packages :: Action [Package] stage0Packages = do cross <- flag CrossCompiling - return $ [ binary - , bytestring - , cabalSyntax + return $ [ cabalSyntax , cabal , compiler - , containers - , directory - , process - , exceptions - , filepath + , directory -- depends on filepath + , filepath -- depends on os-string , ghc - , runGhc , ghcBoot , ghcBootThNext - , ghcPlatform , ghcHeap + , ghcPkg + , ghcPlatform , ghcToolchain , ghci - , ghcPkg , haddock - , hsc2hs + , hp2ps , hpc , hpcBin - , mtl - , osString - , parsec - , semaphoreCompat - , time + , hsc2hs + , osString -- new library not yet present for boot compilers + , process -- depends on filepath + , runGhc + , semaphoreCompat -- depends on , templateHaskellNext - , text - , transformers + , time -- depends on win32 , unlit - , hp2ps , if windowsHost then win32 else unix + -- We must use the in-tree `Win32` as the version + -- bundled with GHC 9.6 is too old for `semaphore-compat`. + -- Once 9.6 is no longer a boot compiler, we can drop win32/unix. + -- These depend on `filepath`/`os-string` through an automatic flag + -- that confused Hadrian, so we must make those a stage0 package as well. + -- Once we drop `Win32`/`unix` it should be possible to drop those too. ] ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] @@ -143,12 +141,14 @@ stage1Packages = do [ libraries0 -- Build all Stage0 libraries in Stage1 , [ array , base + , binary + , bytestring , containers , deepseq , exceptions , ghc - , ghcBootTh , ghcBignum + , ghcBootTh , ghcCompact , ghcExperimental , ghcInternal @@ -158,11 +158,15 @@ stage1Packages = do , hp2ps , hsc2hs , integerGmp + , mtl + , parsec , pretty , rts , semaphoreCompat - , templateHaskell , stm + , templateHaskell + , text + , transformers , unlit , xhtml , if winTarget then win32 else unix View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd339c7acaf842ab275ee153be3521314ab4b85d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd339c7acaf842ab275ee153be3521314ab4b85d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 20 15:13:07 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 20 Apr 2024 11:13:07 -0400 Subject: [Git][ghc/ghc][master] EPA: Avoid duplicated comments in splice decls Message-ID: <6623db834790d_22cfcf16b61dc480ba@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - 2 changed files: - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -1257,8 +1257,7 @@ topdecl :: { LHsDecl GhcPs } -- but we treat an arbitrary expression just as if -- it had a $(..) wrapped around it | infixexp {% runPV (unECP $1) >>= \ $1 -> - do { d <- mkSpliceDecl $1 - ; commentsPA d }} + commentsPA $ mkSpliceDecl $1 } -- Type classes -- @@ -2603,7 +2602,7 @@ decl :: { LHsDecl GhcPs } -- Why do we only allow naked declaration splices in top-level -- declarations and not here? Short answer: because readFail009 -- fails terribly with a panic in cvBindsAndSigs otherwise. - | splice_exp {% mkSpliceDecl $1 } + | splice_exp { mkSpliceDecl $1 } rhs :: { Located (GRHSs GhcPs (LHsExpr GhcPs)) } : '=' exp wherebinds {% runPV (unECP $2) >>= \ $2 -> ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -385,7 +385,7 @@ mkFamDecl loc info topLevel lhs ksig injAnn annsIn OpenTypeFamily -> empty ClosedTypeFamily {} -> whereDots -mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) +mkSpliceDecl :: LHsExpr GhcPs -> (LHsDecl GhcPs) -- If the user wrote -- [pads| ... ] then return a QuasiQuoteD -- $(e) then return a SpliceD @@ -396,18 +396,15 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- Typed splices are not allowed at the top level, thus we do not represent them -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) - | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | otherwise + = L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f8e3a254a20f4573aec26fc85ab74b51d661472 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f8e3a254a20f4573aec26fc85ab74b51d661472 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 02:49:26 2024 From: gitlab at gitlab.haskell.org (Brandon S. Allbery (@geekosaur)) Date: Sat, 20 Apr 2024 22:49:26 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/geekosaur/codeowners-link Message-ID: <66247eb6705f8_30f23ef99890537a4@gitlab.mail> Brandon S. Allbery pushed new branch wip/geekosaur/codeowners-link at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/geekosaur/codeowners-link You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 02:54:29 2024 From: gitlab at gitlab.haskell.org (Brandon S. Allbery (@geekosaur)) Date: Sat, 20 Apr 2024 22:54:29 -0400 Subject: [Git][ghc/ghc][wip/geekosaur/codeowners-link] 6 commits: Fix quantification order for a `op` b and a %m -> b Message-ID: <66247fe5ed3a8_30f23e10d2c3456762@gitlab.mail> Brandon S. Allbery pushed to branch wip/geekosaur/codeowners-link at Glasgow Haskell Compiler / GHC Commits: d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - 6ba672bb by brandon s allbery kf8nh at 2024-04-21T02:54:26+00:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Utils.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Logger.hs - docs/users_guide/9.12.1-notes.rst - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO.hs - libraries/ghc-prim/GHC/Magic.hs - + testsuite/tests/core-to-stg/T24124.hs - + testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/core-to-stg/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7efb6f0078281ef3bf6040e5bf8e134aabc43388...6ba672bb78304f634a66362d25bf88e120f825bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7efb6f0078281ef3bf6040e5bf8e134aabc43388...6ba672bb78304f634a66362d25bf88e120f825bf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 09:41:20 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 05:41:20 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] 2 commits: Revert "Bump time submodule to 1.14" Message-ID: <6624df403263d_30f23e3bc6864641ec@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 3b63186d by Ben Gamari at 2024-04-13T09:07:57-04:00 Revert "Bump time submodule to 1.14" Unfortunately the `Lift` instances introduced in 1.14 trigger #22229. While it's unlikely that an end-user will observe this breakage, we cannot to ship a release with the CI breakage that this implies (as multi-component support would have no validation). Consequently, we have no choice but to try to fix #22229 and bump again in 9.12. This reverts commit 2ed7264434a2edee97ab441c9ccbdf675e0d7896. - - - - - f15a854e by Alan Zimmerman at 2024-04-21T09:59:45+01:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 30 changed files: - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/ghc.cabal.in - ghc/ghc-bin.cabal.in - hadrian/src/Rules/Dependencies.hs - libraries/Cabal - libraries/directory - libraries/hpc - libraries/time - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/parser/should_compile/T23315/T23315.stderr - testsuite/tests/printer/T18791.stderr - testsuite/tests/printer/Test20297.stdout - testsuite/tests/printer/Test24533.stdout - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs.hs ===================================== @@ -101,12 +101,14 @@ deriving instance Data (HsModule GhcPs) data AnnsModule = AnnsModule { am_main :: [AddEpAnn], - am_decls :: [TrailingAnn], - am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- End of file and end of prior token + am_decls :: [TrailingAnn], -- ^ Semis before the start of top decls + am_cs :: [LEpaComment], -- ^ Comments before start of top decl, + -- used in exact printing only + am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- ^ End of file and end of prior token } deriving (Data, Eq) instance NoAnn AnnsModule where - noAnn = AnnsModule [] [] Nothing + noAnn = AnnsModule [] [] [] Nothing instance Outputable (HsModule GhcPs) where ppr (HsModule { hsmodExt = XModulePs { hsmodHaddockModHeader = mbDoc } ===================================== compiler/GHC/Parser.y ===================================== @@ -881,7 +881,7 @@ signature :: { Located (HsModule GhcPs) } : 'signature' modid maybe_warning_pragma maybeexports 'where' body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs-> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnSignature $1, mj AnnWhere $5] (fstOf3 $6) Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnSignature $1, mj AnnWhere $5] (fstOf3 $6) [] Nothing) cs) (thdOf3 $6) $3 Nothing) (Just $2) $4 (fst $ sndOf3 $6) (snd $ sndOf3 $6))) @@ -891,7 +891,7 @@ module :: { Located (HsModule GhcPs) } : 'module' modid maybe_warning_pragma maybeexports 'where' body {% fileSrcSpan >>= \ loc -> acsFinal (\cs eof -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1, mj AnnWhere $5] (fstOf3 $6) eof) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1, mj AnnWhere $5] (fstOf3 $6) [] eof) cs) (thdOf3 $6) $3 Nothing) (Just $2) $4 (fst $ sndOf3 $6) (snd $ sndOf3 $6)) @@ -899,7 +899,7 @@ module :: { Located (HsModule GhcPs) } | body2 {% fileSrcSpan >>= \ loc -> acsFinal (\cs eof -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [] (fstOf3 $1) eof) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [] (fstOf3 $1) [] eof) cs) (thdOf3 $1) Nothing Nothing) Nothing Nothing (fst $ sndOf3 $1) (snd $ sndOf3 $1)))) } @@ -939,14 +939,14 @@ header :: { Located (HsModule GhcPs) } : 'module' modid maybe_warning_pragma maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] [] Nothing) cs) EpNoLayout $3 Nothing) (Just $2) $4 $6 [] ))) } | 'signature' modid maybe_warning_pragma maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs loc (\loc cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] [] Nothing) cs) EpNoLayout $3 Nothing) (Just $2) $4 $6 [] ))) } ===================================== compiler/ghc.cabal.in ===================================== @@ -111,7 +111,7 @@ Library process >= 1 && < 1.7, bytestring >= 0.9 && < 0.13, binary == 0.8.*, - time >= 1.4 && < 1.15, + time >= 1.4 && < 1.13, containers >= 0.6.2.1 && < 0.8, array >= 0.1 && < 0.6, filepath >= 1 && < 1.6, ===================================== ghc/ghc-bin.cabal.in ===================================== @@ -61,7 +61,7 @@ Executable ghc ghci == @ProjectVersionMunged@, haskeline == 0.8.*, exceptions == 0.10.*, - time >= 1.8 && < 1.15 + time >= 1.8 && < 1.13 CPP-Options: -DHAVE_INTERNAL_INTERPRETER Other-Modules: GHCi.Leak ===================================== hadrian/src/Rules/Dependencies.hs ===================================== @@ -29,18 +29,6 @@ extraDepsList = , (containers, "Data.Set.Internal") --> th_internal , (containers, "Data.Sequence.Internal") --> th_internal , (containers, "Data.Graph") --> th_internal - , (time, "Data.Time.Calendar.CalendarDiffDays") --> th_internal - , (time, "Data.Time.Calendar.Days") --> th_internal - , (time, "Data.Time.Calendar.Month") --> th_internal - , (time, "Data.Time.Calendar.Quarter") --> th_internal - , (time, "Data.Time.Calendar.Week") --> th_internal - , (time, "Data.Time.Calendar.WeekDate") --> th_internal - , (time, "Data.Time.Clock.Internal.AbsoluteTime") --> th_internal - , (time, "Data.Time.Clock.Internal.DiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.NominalDiffTime") --> th_internal - , (time, "Data.Time.Clock.Internal.SystemTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UTCTime") --> th_internal - , (time, "Data.Time.Clock.Internal.UniversalTime") --> th_internal ] where (p1,m1) --> (p2,m2) = (PkgMod p1 m1, PkgMod p2 m2) ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit b5ac2f70b0289c5ee1d31211a44133217a8fb9e3 +Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit fc144a581768eb0a328bdcd5adcffca400bd0876 +Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 4989c41b96c7c9ca09a6687da638ac28f3d3688b +Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 ===================================== libraries/time ===================================== @@ -1 +1 @@ -Subproject commit e5c5d1987011efe88a21ab6ded45aaa33a16274f +Subproject commit baab563ee2ce547f7b7f7e7069ed09db2d406941 ===================================== testsuite/tests/ghc-api/exactprint/T22919.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T22919.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T22919.hs:1:29-33 }))] [] + [] (Just ((,) { T22919.hs:3:1 } ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20239.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20239.hs:1:18-22 }))] [] + [] (Just ((,) { Test20239.hs:9:1 } @@ -200,7 +201,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:50 }) (EpaSpan { Test20239.hs:7:86 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:50 }) + (EpaSpan { Test20239.hs:7:86 })) (L (EpAnn (EpaSpan { Test20239.hs:7:51-85 }) @@ -269,7 +273,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:68 }) (EpaSpan { Test20239.hs:7:85 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:68 }) + (EpaSpan { Test20239.hs:7:85 })) (L (EpAnn (EpaSpan { Test20239.hs:7:69-84 }) @@ -334,7 +341,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { Test20239.hs:7:83 }) (EpaSpan { Test20239.hs:7:84 })) + (AnnParen + AnnParens + (EpaSpan { Test20239.hs:7:83 }) + (EpaSpan { Test20239.hs:7:84 })) (HsBoxedOrConstraintTuple) [])))))))))))))]) (Nothing)))]) ===================================== testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { ZeroWidthSemi.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { ZeroWidthSemi.hs:1:22-26 }))] [] + [] (Just ((,) { ZeroWidthSemi.hs:9:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T17544.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544.hs:3:15-19 }))] [] + [] (Just ((,) { T17544.hs:57:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T17544_kw.hs:11:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544_kw.hs:13:13-17 }))] [] + [] (Just ((,) { T17544_kw.hs:25:1 } @@ -227,7 +228,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T17544_kw.hs:19:18 }) (EpaSpan { T17544_kw.hs:19:19 })) + (AnnParen + AnnParens + (EpaSpan { T17544_kw.hs:19:18 }) + (EpaSpan { T17544_kw.hs:19:19 })) (HsBoxedOrConstraintTuple) [])))]) (L ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T24221.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T24221.hs:1:15-19 }))] [] + [] (Just ((,) { T24221.hs:43:4 } ===================================== testsuite/tests/module/mod185.stderr ===================================== @@ -8,6 +8,7 @@ (EpAnn (EpaSpan { mod185.hs:1:1 }) (AnnsModule + [] [] [] (Just ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { DumpParsedAst.hs:4:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAst.hs:4:22-26 }))] [] + [] (Just ((,) { DumpParsedAst.hs:26:1 } @@ -228,7 +229,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { DumpParsedAst.hs:9:16 }) (EpaSpan { DumpParsedAst.hs:9:18 })) + (AnnParen + AnnParensSquare + (EpaSpan { DumpParsedAst.hs:9:16 }) + (EpaSpan { DumpParsedAst.hs:9:18 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:9:17 }) @@ -315,7 +319,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:11:10 }) (EpaSpan { DumpParsedAst.hs:11:17 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:11:10 }) + (EpaSpan { DumpParsedAst.hs:11:17 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:11:11-16 }) @@ -410,7 +417,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:11:26 }) (EpaSpan { DumpParsedAst.hs:11:36 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:11:26 }) + (EpaSpan { DumpParsedAst.hs:11:36 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:11:27-35 }) @@ -555,7 +565,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { DumpParsedAst.hs:10:27 }) (EpaSpan { DumpParsedAst.hs:10:29 })) + (AnnParen + AnnParensSquare + (EpaSpan { DumpParsedAst.hs:10:27 }) + (EpaSpan { DumpParsedAst.hs:10:29 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:10:28 }) @@ -732,7 +745,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:15:25 }) (EpaSpan { DumpParsedAst.hs:15:29 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:15:25 }) + (EpaSpan { DumpParsedAst.hs:15:29 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:15:26-28 }) @@ -867,7 +883,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:17:17 }) (EpaSpan { DumpParsedAst.hs:17:27 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:17:17 }) + (EpaSpan { DumpParsedAst.hs:17:27 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:17:18-26 }) @@ -1460,7 +1479,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:22:22 }) (EpaSpan { DumpParsedAst.hs:22:37 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:22:22 }) + (EpaSpan { DumpParsedAst.hs:22:37 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:22:23-36 }) @@ -1567,7 +1589,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:22:42 }) (EpaSpan { DumpParsedAst.hs:22:52 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:22:42 }) + (EpaSpan { DumpParsedAst.hs:22:52 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:22:43-51 }) @@ -1688,7 +1713,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { DumpParsedAst.hs:23:10 }) (EpaSpan { DumpParsedAst.hs:23:34 })) + (AnnParen + AnnParens + (EpaSpan { DumpParsedAst.hs:23:10 }) + (EpaSpan { DumpParsedAst.hs:23:34 })) (L (EpAnn (EpaSpan { DumpParsedAst.hs:23:11-33 }) ===================================== testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { DumpParsedAstComments.hs:5:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAstComments.hs:5:30-34 }))] [] + [] (Just ((,) { DumpParsedAstComments.hs:20:1 } ===================================== testsuite/tests/parser/should_compile/DumpSemis.stderr ===================================== @@ -22,6 +22,7 @@ (EpaSpan { DumpSemis.hs:4:7 })) ,(AddSemiAnn (EpaSpan { DumpSemis.hs:4:8 }))] + [] (Just ((,) { DumpSemis.hs:46:1 } ===================================== testsuite/tests/parser/should_compile/KindSigs.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { KindSigs.hs:6:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { KindSigs.hs:6:17-21 }))] [] + [] (Just ((,) { KindSigs.hs:36:1 } ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T15323.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T15323.hs:3:15-19 }))] [] + [] (Just ((,) { T15323.hs:7:1 } @@ -163,7 +164,10 @@ (EpaComments [])) (HsParTy - (AnnParen AnnParens (EpaSpan { T15323.hs:6:31 }) (EpaSpan { T15323.hs:6:36 })) + (AnnParen + AnnParens + (EpaSpan { T15323.hs:6:31 }) + (EpaSpan { T15323.hs:6:36 })) (L (EpAnn (EpaSpan { T15323.hs:6:32-35 }) ===================================== testsuite/tests/parser/should_compile/T20452.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20452.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20452.hs:3:15-19 }))] [] + [] (Just ((,) { T20452.hs:10:1 } @@ -376,7 +377,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { T20452.hs:8:57 }) (EpaSpan { T20452.hs:8:74 })) + (AnnParen + AnnParensSquare + (EpaSpan { T20452.hs:8:57 }) + (EpaSpan { T20452.hs:8:74 })) (L (EpAnn (EpaSpan { T20452.hs:8:58-73 }) @@ -385,7 +389,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T20452.hs:8:58 }) (EpaSpan { T20452.hs:8:73 })) + (AnnParen + AnnParens + (EpaSpan { T20452.hs:8:58 }) + (EpaSpan { T20452.hs:8:73 })) (HsBoxedOrConstraintTuple) [(L (EpAnn @@ -585,7 +592,10 @@ (EpaComments [])) (HsListTy - (AnnParen AnnParensSquare (EpaSpan { T20452.hs:9:57 }) (EpaSpan { T20452.hs:9:74 })) + (AnnParen + AnnParensSquare + (EpaSpan { T20452.hs:9:57 }) + (EpaSpan { T20452.hs:9:74 })) (L (EpAnn (EpaSpan { T20452.hs:9:58-73 }) @@ -594,7 +604,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T20452.hs:9:58 }) (EpaSpan { T20452.hs:9:73 })) + (AnnParen + AnnParens + (EpaSpan { T20452.hs:9:58 }) + (EpaSpan { T20452.hs:9:73 })) (HsBoxedOrConstraintTuple) [(L (EpAnn ===================================== testsuite/tests/parser/should_compile/T20718.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20718.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718.hs:3:15-19 }))] [] + [] (Just ((,) { T20718.hs:12:1 } ===================================== testsuite/tests/parser/should_compile/T20718b.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20718b.hs:4:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718b.hs:4:16-20 }))] [] + [] (Just ((,) { T20718b.hs:8:1 } ===================================== testsuite/tests/parser/should_compile/T20846.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T20846.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20846.hs:1:15-19 }))] [] + [] (Just ((,) { T20846.hs:5:1 } ===================================== testsuite/tests/parser/should_compile/T23315/T23315.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnSignature (EpaSpan { T23315.hsig:1:1-9 })) ,(AddEpAnn AnnWhere (EpaSpan { T23315.hsig:1:18-22 }))] [] + [] (Nothing)) (EpaComments [])) @@ -94,7 +95,10 @@ (EpaComments [])) (HsTupleTy - (AnnParen AnnParens (EpaSpan { T23315.hsig:3:6 }) (EpaSpan { T23315.hsig:3:7 })) + (AnnParen + AnnParens + (EpaSpan { T23315.hsig:3:6 }) + (EpaSpan { T23315.hsig:3:7 })) (HsBoxedOrConstraintTuple) [])))))))) ,(L ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { T18791.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T18791.hs:2:15-19 }))] [] + [] (Just ((,) { T18791.hs:6:1 } ===================================== testsuite/tests/printer/Test20297.stdout ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20297.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.hs:2:18-22 }))] [] + [] (Just ((,) { Test20297.hs:12:1 } @@ -418,6 +419,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test20297.ppr.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.ppr.hs:2:18-22 }))] [] + [] (Just ((,) { Test20297.ppr.hs:9:25 } ===================================== testsuite/tests/printer/Test24533.stdout ===================================== @@ -11,6 +11,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test24533.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test24533.hs:2:18-22 }))] [] + [] (Just ((,) { Test24533.hs:17:1 } @@ -643,6 +644,7 @@ [(AddEpAnn AnnModule (EpaSpan { Test24533.ppr.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test24533.ppr.hs:2:18-22 }))] [] + [] (Just ((,) { Test24533.ppr.hs:6:20 } ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -961,8 +961,10 @@ lepa k epAnn = fmap (\newAnns -> epAnn { anns = newAnns }) -- data AnnsModule -- = AnnsModule { --- am_main :: [AddEpAnn], --- am_decls :: AnnList +-- am_main :: [AddEpAnn], +-- am_decls :: [TrailingAnn], +-- am_cs :: [LEpaComment], +-- am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- } deriving (Data, Eq) lam_main :: Lens AnnsModule [AddEpAnn] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/397f549b18ccfa679161fea7555afe519131e15c...f15a854ea3f5265b2dfca6a17519d316ff61fce0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/397f549b18ccfa679161fea7555afe519131e15c...f15a854ea3f5265b2dfca6a17519d316ff61fce0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 10:39:31 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 06:39:31 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] EPA: Fix comments in mkListSyntaxTy0 Message-ID: <6624ece3ed90a_30f23e4274a08643e6@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: c8d25501 by Alan Zimmerman at 2024-04-21T10:41:35+01:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 (cherry picked from commit f07015858fd79dca41983dbf3a249dfecd8d2eea) - - - - - 3 changed files: - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3318,12 +3318,12 @@ withCombinedComments :: HasLoc l2 => l1 -> l2 -> - (SrcSpan -> EpAnnComments -> P a) -> + (SrcSpan -> P a) -> P (LocatedA a) withCombinedComments start end use = do cs <- getCommentsFor fullSpan - a <- use fullSpan cs - pure (L (noAnnSrcSpan fullSpan) a) + a <- use fullSpan + pure (L (EpAnn (spanAsAnchor fullSpan) noAnn cs) a) where fullSpan = combineSrcSpans (getHasLoc start) (getHasLoc end) @@ -3363,15 +3363,14 @@ mkTupleSyntaxTycon boxity n = mkListSyntaxTy0 :: EpaLocation -> EpaLocation -> SrcSpan - -> EpAnnComments -> P (HsType GhcPs) -mkListSyntaxTy0 brkOpen brkClose span comments = +mkListSyntaxTy0 brkOpen brkClose span = punsIfElse enabled disabled where enabled = HsTyVar noAnn NotPromoted rn -- attach the comments only to the RdrName since it's the innermost AST node - rn = L (EpAnn fullLoc rdrNameAnn comments) listTyCon_RDR + rn = L (EpAnn fullLoc rdrNameAnn emptyComments) listTyCon_RDR disabled = HsExplicitListTy annsKeyword NotPromoted [] ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.hs ===================================== @@ -1,17 +1,18 @@ {-# language NoListTuplePuns #-} +{-# OPTIONS -ddump-parsed-ast #-} module AnnotationNoListTuplePuns where type A = - -- comment pre + -- comment pre A [ - -- comment inside + -- comment inside A ] - -- comment post + -- comment post A type B = - -- comment pre + -- comment pre B [ - -- comment inside + -- comment inside B Bool ] - -- comment post + -- comment post B ===================================== testsuite/tests/printer/AnnotationNoListTuplePuns.stdout ===================================== @@ -0,0 +1,323 @@ + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.hs:19:1 } + { AnnotationNoListTuplePuns.hs:18:3-19 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.hs:1:1-32 }))] + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:18:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post B") + { AnnotationNoListTuplePuns.hs:17:3 }))])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(5,1)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:6:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre A") + { AnnotationNoListTuplePuns.hs:5:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(7,3)-(9,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:8:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside A") + { AnnotationNoListTuplePuns.hs:7:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:7:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:9:3 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(12,1)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:10:3-19 }) + (EpaComment + (EpaLineComment + "-- comment post A") + { AnnotationNoListTuplePuns.hs:9:3 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:13:3-18 }) + (EpaComment + (EpaLineComment + "-- comment pre B") + { AnnotationNoListTuplePuns.hs:12:8 }))])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.hs:12:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.hs:12:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:12:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:(14,3)-(17,3) }) + (AnnListItem + []) + (EpaComments + [(L + (EpaSpan + { AnnotationNoListTuplePuns.hs:15:5-23 }) + (EpaComment + (EpaLineComment + "-- comment inside B") + { AnnotationNoListTuplePuns.hs:14:3 }))])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.hs:14:3 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.hs:17:3 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.hs:16:5-8 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + + +==================== Parser AST ==================== + +(L + { AnnotationNoListTuplePuns.ppr.hs:1:1 } + (HsModule + (XModulePs + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:1:1 }) + (AnnsModule + [(AddEpAnn AnnModule (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:1-6 })) + ,(AddEpAnn AnnWhere (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:34-38 }))] + [] + [] + (Just + ((,) + { AnnotationNoListTuplePuns.ppr.hs:5:16 } + { AnnotationNoListTuplePuns.ppr.hs:5:15 }))) + (EpaCommentsBalanced + [(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }) + (EpaComment + (EpaBlockComment + "{-# language NoListTuplePuns #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1 })) + ,(L + (EpaSpan + { AnnotationNoListTuplePuns.ppr.hs:2:1-33 }) + (EpaComment + (EpaBlockComment + "{-# OPTIONS -ddump-parsed-ast #-}") + { AnnotationNoListTuplePuns.ppr.hs:1:1-32 }))] + [])) + (EpVirtualBraces + (1)) + (Nothing) + (Nothing)) + (Just + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:3:8-32 }) + (AnnListItem + []) + (EpaComments + [])) + {ModuleName: AnnotationNoListTuplePuns})) + (Nothing) + [] + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-11 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: A})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10-11 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:4:11 }))] + (NotPromoted) + []))))) + ,(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-15 }) + (AnnListItem + []) + (EpaComments + [])) + (TyClD + (NoExtField) + (SynDecl + [(AddEpAnn AnnType (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:1-4 })) + ,(AddEpAnn AnnEqual (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:8 }))] + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:6 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: B})) + (HsQTvs + (NoExtField) + []) + (Prefix) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10-15 }) + (AnnListItem + []) + (EpaComments + [])) + (HsExplicitListTy + [(AddEpAnn AnnOpenS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:10 })) + ,(AddEpAnn AnnCloseS (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:15 }))] + (NotPromoted) + [(L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (AnnListItem + []) + (EpaComments + [])) + (HsTyVar + [] + (NotPromoted) + (L + (EpAnn + (EpaSpan { AnnotationNoListTuplePuns.ppr.hs:5:11-14 }) + (NameAnnTrailing + []) + (EpaComments + [])) + (Unqual + {OccName: Bool}))))])))))])) + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8d25501884a6633b580bc1b347b7ca8f2d04fe6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8d25501884a6633b580bc1b347b7ca8f2d04fe6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 11:39:55 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 07:39:55 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] EPA: Provide correct span for PatBind Message-ID: <6624fb0bc6540_f1fa532ff647164d@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 7d6ae7aa by Alan Zimmerman at 2024-04-21T11:39:48+01:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 (cherry picked from commit c90c60390aa3949b400f26ee0534273c56e19005) - - - - - 6 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -116,7 +116,7 @@ type instance XFunBind (GhcPass pL) GhcTc = (HsWrapper, [CoreTickish]) -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. -type instance XPatBind GhcPs (GhcPass pR) = [AddEpAnn] +type instance XPatBind GhcPs (GhcPass pR) = NoExtField type instance XPatBind GhcRn (GhcPass pR) = NameSet -- See Note [Bind free vars] type instance XPatBind GhcTc (GhcPass pR) = ( Type -- Type of the GRHSs ===================================== compiler/GHC/Parser.y ===================================== @@ -2585,7 +2585,7 @@ decl_no_th :: { LHsDecl GhcPs } ; !cs <- getCommentsFor l ; return $! (sL (commentsA l cs) $ ValD noExtField r) } } | PREFIX_PERCENT atype infixexp opt_sig rhs {% runPV (unECP $3) >>= \ $3 -> - do { let { l = comb2 $3 $> } + do { let { l = comb2 $1 $> } ; r <- checkValDef l $3 (mkMultAnn (epTok $1) $2, $4) $5; -- parses bindings of the form %p x or -- %p x :: sig ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1323,7 +1323,7 @@ checkValDef loc lhs (mult, Just (sigAnn, sig)) grhss -- x :: ty = rhs parses as a *pattern* binding = do lhs' <- runPV $ mkHsTySigPV (combineLocsA lhs sig) lhs sig [sigAnn] >>= checkLPat - checkPatBind loc [] lhs' grhss mult + checkPatBind loc lhs' grhss mult checkValDef loc lhs (mult_ann, Nothing) grhss | HsNoMultAnn{} <- mult_ann @@ -1334,12 +1334,12 @@ checkValDef loc lhs (mult_ann, Nothing) grhss fun is_infix pats grhss Nothing -> do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' grhss mult_ann } + checkPatBind loc lhs' grhss mult_ann } checkValDef loc lhs (mult_ann, Nothing) ghrss -- %p x = rhs parses as a *pattern* binding = do lhs' <- checkPattern lhs - checkPatBind loc [] lhs' ghrss mult_ann + checkPatBind loc lhs' ghrss mult_ann checkFunBind :: SrcStrictness -> SrcSpan @@ -1377,15 +1377,14 @@ makeFunBind fn ms -- See Note [FunBind vs PatBind] checkPatBind :: SrcSpan - -> [AddEpAnn] -> LPat GhcPs -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> HsMultAnn GhcPs -> P (HsBind GhcPs) -checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) +checkPatBind loc (L _ (BangPat ans (L _ (VarPat _ v)))) (L _match_span grhss) (HsNoMultAnn _) = return (makeFunBind v (L (noAnnSrcSpan loc) - [L (noAnnSrcSpan loc) (m (ans++annsIn) v)])) + [L (noAnnSrcSpan loc) (m ans v)])) where m a v = Match { m_ext = a , m_ctxt = FunRhs { mc_fun = v @@ -1394,8 +1393,8 @@ checkPatBind loc annsIn (L _ (BangPat ans (L _ (VarPat _ v)))) , m_pats = [] , m_grhss = grhss } -checkPatBind _loc annsIn lhs (L _ grhss) mult = do - return (PatBind annsIn lhs mult grhss) +checkPatBind _loc lhs (L _ grhss) mult = do + return (PatBind noExtField lhs mult grhss) checkValSigLhs :: LHsExpr GhcPs -> P (LocatedN RdrName) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -218,7 +218,7 @@ cvtDec (TH.ValD pat body ds) ; returnJustLA $ Hs.ValD noExtField $ PatBind { pat_lhs = pat' , pat_rhs = GRHSs emptyComments body' ds' - , pat_ext = noAnn + , pat_ext = noExtField , pat_mult = HsNoMultAnn noExtField } } ===================================== testsuite/tests/linear/should_fail/LinearLet6.stderr ===================================== @@ -13,7 +13,7 @@ LinearLet6.hs:10:3: error: [GHC-18872] where (Just y) = x -LinearLet6.hs:15:14: error: [GHC-18872] +LinearLet6.hs:15:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ arising from a non-linear pattern ‘Just y’ (non-variable lazy pattern aren't linear) ===================================== testsuite/tests/linear/should_fail/LinearLet7.stderr ===================================== @@ -1,14 +1,14 @@ -LinearLet7.hs:6:14: error: [GHC-18872] +LinearLet7.hs:6:11: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from multiplicity of ‘g’ - • In a pattern binding: g = \ y -> g y - In the expression: let %1 g = \ y -> ... in g x + arising from a non-linear pattern ‘_’ + (non-variable pattern bindings that have been generalised aren't linear) + • In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x LinearLet7.hs:6:14: error: [GHC-18872] • Couldn't match type ‘Many’ with ‘One’ - arising from a non-linear pattern ‘_’ - (non-variable pattern bindings that have been generalised aren't linear) - • In the expression: let %1 g = \ y -> ... in g x + arising from multiplicity of ‘g’ + • In a pattern binding: g = \ y -> g y + In the expression: let %1 g = \ y -> ... in g x In an equation for ‘f’: f x = let %1 g = ... in g x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d6ae7aa4def7131d281040e6b0e600f84cd1bb2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d6ae7aa4def7131d281040e6b0e600f84cd1bb2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 12:02:19 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Sun, 21 Apr 2024 08:02:19 -0400 Subject: [Git][ghc/ghc][wip/T24477] 113 commits: EPA: Fix FamDecl range Message-ID: <6625004b1d9a5_f1fa5679d3c7833d@gitlab.mail> Jade pushed to branch wip/T24477 at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - f745c0b8 by Jade at 2024-04-21T14:06:43+02:00 Improve suggestions for language extensions - When suggesting Language extensions, also suggest Extensions which imply them - Suggest ExplicitForAll and GADTSyntax instead of more specific extensions - Rephrase suggestion to include the term 'Extension' - Also moves some flag specific definitions out of Session.hs into Flags.hs (#24478) Fixes: #24477 Fixes: #24448 Fixes: #10893 - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc3bec95c3a433758ceb7dc3a8eba177d125f57b...f745c0b85128b84901660f3e9df12e23b28a4958 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc3bec95c3a433758ceb7dc3a8eba177d125f57b...f745c0b85128b84901660f3e9df12e23b28a4958 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 12:48:57 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 08:48:57 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] EPA: Fix span for PatBuilderAppType Message-ID: <66250b39e3f8e_f1fa5bce36482133@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 64013156 by Alan Zimmerman at 2024-04-21T12:43:22+01:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 (cherry picked from commit 26036f96919b1a8b99715dd99724163012c719fc) - - - - - 8 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - testsuite/tests/rename/should_fail/T17594b.stderr - testsuite/tests/typecheck/should_fail/T17594c.stderr - testsuite/tests/typecheck/should_fail/T17594d.stderr - testsuite/tests/typecheck/should_fail/T17594g.stderr Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -219,7 +219,7 @@ type instance XHsPS GhcPs = EpAnnCO type instance XHsPS GhcRn = HsPSRn type instance XHsPS GhcTc = HsPSRn -type instance XHsTP GhcPs = EpAnnCO +type instance XHsTP GhcPs = NoExtField type instance XHsTP GhcRn = HsTyPatRn type instance XHsTP GhcTc = DataConCantHappen @@ -295,9 +295,9 @@ mkHsPatSigType :: EpAnnCO -> LHsType GhcPs -> HsPatSigType GhcPs mkHsPatSigType ann x = HsPS { hsps_ext = ann , hsps_body = x } -mkHsTyPat :: EpAnnCO -> LHsType GhcPs -> HsTyPat GhcPs -mkHsTyPat ann x = HsTP { hstp_ext = ann - , hstp_body = x } +mkHsTyPat :: LHsType GhcPs -> HsTyPat GhcPs +mkHsTyPat x = HsTP { hstp_ext = noExtField + , hstp_body = x } mkEmptyWildCardBndrs :: thing -> HsWildCardBndrs GhcRn thing mkEmptyWildCardBndrs x = HsWC { hswc_body = x @@ -589,7 +589,7 @@ mkHsAppTys = foldl' mkHsAppTy mkHsAppKindTy :: XAppKindTy (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -> LHsType (GhcPass p) -mkHsAppKindTy x ty k = addCLocA ty k (HsAppKindTy x ty k) +mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) {- ************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -3401,7 +3401,7 @@ bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parse argpat :: { LPat GhcPs } argpat : apat { $1 } - | PREFIX_AT atype { L (getLocAnn (reLoc $2)) (InvisPat (epTok $1) (mkHsTyPat noAnn $2)) } + | PREFIX_AT atype { sLLa $1 $> (InvisPat (epTok $1) (mkHsTyPat $2)) } argpats :: { [LPat GhcPs] } : argpat argpats { $1 : $2 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1458,9 +1458,12 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L loc _)))) es ops cps - = go pat (L loc (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat + anc' = case tok of + NoEpTok -> anc + EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] go _ _ _ _ = return Nothing data ArgPatBuilder p @@ -1920,8 +1923,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) mkHsAppTypePV l p at t = do !cs <- getCommentsFor (locA l) - let anns = EpAnn (spanAsAnchor (getLocA t)) NoEpAnns cs - return $ L l (PatBuilderAppType p at (mkHsTyPat anns t)) + return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t)) mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar) @@ -1978,7 +1980,7 @@ instance DisambECP (PatBuilder GhcPs) where mkSumOrTuplePV = mkSumOrTuplePat mkHsEmbTyPV l toktype ty = return $ L (noAnnSrcSpan l) $ - PatBuilderPat (EmbTyPat toktype (mkHsTyPat noAnn ty)) + PatBuilderPat (EmbTyPat toktype (mkHsTyPat ty)) rejectPragmaPV _ = return () -- | Ensure that a literal pattern isn't of type Addr#, Float#, Double#. ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1446,7 +1446,7 @@ cvtp (ConP s ts ps) = do { s' <- cNameN s ; ps' <- cvtPats ps ; ts' <- mapM cvtType ts ; let pps = map (parenthesizePat appPrec) ps' - pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat noAnn t)) ts' + pts = map (\t -> HsConPatTyArg noAnn (mkHsTyPat t)) ts' ; return $ ConPat { pat_con_ext = noAnn , pat_con = s' @@ -1489,9 +1489,9 @@ cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noAnn e' p'} cvtp (TypeP t) = do { t' <- cvtType t - ; return $ EmbTyPat noAnn (mkHsTyPat noAnn t') } + ; return $ EmbTyPat noAnn (mkHsTyPat t') } cvtp (InvisP t) = do { t' <- cvtType t - ; pure (InvisPat noAnn (mkHsTyPat noAnn t'))} + ; pure (InvisPat noAnn (mkHsTyPat t'))} cvtPatFld :: (TH.Name, TH.Pat) -> CvtM (LHsRecField GhcPs (LPat GhcPs)) cvtPatFld (s,p) ===================================== testsuite/tests/rename/should_fail/T17594b.stderr ===================================== @@ -1,84 +1,84 @@ -T17594b.hs:7:6: error: [GHC-78249] +T17594b.hs:7:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:10:6: error: [GHC-78249] +T17594b.hs:10:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:14:6: error: [GHC-78249] +T17594b.hs:14:5: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:6: error: [GHC-78249] +T17594b.hs:17:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:10: error: [GHC-78249] +T17594b.hs:17:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:14: error: [GHC-78249] +T17594b.hs:17:13: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:27: error: [GHC-78249] +T17594b.hs:17:26: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:31: error: [GHC-78249] +T17594b.hs:17:30: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:17:35: error: [GHC-78249] +T17594b.hs:17:34: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:20:11: error: [GHC-78249] +T17594b.hs:20:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:22:20: error: [GHC-78249] +T17594b.hs:22:19: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:25:10: error: [GHC-78249] +T17594b.hs:25:9: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:6: error: [GHC-78249] +T17594b.hs:28:5: error: [GHC-78249] Illegal invisible type pattern: t1 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:10: error: [GHC-78249] +T17594b.hs:28:9: error: [GHC-78249] Illegal invisible type pattern: t2 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:32: error: [GHC-78249] +T17594b.hs:28:31: error: [GHC-78249] Illegal invisible type pattern: t3 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:58: error: [GHC-78249] +T17594b.hs:28:57: error: [GHC-78249] Illegal invisible type pattern: t4 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:62: error: [GHC-78249] +T17594b.hs:28:61: error: [GHC-78249] Illegal invisible type pattern: t5 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:28:71: error: [GHC-78249] +T17594b.hs:28:70: error: [GHC-78249] Illegal invisible type pattern: t6 Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:31:11: error: [GHC-78249] +T17594b.hs:31:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:34:11: error: [GHC-78249] +T17594b.hs:34:10: error: [GHC-78249] Illegal invisible type pattern: t Suggested fix: Perhaps you intended to use TypeAbstractions -T17594b.hs:37:7: error: [GHC-78249] +T17594b.hs:37:6: error: [GHC-78249] Illegal invisible type pattern: ($(TH.varT (TH.mkName "t"))) Suggested fix: Perhaps you intended to use TypeAbstractions ===================================== testsuite/tests/typecheck/should_fail/T17594c.stderr ===================================== @@ -1,5 +1,5 @@ -T17594c.hs:5:11: error: [GHC-14964] +T17594c.hs:5:10: error: [GHC-14964] • Invisible type pattern t has no associated forall • In the expression: \ @t -> undefined :: t In the expression: [\ @t -> undefined :: t] ===================================== testsuite/tests/typecheck/should_fail/T17594d.stderr ===================================== @@ -1,4 +1,4 @@ -T17594d.hs:8:6: error: [GHC-14964] +T17594d.hs:8:5: error: [GHC-14964] • Invisible type pattern t has no associated forall • In an equation for ‘id'’: id' @t x = x :: t ===================================== testsuite/tests/typecheck/should_fail/T17594g.stderr ===================================== @@ -1,4 +1,4 @@ -T17594g.hs:6:6: error: [GHC-14964] +T17594g.hs:6:5: error: [GHC-14964] • Invisible type pattern a has no associated forall • In an equation for ‘id'’: id' @a x = x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/640131560e6e305106f9ef22d8831f0597d2aac4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/640131560e6e305106f9ef22d8831f0597d2aac4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 13:26:39 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 09:26:39 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] EPA: Avoid duplicated comments in splice decls Message-ID: <6625140f9f5fe_f1fa510aaea0836a4@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 898fcbd2 by Alan Zimmerman at 2024-04-21T13:49:41+01:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 (cherry picked from commit 2f8e3a254a20f4573aec26fc85ab74b51d661472) - - - - - 2 changed files: - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -1257,8 +1257,7 @@ topdecl :: { LHsDecl GhcPs } -- but we treat an arbitrary expression just as if -- it had a $(..) wrapped around it | infixexp {% runPV (unECP $1) >>= \ $1 -> - do { d <- mkSpliceDecl $1 - ; commentsPA d }} + commentsPA $ mkSpliceDecl $1 } -- Type classes -- @@ -2603,7 +2602,7 @@ decl :: { LHsDecl GhcPs } -- Why do we only allow naked declaration splices in top-level -- declarations and not here? Short answer: because readFail009 -- fails terribly with a panic in cvBindsAndSigs otherwise. - | splice_exp {% mkSpliceDecl $1 } + | splice_exp { mkSpliceDecl $1 } rhs :: { Located (GRHSs GhcPs (LHsExpr GhcPs)) } : '=' exp wherebinds {% runPV (unECP $2) >>= \ $2 -> ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -386,7 +386,7 @@ mkFamDecl loc info topLevel lhs ksig injAnn annsIn OpenTypeFamily -> empty ClosedTypeFamily {} -> whereDots -mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) +mkSpliceDecl :: LHsExpr GhcPs -> (LHsDecl GhcPs) -- If the user wrote -- [pads| ... ] then return a QuasiQuoteD -- $(e) then return a SpliceD @@ -397,18 +397,15 @@ mkSpliceDecl :: LHsExpr GhcPs -> P (LHsDecl GhcPs) -- Typed splices are not allowed at the top level, thus we do not represent them -- as spliced declaration. See #10945 mkSpliceDecl lexpr@(L loc expr) - | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr = do - cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField (L loc splice) DollarSplice) - - | otherwise = do - !cs <- getCommentsFor (locA loc) - return $ L (addCommentsToEpAnn loc cs) $ SpliceD noExtField (SpliceDecl noExtField - (L loc (HsUntypedSpliceExpr noAnn lexpr)) + | HsUntypedSplice _ splice@(HsUntypedSpliceExpr {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | HsUntypedSplice _ splice@(HsQuasiQuote {}) <- expr + = L loc $ SpliceD noExtField (SpliceDecl noExtField (L (l2l loc) splice) DollarSplice) + + | otherwise + = L loc $ SpliceD noExtField (SpliceDecl noExtField + (L (l2l loc) (HsUntypedSpliceExpr noAnn (la2la lexpr))) BareSplice) mkRoleAnnotDecl :: SrcSpan View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/898fcbd20a7ec5164bb37c33f1c909430200ea06 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/898fcbd20a7ec5164bb37c33f1c909430200ea06 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 21 14:32:48 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 21 Apr 2024 10:32:48 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] EPA: Extend StringLiteral range to include trailing commas Message-ID: <66252390ad02_f1fa51adcc5c920da@gitlab.mail> Alan Zimmerman pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: 9f509a09 by Alan Zimmerman at 2024-04-21T15:32:17+01:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. (cherry picked from commit 00d3ecf0775c1a3f1ab8495e5e125f21d450394e) - - - - - 2 changed files: - compiler/GHC/Parser.y - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -4558,7 +4558,8 @@ addTrailingCommaN (L anns a) span = do return (L anns' a) addTrailingCommaS :: Located StringLiteral -> EpaLocation -> Located StringLiteral -addTrailingCommaS (L l sl) span = L l (sl { sl_tc = Just (epaToNoCommentsLocation span) }) +addTrailingCommaS (L l sl) span + = L (widenSpan l [AddEpAnn AnnComma span]) (sl { sl_tc = Just (epaToNoCommentsLocation span) }) -- ------------------------------------- ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -652,6 +652,10 @@ printSourceText :: (Monad m, Monoid w) => SourceText -> String -> EP w m () printSourceText (NoSourceText) txt = printStringAdvance txt >> return () printSourceText (SourceText txt) _ = printStringAdvance (unpackFS txt) >> return () +printSourceTextAA :: (Monad m, Monoid w) => SourceText -> String -> EP w m () +printSourceTextAA (NoSourceText) txt = printStringAtAA (EpaDelta (SameLine 0) []) txt >> return () +printSourceTextAA (SourceText txt) _ = printStringAtAA (EpaDelta (SameLine 0) []) (unpackFS txt) >> return () + -- --------------------------------------------------------------------- printStringAtSs :: (Monad m, Monoid w) => SrcSpan -> String -> EP w m () @@ -2121,7 +2125,7 @@ instance ExactPrint StringLiteral where setAnnotationAnchor a _ _ _ = a exact (StringLiteral src fs mcomma) = do - printSourceText src (show (unpackFS fs)) + printSourceTextAA src (show (unpackFS fs)) mcomma' <- mapM (\r -> printStringAtNC r ",") mcomma return (StringLiteral src fs mcomma') View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f509a09f60707024cac6557f2b07c2e06bd9b23 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f509a09f60707024cac6557f2b07c2e06bd9b23 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 03:09:07 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Sun, 21 Apr 2024 23:09:07 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/clyring/seqHash-DmdTransformer Message-ID: <6625d4d3cddd2_29e22c1b47893841@gitlab.mail> Matthew Craven pushed new branch wip/clyring/seqHash-DmdTransformer at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/clyring/seqHash-DmdTransformer You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 05:27:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 22 Apr 2024 01:27:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 14 commits: Put the newline after errors instead of before them Message-ID: <6625f558a3aff_7a389507530576cf@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - 2d521ff2 by brandon s allbery kf8nh at 2024-04-22T01:27:35-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Utils/Fingerprint.hs - compiler/GHC/Utils/Logger.hs - configure.ac - docs/users_guide/phases.rst - hadrian/bindist/Makefile - hadrian/bindist/config.mk.in - hadrian/cfg/default.host.target.in - hadrian/cfg/default.target.in - hadrian/src/Builder.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - libraries/ghc-internal/jsbits/base.js - libraries/ghc-internal/jsbits/platform.js - + m4/fp_js_cpp_cmd_with_args.m4 - m4/fp_settings.m4 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94b2c22e652a540f6d437473e72107d0f54ebbe1...2d521ff2bf235705abdf08bca9fc68498c1ca730 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94b2c22e652a540f6d437473e72107d0f54ebbe1...2d521ff2bf235705abdf08bca9fc68498c1ca730 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 07:48:29 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 22 Apr 2024 03:48:29 -0400 Subject: [Git][ghc/ghc][master] 10 commits: JS: fix typos and namings (fixes #24602) Message-ID: <6626164d68229_7a38917eb1c487774@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - 30 changed files: - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Utils/Fingerprint.hs - configure.ac - docs/users_guide/phases.rst - hadrian/bindist/Makefile - hadrian/bindist/config.mk.in - hadrian/cfg/default.host.target.in - hadrian/cfg/default.target.in - hadrian/src/Builder.hs - hadrian/src/Rules/Generate.hs - libraries/ghc-internal/jsbits/base.js - libraries/ghc-internal/jsbits/platform.js - + m4/fp_js_cpp_cmd_with_args.m4 - m4/fp_settings.m4 - m4/fp_setup_windows_toolchain.m4 - m4/ghc_toolchain.m4 - m4/prep_target_file.m4 - rts/js/gc.js - rts/js/mem.js - rts/js/profiling.js The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f8e3a254a20f4573aec26fc85ab74b51d661472...83eb10da239e6bef0d06dbba174809f99c463d8d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f8e3a254a20f4573aec26fc85ab74b51d661472...83eb10da239e6bef0d06dbba174809f99c463d8d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 07:49:04 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 22 Apr 2024 03:49:04 -0400 Subject: [Git][ghc/ghc][master] fix link in CODEOWNERS Message-ID: <662616706a418_7a38919969ec91262@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 1 changed file: - CODEOWNERS Changes: ===================================== CODEOWNERS ===================================== @@ -1,5 +1,5 @@ # Confused about what this is? See -# https://gitlab.haskell.org/help/user/project/code_owners +# https://docs.gitlab.com/ee/user/project/codeowners/ # Catch-all * @bgamari View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1cf8dc2c941d36dc92139faa07ee6baf2599e38 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1cf8dc2c941d36dc92139faa07ee6baf2599e38 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 08:08:49 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 04:08:49 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <66261b115147d_7a3891c9a1349142d@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: 39f80743 by Fendor at 2024-04-22T10:08:40+02:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 7dba4d6b by Fendor at 2024-04-22T10:08:40+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. - - - - - 5 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96061301595b4efd079c34a18e119a654bc7b690...7dba4d6bb518c5ac74fd9db0e1f68ec359182602 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96061301595b4efd079c34a18e119a654bc7b690...7dba4d6bb518c5ac74fd9db0e1f68ec359182602 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 08:13:37 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 04:13:37 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 67 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <66261c3164a41_7a3891e31c68935ab@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 47ad2517 by Fendor at 2024-04-22T10:13:17+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - c80d115b by Fendor at 2024-04-22T10:13:22+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6df52a0a6b51fa42349855b6556162f2b9cadc1f...c80d115b604f1f591874773a79f8dcb07ec8b83a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6df52a0a6b51fa42349855b6556162f2b9cadc1f...c80d115b604f1f591874773a79f8dcb07ec8b83a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 09:27:49 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 05:27:49 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 72 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <66262d95eaee6_7a389288ae44111417@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 47ad2517 by Fendor at 2024-04-22T10:13:17+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - c80d115b by Fendor at 2024-04-22T10:13:22+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - b2f88df7 by Fendor at 2024-04-22T10:37:29+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 25abd579 by Fendor at 2024-04-22T11:27:33+02:00 Break cyclic module dependency - - - - - 0e8e5bf0 by Fendor at 2024-04-22T11:27:33+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - faf75a40 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 860806e9 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/890e5b5a7d58793a7232bbf9f2eb44aae5e7f74a...860806e9f178b66946fba618ad7d8d6e8114b64a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/890e5b5a7d58793a7232bbf9f2eb44aae5e7f74a...860806e9f178b66946fba618ad7d8d6e8114b64a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 09:37:47 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 05:37:47 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] Implement TrieMap for IfaceType Message-ID: <66262feaee953_7a3892a6102411172e@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: a42dcf7a by Fendor at 2024-04-22T11:37:35+02:00 Implement TrieMap for IfaceType - - - - - 6 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -129,7 +129,7 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX -type LiteralMap a = Map.Map Literal a +type LiteralMap a = Map.Map Literal a -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -36,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -340,6 +342,95 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } + +{- +************************************************************************ +* * + Composition +* * +************************************************************************ +-} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} + + {- ************************************************************************ * * ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -113,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -124,7 +124,7 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } -type LiteralMap a = Map.Map Literal a +type LiteralMap = Map.Map Literal -- TODO(22292): derive instance Functor StgArgMap where ===================================== compiler/ghc.cabal.in ===================================== @@ -594,6 +594,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a42dcf7a9856a9aaba305a1fff098da59ed27f1c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a42dcf7a9856a9aaba305a1fff098da59ed27f1c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 09:38:57 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 05:38:57 -0400 Subject: [Git][ghc/ghc][wip/fendor/iface-sharing] 74 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <662630314b52a_7a3892b188281120c3@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/iface-sharing at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 47ad2517 by Fendor at 2024-04-22T10:13:17+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - c80d115b by Fendor at 2024-04-22T10:13:22+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - b2f88df7 by Fendor at 2024-04-22T10:37:29+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 25abd579 by Fendor at 2024-04-22T11:27:33+02:00 Break cyclic module dependency - - - - - 0e8e5bf0 by Fendor at 2024-04-22T11:27:33+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - faf75a40 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 860806e9 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - a42dcf7a by Fendor at 2024-04-22T11:37:35+02:00 Implement TrieMap for IfaceType - - - - - 85a7dab9 by Fendor at 2024-04-22T11:38:41+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/578f15ac1b3991706a55c717b8d9973409b695b2...85a7dab9570e417e5760af3ff3c049461ddc96f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/578f15ac1b3991706a55c717b8d9973409b695b2...85a7dab9570e417e5760af3ff3c049461ddc96f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 09:53:51 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 05:53:51 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 75 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <662633afdace1_7a3892d6a5b81122e0@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 47ad2517 by Fendor at 2024-04-22T10:13:17+02:00 Refactor the Binary serialisation interface The end goal is to dynamically add deduplication tables for `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to ths refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - c80d115b by Fendor at 2024-04-22T10:13:22+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - b2f88df7 by Fendor at 2024-04-22T10:37:29+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 25abd579 by Fendor at 2024-04-22T11:27:33+02:00 Break cyclic module dependency - - - - - 0e8e5bf0 by Fendor at 2024-04-22T11:27:33+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - faf75a40 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 860806e9 by Matthew Pickering at 2024-04-22T11:27:33+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - a42dcf7a by Fendor at 2024-04-22T11:37:35+02:00 Implement TrieMap for IfaceType - - - - - 85a7dab9 by Fendor at 2024-04-22T11:38:41+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 35caa779 by Fendor at 2024-04-22T11:53:41+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3632e6cd3a9dc352bbf516b58e505f419d7a7832...35caa77917244c34b44c47f534b966c09a9ce351 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3632e6cd3a9dc352bbf516b58e505f419d7a7832...35caa77917244c34b44c47f534b966c09a9ce351 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:11:19 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:11:19 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 4 commits: Add deduplication table for `IfaceType` Message-ID: <662637c746ea7_7a3892f5b8b8112446@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 197f0000 by Fendor at 2024-04-22T12:10:55+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. - - - - - edebdeb4 by Matthew Pickering at 2024-04-22T12:10:55+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - d42b03c4 by Matthew Pickering at 2024-04-22T12:10:55+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - c79e84be by Fendor at 2024-04-22T12:10:55+02:00 Implement TrieMap for IfaceType - - - - - 24 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -129,7 +129,7 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX -type LiteralMap a = Map.Map Literal a +type LiteralMap a = Map.Map Literal a -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -36,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -340,6 +342,95 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } + +{- +************************************************************************ +* * + Composition +* * +************************************************************************ +-} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} + + {- ************************************************************************ * * ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -207,6 +207,7 @@ data DynFlags = DynFlags { dmdUnboxWidth :: !Int, -- ^ Whether DmdAnal should optimistically put an -- Unboxed demand on returned products with at most -- this number of fields + ifCompression :: Int, specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types @@ -546,6 +547,7 @@ defaultDynFlags mySettings = maxPmCheckModels = 30, simplTickFactor = 100, dmdUnboxWidth = 3, -- Default: Assume an unboxed demand on function bodies returning a triple + ifCompression = 2, -- Default: Apply safe compressions specConstrThreshold = Just 2000, specConstrCount = Just 3, specConstrRecursive = 3, ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -163,7 +163,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -612,7 +612,7 @@ extract_renamed_stuff mod_summary tc_result = do -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) let out_file = ml_hie_file $ ms_location mod_summary - liftIO $ writeHieFile out_file hieFile + liftIO $ writeHieFile (flagsToIfCompression dflags) out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files @@ -1207,7 +1207,7 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do withTiming logger (text "WriteIface"<+>brackets (text iface_name)) (const ()) - (writeIface logger profile iface_name iface) + (writeIface logger profile (flagsToIfCompression dflags) iface_name iface) if (write_interface || force_write_interface) then do ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1695,6 +1695,9 @@ dynamic_flags_deps = [ , make_ord_flag defFlag "fno-refinement-level-hole-fits" (noArg (\d -> d { refLevelHoleFits = Nothing })) + , make_ord_flag defFlag "fwrite-if-compression" + (intSuffix (\n d -> d { ifCompression = n })) + , make_dep_flag defGhcFlag "fllvm-pass-vectors-in-regs" (noArg id) "vectors registers are now passed in registers by default." ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -14,6 +14,7 @@ module GHC.Iface.Binary ( writeBinIface, readBinIface, readBinIfaceHeader, + CompressionIFace(..), getSymtabName, CheckHiWay(..), TraceBinIFace(..), @@ -25,6 +26,8 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude @@ -46,14 +49,19 @@ import GHC.Types.SrcLoc import GHC.Platform import GHC.Settings.Constants import GHC.Utils.Fingerprint +import GHC.Iface.Type (IfaceType(..), getIfaceType, putIfaceType, ifaceTypeSharedByte) +import Control.Monad import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.Char -import Data.Word import Data.IORef -import Control.Monad +import Data.Map.Strict (Map) +import Data.Word +import System.IO.Unsafe +import Data.Typeable (Typeable) + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -66,6 +74,21 @@ data TraceBinIFace = TraceBinIFace (SDoc -> IO ()) | QuietBinIFace +data CompressionIFace + = NormalCompression + -- ^ Perform the normal compression operations, + -- such as deduplicating 'Name's and 'FastString's + | SafeExtraCompression + -- ^ Perform some extra compression steps that have minimal impact + -- on the run-time of 'ghc'. + -- + -- This reduces the size of '.hi' files significantly in some cases + -- and reduces overall memory usage in certain scenarios. + | MaximalCompression + -- ^ Try to compress as much as possible. + -- + -- Yields the smallest '.hi' files but at the cost of additional run-time. + -- | Read an interface file header, checking the magic number, version, and -- way. Returns the hash of the source file and a BinHandle which points at the -- start of the rest of the interface file data. @@ -158,30 +181,42 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable nameReaderTable <- initNameReaderTable name_cache - - - -- The order of these deserialisation matters! - -- - -- See Note [Order of deduplication tables during iface binary serialisation] for details. - fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) - let - fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - - nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) - let - nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - - pure bhName + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + + let -- For any 'ReaderTable', we decode the table that is found at the location + -- the forward reference points to. + -- After decoding the table, we create a 'BinaryReader' and immediately + -- add it to the 'ReaderUserData' of 'ReadBinHandle'. + decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle + decodeReaderTable tbl bh0 = do + table <- Binary.forwardGet bh (getTable tbl bh0) + let binaryReader = mkReaderFromTable tbl table + pure $ addReaderToUserData binaryReader bh0 + + -- Decode all the tables and populate the 'ReaderUserData'. + bhFinal <- foldM (\bh0 act -> act bh0) bh + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + [ decodeReaderTable fsReaderTable + , decodeReaderTable nameReaderTable + , decodeReaderTable ifaceTypeReaderTable + ] + + writeIORef bhRef (getReaderUserData bhFinal) + pure bhFinal -- | Write an interface file. -- -- See Note [Deduplication during iface binary serialisation] for details. -writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () -writeBinIface profile traceBinIface hi_path mod_iface = do +writeBinIface :: Profile -> TraceBinIFace -> CompressionIFace -> FilePath -> ModIface -> IO () +writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do bh <- openBinMem initBinMemSize let platform = profilePlatform profile put_ bh (binaryInterfaceMagic platform) @@ -195,7 +230,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p - putWithUserData traceBinIface bh mod_iface + putWithUserData traceBinIface compressionLevel bh mod_iface extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p @@ -209,9 +244,9 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () -putWithUserData traceBinIface bh payload = do - (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) +putWithUserData :: Binary a => TraceBinIFace -> CompressionIFace -> WriteBinHandle -> a -> IO () +putWithUserData traceBinIface compressionLevel bh payload = do + (name_count, fs_count, _b) <- putWithTables compressionLevel bh (\bh' -> put bh' payload) case traceBinIface of QuietBinIFace -> return () @@ -234,11 +269,12 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Order of deduplication tables during iface binary serialisation] -putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) -putWithTables bh' put_payload = do +putWithTables :: CompressionIFace -> WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables compressionLevel bh' put_payload = do -- Initialise deduplicating tables. (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initNameWriterTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel -- Initialise the 'WriterUserData'. let writerUserData = mkWriterUserData @@ -250,6 +286,7 @@ putWithTables bh' put_payload = do -- -- See Note [Binary UserData] , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -257,18 +294,24 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Order of deduplication tables during iface binary serialisation] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) - where - putAllTables _ [] act = do - a <- act - pure ([], a) - putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do - putAllTables bh xs act - pure (r : res, a) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -450,6 +493,42 @@ Here, a visualisation of the table structure we currently have (ignoring 'Extens -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> lazyGet' getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: CompressionIFace -> IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType compressionLevel = do + sym_tab <- initGenericSymbolTable @(Map IfaceType) + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ ifaceWriter sym_tab + ) + where + ifaceWriter sym_tab = case compressionLevel of + NormalCompression -> literalIfaceTypeSerialiser + SafeExtraCompression -> ifaceTyConAppSerialiser sym_tab + MaximalCompression -> fullIfaceTypeSerialiser sym_tab + + ifaceTyConAppSerialiser sym_tab bh ty = case ty of + IfaceTyConApp {} -> do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + _ -> putIfaceType bh ty + + + fullIfaceTypeSerialiser sym_tab bh ty = do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + + literalIfaceTypeSerialiser = putIfaceType + initNameReaderTable :: NameCache -> IO (ReaderTable Name) initNameReaderTable cache = do ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable, CompressionIFace) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -74,8 +73,8 @@ putBinLine bh xs = do -- | Write a `HieFile` to the given `FilePath`, with a proper header and -- symbol tables for `Name`s and `FastString`s -writeHieFile :: FilePath -> HieFile -> IO () -writeHieFile hie_file_path hiefile = do +writeHieFile :: CompressionIFace -> FilePath -> HieFile -> IO () +writeHieFile compression hie_file_path hiefile = do bh0 <- openBinMem initBinMemSize -- Write the header: hieHeader followed by the @@ -84,58 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBinWriter bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType compression - -- remember where the symbol table pointer will go - symtab_p_p <- tellBinWriter bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBinWriter bh - putAt bh symtab_p_p symtab_p - seekBinWriter bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBinWriter bh - putAt bh dict_p_p dict_p - seekBinWriter bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Order of deduplication tables during iface binary serialisation] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -216,50 +215,32 @@ readHieFileHeader file bh0 = do readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBinReader bin_handle - seekBinReader bin_handle dict_p - dict <- getDictionary bin_handle - seekBinReader bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBinReader bh1 - seekBinReader bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBinReader bh1 data_p' - return symtab - -putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Iface.Load ( loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, findAndReadIface, readIface, writeIface, + flagsToIfCompression, moduleFreeHolesPrecise, needWiredInHomeIface, loadWiredInHomeIface, @@ -965,11 +966,18 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do -- | Write interface file -writeIface :: Logger -> Profile -> FilePath -> ModIface -> IO () -writeIface logger profile hi_file_path new_iface +writeIface :: Logger -> Profile -> CompressionIFace -> FilePath -> ModIface -> IO () +writeIface logger profile compression_level hi_file_path new_iface = do createDirectoryIfMissing True (takeDirectory hi_file_path) let printer = TraceBinIFace (debugTraceMsg logger 3) - writeBinIface profile printer hi_file_path new_iface + writeBinIface profile printer compression_level hi_file_path new_iface + +flagsToIfCompression :: DynFlags -> CompressionIFace +flagsToIfCompression dflags = case ifCompression dflags of + 0 -> NormalCompression + 1 -> NormalCompression + 2 -> SafeExtraCompression + _ -> MaximalCompression -- | @readIface@ tries just the one file. -- ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -33,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, ifaceTypeSharedByte, -- Equality testing isIfaceLiftedTypeKind, @@ -90,11 +92,13 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) +import Data.Maybe (isJust) +import Data.Proxy +import qualified Data.Semigroup as Semi +import Data.Word (Word8) +import Control.Arrow (first) import Control.DeepSeq import Control.Monad ((<$!>)) -import Control.Arrow (first) -import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) {- ************************************************************************ @@ -109,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName @@ -2191,38 +2199,70 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + put_ bh ty = + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ty - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } + get bh = getIfaceTypeShared bh - get bh = do +-- | This is the byte tag we expect to read when the next +-- value is not an 'IfaceType' value, but an offset into a +-- lookup value. +-- +-- Must not overlap with any byte tag in 'getIfaceType'. +ifaceTypeSharedByte :: Word8 +ifaceTypeSharedByte = 99 + +-- | Like 'getIfaceType' but checks for a specific byte tag +-- that indicates that we won't be able to read a 'IfaceType' value +-- but rather an offset into a lookup table. Consequentially, +-- we look up the value for the 'IfaceType' in the look up table. +-- +-- See Note [Deduplication during iface binary serialisation] +-- for details. +getIfaceTypeShared :: ReadBinHandle -> IO IfaceType +getIfaceTypeShared bh = do + start <- tellBinReader bh + tag <- getByte bh + if ifaceTypeSharedByte == tag + then case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + else seekBinReader bh start >> getIfaceType bh + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -124,7 +124,7 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } -type LiteralMap a = Map.Map Literal a +type LiteralMap = Map.Map Literal -- TODO(22292): derive instance Functor StgArgMap where ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack, HasDebugCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -133,6 +142,7 @@ import Data.List (unfoldr) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import Type.Reflection ( Typeable, SomeTypeRep(..) ) import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) @@ -143,6 +153,8 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) +import GHC.Data.TrieMap + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -231,20 +243,28 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: forall a. Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) - { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + { ud_reader_data = + let + typRep = Refl.typeRep @a + in + Map.insert (SomeTypeRep typRep) (SomeBinaryReader typRep reader) (ud_reader_data (rbm_userData bh)) } } -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: forall a . Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) - { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + { ud_writer_data = + let + typRep = Refl.typeRep @a + in + Map.insert (SomeTypeRep typRep) (SomeBinaryWriter typRep writer) (ud_writer_data (wbm_userData bh)) } } @@ -1103,24 +1123,32 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' get + +lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f bh' seekBinReader bh p -- skip over the object for now return a @@ -1174,6 +1202,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) @@ -1185,7 +1219,7 @@ data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryRead -- See Note [Binary UserData] data WriterUserData = WriterUserData { - ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + ud_writer_data :: Map SomeTypeRep SomeBinaryWriter -- ^ A mapping from a type witness to the 'Writer' for the associated type. -- This is a 'Map' because microbenchmarks indicated this is more efficient -- than other representations for less than ten elements. @@ -1202,7 +1236,7 @@ data WriterUserData = -- See Note [Binary UserData] data ReaderUserData = ReaderUserData { - ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + ud_reader_data :: Map SomeTypeRep SomeBinaryReader -- ^ A mapping from a type witness to the 'Reader' for the associated type. -- This is a 'Map' because microbenchmarks indicated this is more efficient -- than other representations for less than ten elements. @@ -1216,12 +1250,12 @@ data ReaderUserData = mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData mkWriterUserData caches = noWriterUserData - { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (SomeTypeRep typRep, cache)) caches } mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData mkReaderUserData caches = noReaderUserData - { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (SomeTypeRep typRep, cache)) caches } mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter @@ -1347,6 +1381,110 @@ newtype WriterTable = WriterTable -- ^ Serialise a table to disk. Returns the number of written elements. } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +-- | The 'GenericSymbolTable' stores a mapping from already seen elements to an index. +-- If an element wasn't seen before, it is added to the mapping together with a fresh +-- index. +-- +-- 'GenericSymbolTable' is a variant of a 'BinSymbolTable' that is polymorphic in the table implementation. +-- As such it can be used with any container that implements the 'TrieMap' type class. +-- +-- While 'GenericSymbolTable' is similar to the 'BinSymbolTable', it supports storing tree-like +-- structures such as 'Type' and 'IfaceType' more efficiently. +-- +data GenericSymbolTable m = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use. + , gen_symtab_map :: !(IORef (m Int)) + -- ^ Given a symbol, find the symbol and return its index. + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer. + -- This is an optimisation, as it allows us to write out quickly all + -- newly discovered values that are discovered when serialising 'Key m' + -- to disk. + } + +-- | Initialise a 'GenericSymbolTable', initialising the index to '0'. +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo + } + +-- | Serialise the 'GenericSymbolTable' to disk. +-- +-- Since 'GenericSymbolTable' stores tree-like structures, such as 'IfaceType', +-- serialising an element can add new elements to the mapping. +-- Thus, 'putGenericSymbolTable' first serialises all values, and then checks whether any +-- new elements have been discovered. If so, repeat the loop. +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab + putGenericSymbolTable :: WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) + case vs of + [] -> readFastMutInt symtab_next + todo -> do + mapM_ (\n -> serialiser bh n) (reverse todo) + loop + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop) + +-- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +-- | Write an element 'Key m' to the given 'WriteBinHandle'. +-- +-- If the element was seen before, we simply write the index of that element to the +-- 'WriteBinHandle'. If we haven't seen it before, we add the element to +-- the 'GenericSymbolTable', increment the index, and return this new index. +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () +{-# INLINE putGenericSymTab #-} +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } + bh val = do + symtab_map <- readIORef symtab_map_ref + case lookupTM val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) + put_ bh (fromIntegral off :: Word32) + +-- | Read a value from a 'SymbolTable'. +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/ghc.cabal.in ===================================== @@ -594,6 +594,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1777,3 +1777,12 @@ as such you shouldn't need to set any of them explicitly. A flag This flag sets the size (in bytes) threshold above which the second approach is used. You can disable the second approach entirely by setting the threshold to 0. + +.. ghc-flag:: -fwrite-if-compression=⟨n⟩ + :shortdesc: *default: 2.* Tweak the level of interface file compression. + :type: dynamic + :category: optimization + + :default: 2 + + TODO ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkVisFunTyMany` wordTy `mkVisFunTyMany` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a42dcf7a9856a9aaba305a1fff098da59ed27f1c...c79e84bef5b9c45eaaa21de9d4fcc19bdcaeb4f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a42dcf7a9856a9aaba305a1fff098da59ed27f1c...c79e84bef5b9c45eaaa21de9d4fcc19bdcaeb4f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:12:44 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:12:44 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` Message-ID: <6626381ca1817_7a389302a280112715@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 391a8c90 by Fendor at 2024-04-22T12:12:23+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 12 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -137,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -148,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -156,7 +156,7 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do fsReaderTable <- initFastStringReaderTable nameReaderTable <- initNameReaderTable name_cache @@ -192,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -209,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -234,7 +234,7 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Order of deduplication tables during iface binary serialisation] -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int, Int, b) +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) putWithTables bh' put_payload = do -- Initialise deduplicating tables. (fast_wt, fsWriter) <- initFastStringWriterTable @@ -489,7 +489,7 @@ initNameWriterTable = do ) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -498,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -519,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -543,7 +543,7 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: BinSymbolTable -> BinHandle -> Name -> IO () +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } @@ -569,7 +569,7 @@ putName BinSymbolTable{ -- See Note [Symbol table representation of names] getSymtabName :: SymbolTable Name - -> BinHandle -> IO Name + -> ReadBinHandle -> IO Name getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -112,9 +112,9 @@ writeHieFile hie_file_path hiefile = do put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -122,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -182,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -191,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -214,7 +214,7 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data @@ -233,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -261,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (SymbolTable Name) +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -277,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable Name -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -335,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -346,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -39,7 +39,7 @@ computeFingerprint put_nonbinding_name a = do -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -119,10 +119,10 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = case findUserDataWriter (Proxy @BindingName) bh of tbl -> @@ -2445,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -89,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq -import Control.Monad +import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -322,7 +322,7 @@ putObject bh mod_name deps os = do -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -330,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -345,7 +345,7 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) @@ -353,7 +353,7 @@ getObjectBody bh0 mod_name = do block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -364,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -393,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -409,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -779,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -22,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -31,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -85,7 +87,6 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, - -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding @@ -173,70 +174,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noReaderUserData noWriterUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_reader :: ReaderUserData, -- sigh, need parameterized modules :-) - bh_writer :: WriterUserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) + } + +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getReaderUserData :: BinHandle -> ReaderUserData -getReaderUserData bh = bh_reader bh +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh -getWriterUserData :: BinHandle -> WriterUserData -getWriterUserData bh = bh_writer bh +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setWriterUserData :: BinHandle -> WriterUserData -> BinHandle -setWriterUserData bh us = bh { bh_writer = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } -setReaderUserData :: BinHandle -> ReaderUserData -> BinHandle -setReaderUserData bh us = bh { bh_reader = us } +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } -addReaderToUserData :: SomeBinaryReader -> BinHandle -> BinHandle +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh - { bh_reader = (bh_reader bh) - { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (bh_reader bh)) + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) } } -addWriterToUserData :: SomeBinaryWriter -> BinHandle -> BinHandle +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh - { bh_writer = (bh_writer bh) - { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (bh_writer bh)) + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) } } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -255,23 +277,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -279,45 +301,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) + +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" + else writeFastMutInt ix_r p + +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ _ ix_r _ arr_r) fn = do +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -326,20 +363,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noReaderUserData noWriterUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -360,7 +400,7 @@ expandBin (BinMem _ _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -376,7 +416,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -397,8 +437,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -419,39 +459,37 @@ putPrim h@(BinMem _ _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -459,7 +497,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -472,7 +510,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -484,7 +522,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -505,10 +543,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -531,15 +569,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -556,15 +594,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -580,15 +618,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -608,15 +646,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -1027,63 +1065,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1091,14 +1129,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1193,27 +1231,27 @@ mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinary mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb newtype BinaryReader s = BinaryReader - { getEntry :: BinHandle -> IO s + { getEntry :: ReadBinHandle -> IO s } deriving (Functor) newtype BinaryWriter s = BinaryWriter - { putEntry :: BinHandle -> s -> IO () + { putEntry :: WriteBinHandle -> s -> IO () } -mkWriter :: (BinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s mkWriter f = BinaryWriter { putEntry = f } -mkReader :: (BinHandle -> IO s) -> BinaryReader s +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s mkReader f = BinaryReader { getEntry = f } -- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. -- --- If no 'BinaryReader' for that type can be found, this function will panic at run-time. -findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> BinHandle -> BinaryReader a +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a findUserDataReader query bh = case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) @@ -1234,8 +1272,8 @@ findUserDataReader query bh = -- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. -- --- If no 'BinaryWriter' for that type can be found, this function will panic at run-time. -findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> BinHandle -> BinaryWriter a +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a findUserDataWriter query bh = case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) @@ -1265,8 +1303,8 @@ noWriterUserData = WriterUserData { ud_writer_data = Map.empty } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) -> ReaderUserData newReadState get_name get_fs = mkReaderUserData @@ -1275,11 +1313,11 @@ newReadState get_name get_fs = , mkSomeBinaryReader $ mkReader get_fs ] -newWriteState :: (BinHandle -> Name -> IO ()) +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) + -> (WriteBinHandle -> FastString -> IO ()) -> WriterUserData newWriteState put_non_binding_name put_binding_name put_fs = mkWriterUserData @@ -1295,7 +1333,7 @@ newWriteState put_non_binding_name put_binding_name put_fs = -- | A 'ReaderTable' describes how to deserialise a table from disk, -- and how to create a 'BinaryReader' that looks up values in the deduplication table. data ReaderTable a = ReaderTable - { getTable :: BinHandle -> IO (SymbolTable a) + { getTable :: ReadBinHandle -> IO (SymbolTable a) -- ^ Deserialise a list of elements into a 'SymbolTable'. , mkReaderFromTable :: SymbolTable a -> BinaryReader a -- ^ Given the table from 'getTable', create a 'BinaryReader' @@ -1305,7 +1343,7 @@ data ReaderTable a = ReaderTable -- | A 'WriterTable' is an interface any deduplication table can implement to -- describe how the table can be written to disk. newtype WriterTable = WriterTable - { putTable :: BinHandle -> IO Int + { putTable :: WriteBinHandle -> IO Int -- ^ Serialise a table to disk. Returns the number of written elements. } @@ -1346,14 +1384,14 @@ initFastStringWriterTable = do , mkWriter $ putDictFastString bin_dict ) -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1362,12 +1400,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1404,34 +1442,34 @@ type SymbolTable a = Array Int a -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 278f8b07e027ce33f11a73d3f055c99a34d3cee9 +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/391a8c90b680a5654df85dddc32a6d237eace898 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/391a8c90b680a5654df85dddc32a6d237eace898 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:15:15 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:15:15 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <662638b39cb92_7a389315e73c11334b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: eee8f0d6 by Fendor at 2024-04-22T12:13:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - eda3aa6e by Fendor at 2024-04-22T12:14:44+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +103,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +141,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +174,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +277,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +301,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +363,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +400,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +416,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +437,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +459,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +497,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +510,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +522,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +543,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +569,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +594,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +618,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +646,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1065,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1129,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1147,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1168,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1400,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1434,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1481,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/391a8c90b680a5654df85dddc32a6d237eace898...eda3aa6ee1c86bab4c07b81ce758fc4520e72f69 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/391a8c90b680a5654df85dddc32a6d237eace898...eda3aa6ee1c86bab4c07b81ce758fc4520e72f69 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:21:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:21:30 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 8 commits: Refactor the Binary serialisation interface Message-ID: <66263a2a2e688_7a38932eab5011373c@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: eee8f0d6 by Fendor at 2024-04-22T12:13:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - eda3aa6e by Fendor at 2024-04-22T12:14:44+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 303b95e9 by Fendor at 2024-04-22T12:19:48+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 3a082e6e by Fendor at 2024-04-22T12:19:50+02:00 Break cyclic module dependency - - - - - 7532c18e by Fendor at 2024-04-22T12:20:38+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - b3dbf7bd by Matthew Pickering at 2024-04-22T12:21:21+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 70dd312b by Matthew Pickering at 2024-04-22T12:21:21+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 2fc1995a by Fendor at 2024-04-22T12:21:21+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c79e84bef5b9c45eaaa21de9d4fcc19bdcaeb4f5...2fc1995a1704d41a3bea6cac7edd172979a5c5e1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c79e84bef5b9c45eaaa21de9d4fcc19bdcaeb4f5...2fc1995a1704d41a3bea6cac7edd172979a5c5e1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:25:02 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:25:02 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 4 commits: Add deduplication table for `IfaceType` Message-ID: <66263afe57936_7a389340512011422a@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 63c952a9 by Fendor at 2024-04-22T12:23:48+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - 80ea1dd5 by Matthew Pickering at 2024-04-22T12:23:48+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - d026f8aa by Matthew Pickering at 2024-04-22T12:23:48+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 00c8808b by Fendor at 2024-04-22T12:23:48+02:00 Implement TrieMap for IfaceType - - - - - 25 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs - utils/haddock Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -129,7 +129,7 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX -type LiteralMap a = Map.Map Literal a +type LiteralMap a = Map.Map Literal a -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -36,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -340,6 +342,95 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } + +{- +************************************************************************ +* * + Composition +* * +************************************************************************ +-} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} + + {- ************************************************************************ * * ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -207,6 +207,7 @@ data DynFlags = DynFlags { dmdUnboxWidth :: !Int, -- ^ Whether DmdAnal should optimistically put an -- Unboxed demand on returned products with at most -- this number of fields + ifCompression :: Int, specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types @@ -546,6 +547,7 @@ defaultDynFlags mySettings = maxPmCheckModels = 30, simplTickFactor = 100, dmdUnboxWidth = 3, -- Default: Assume an unboxed demand on function bodies returning a triple + ifCompression = 2, -- Default: Apply safe compressions specConstrThreshold = Just 2000, specConstrCount = Just 3, specConstrRecursive = 3, ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -163,7 +163,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -612,7 +612,7 @@ extract_renamed_stuff mod_summary tc_result = do -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) let out_file = ml_hie_file $ ms_location mod_summary - liftIO $ writeHieFile out_file hieFile + liftIO $ writeHieFile (flagsToIfCompression dflags) out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files @@ -1207,7 +1207,7 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do withTiming logger (text "WriteIface"<+>brackets (text iface_name)) (const ()) - (writeIface logger profile iface_name iface) + (writeIface logger profile (flagsToIfCompression dflags) iface_name iface) if (write_interface || force_write_interface) then do ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1695,6 +1695,9 @@ dynamic_flags_deps = [ , make_ord_flag defFlag "fno-refinement-level-hole-fits" (noArg (\d -> d { refLevelHoleFits = Nothing })) + , make_ord_flag defFlag "fwrite-if-compression" + (intSuffix (\n d -> d { ifCompression = n })) + , make_dep_flag defGhcFlag "fllvm-pass-vectors-in-regs" (noArg id) "vectors registers are now passed in registers by default." ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -14,6 +14,7 @@ module GHC.Iface.Binary ( writeBinIface, readBinIface, readBinIfaceHeader, + CompressionIFace(..), getSymtabName, CheckHiWay(..), TraceBinIFace(..), @@ -25,6 +26,8 @@ module GHC.Iface.Binary ( putName, putSymbolTable, BinSymbolTable(..), + initWriteIfaceType, initReadIfaceTypeTable, + putAllTables, ) where import GHC.Prelude @@ -46,14 +49,19 @@ import GHC.Types.SrcLoc import GHC.Platform import GHC.Settings.Constants import GHC.Utils.Fingerprint +import GHC.Iface.Type (IfaceType(..), getIfaceType, putIfaceType, ifaceTypeSharedByte) +import Control.Monad import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.Char -import Data.Word import Data.IORef -import Control.Monad +import Data.Map.Strict (Map) +import Data.Word +import System.IO.Unsafe +import Data.Typeable (Typeable) + -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -66,6 +74,21 @@ data TraceBinIFace = TraceBinIFace (SDoc -> IO ()) | QuietBinIFace +data CompressionIFace + = NormalCompression + -- ^ Perform the normal compression operations, + -- such as deduplicating 'Name's and 'FastString's + | SafeExtraCompression + -- ^ Perform some extra compression steps that have minimal impact + -- on the run-time of 'ghc'. + -- + -- This reduces the size of '.hi' files significantly in some cases + -- and reduces overall memory usage in certain scenarios. + | MaximalCompression + -- ^ Try to compress as much as possible. + -- + -- Yields the smallest '.hi' files but at the cost of additional run-time. + -- | Read an interface file header, checking the magic number, version, and -- way. Returns the hash of the source file and a BinHandle which points at the -- start of the rest of the interface file data. @@ -158,30 +181,42 @@ getWithUserData name_cache bh = do -- Reading names has the side effect of adding them into the given NameCache. getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + fsReaderTable <- initFastStringReaderTable nameReaderTable <- initNameReaderTable name_cache - - - -- The order of these deserialisation matters! - -- - -- See Note [Order of deduplication tables during iface binary serialisation] for details. - fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) - let - fsReader = mkReaderFromTable fsReaderTable fsTable - bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - - nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) - let - nameReader = mkReaderFromTable nameReaderTable nameTable - bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - - pure bhName + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + + let -- For any 'ReaderTable', we decode the table that is found at the location + -- the forward reference points to. + -- After decoding the table, we create a 'BinaryReader' and immediately + -- add it to the 'ReaderUserData' of 'ReadBinHandle'. + decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle + decodeReaderTable tbl bh0 = do + table <- Binary.forwardGet bh (getTable tbl bh0) + let binaryReader = mkReaderFromTable tbl table + pure $ addReaderToUserData binaryReader bh0 + + -- Decode all the tables and populate the 'ReaderUserData'. + bhFinal <- foldM (\bh0 act -> act bh0) bh + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + [ decodeReaderTable fsReaderTable + , decodeReaderTable nameReaderTable + , decodeReaderTable ifaceTypeReaderTable + ] + + writeIORef bhRef (getReaderUserData bhFinal) + pure bhFinal -- | Write an interface file. -- -- See Note [Deduplication during iface binary serialisation] for details. -writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () -writeBinIface profile traceBinIface hi_path mod_iface = do +writeBinIface :: Profile -> TraceBinIFace -> CompressionIFace -> FilePath -> ModIface -> IO () +writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do bh <- openBinMem initBinMemSize let platform = profilePlatform profile put_ bh (binaryInterfaceMagic platform) @@ -195,7 +230,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p - putWithUserData traceBinIface bh mod_iface + putWithUserData traceBinIface compressionLevel bh mod_iface extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p @@ -209,9 +244,9 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () -putWithUserData traceBinIface bh payload = do - (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) +putWithUserData :: Binary a => TraceBinIFace -> CompressionIFace -> WriteBinHandle -> a -> IO () +putWithUserData traceBinIface compressionLevel bh payload = do + (name_count, fs_count, _b) <- putWithTables compressionLevel bh (\bh' -> put bh' payload) case traceBinIface of QuietBinIFace -> return () @@ -234,11 +269,12 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Order of deduplication tables during iface binary serialisation] -putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) -putWithTables bh' put_payload = do +putWithTables :: CompressionIFace -> WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables compressionLevel bh' put_payload = do -- Initialise deduplicating tables. (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initNameWriterTable + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel -- Initialise the 'WriterUserData'. let writerUserData = mkWriterUserData @@ -250,6 +286,7 @@ putWithTables bh' put_payload = do -- -- See Note [Binary UserData] , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + , mkSomeBinaryWriter @IfaceType ifaceTypeWriter ] let bh = setWriterUserData bh' writerUserData @@ -257,18 +294,24 @@ putWithTables bh' put_payload = do -- The order of these entries matters! -- -- See Note [Order of deduplication tables during iface binary serialisation] for details. - putAllTables bh [fast_wt, name_wt] $ do + putAllTables bh [fast_wt, name_wt, ifaceType_wt] $ do put_payload bh return (name_count, fs_count, r) - where - putAllTables _ [] act = do - a <- act - pure ([], a) - putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do - putAllTables bh xs act - pure (r : res, a) + +-- | Write all deduplication tables to disk after serialising the +-- main payload. +-- +-- Writes forward pointers to the deduplication tables before writing the payload +-- to allow deserialisation *before* the payload is read again. +putAllTables :: WriteBinHandle -> [WriterTable] -> IO b -> IO ([Int], b) +putAllTables _ [] act = do + a <- act + pure ([], a) +putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) -- | Initial ram buffer to allocate for writing interface files initBinMemSize :: Int @@ -450,6 +493,42 @@ Here, a visualisation of the table structure we currently have (ignoring 'Extens -- The symbol table -- +initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) +initReadIfaceTypeTable ud = do + pure $ + ReaderTable + { getTable = getGenericSymbolTable (\bh -> lazyGet' getIfaceType (setReaderUserData bh ud)) + , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) + } + +initWriteIfaceType :: CompressionIFace -> IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType compressionLevel = do + sym_tab <- initGenericSymbolTable @(Map IfaceType) + pure + ( WriterTable + { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) + } + , mkWriter $ ifaceWriter sym_tab + ) + where + ifaceWriter sym_tab = case compressionLevel of + NormalCompression -> literalIfaceTypeSerialiser + SafeExtraCompression -> ifaceTyConAppSerialiser sym_tab + MaximalCompression -> fullIfaceTypeSerialiser sym_tab + + ifaceTyConAppSerialiser sym_tab bh ty = case ty of + IfaceTyConApp {} -> do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + _ -> putIfaceType bh ty + + + fullIfaceTypeSerialiser sym_tab bh ty = do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + + literalIfaceTypeSerialiser = putIfaceType + initNameReaderTable :: NameCache -> IO (ReaderTable Name) initNameReaderTable cache = do ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -38,22 +38,21 @@ import Data.ByteString ( ByteString ) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import Data.Word ( Word8, Word32 ) -import Control.Monad ( replicateM, when, forM_ ) +import Control.Monad ( replicateM, when, forM_, foldM ) import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable, CompressionIFace) +import GHC.Iface.Type (IfaceType) +import System.IO.Unsafe (unsafeInterleaveIO) +import qualified GHC.Utils.Binary as Binary data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM Name (Int, HieName))) } -data HieDictionary = HieDictionary - { hie_dict_next :: !FastMutInt -- The next index to use - , hie_dict_map :: !(IORef (UniqFM FastString (Int,FastString))) -- indexed by FastString - } - initBinMemSize :: Int initBinMemSize = 1024*1024 @@ -74,8 +73,8 @@ putBinLine bh xs = do -- | Write a `HieFile` to the given `FilePath`, with a proper header and -- symbol tables for `Name`s and `FastString`s -writeHieFile :: FilePath -> HieFile -> IO () -writeHieFile hie_file_path hiefile = do +writeHieFile :: CompressionIFace -> FilePath -> HieFile -> IO () +writeHieFile compression hie_file_path hiefile = do bh0 <- openBinMem initBinMemSize -- Write the header: hieHeader followed by the @@ -84,58 +83,58 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ BSC.pack $ show hieVersion putBinLine bh0 $ ghcVersion - -- remember where the dictionary pointer will go - dict_p_p <- tellBinWriter bh0 - put_ bh0 dict_p_p + (fs_tbl, fs_w) <- initFastStringWriterTable + (name_tbl, name_w) <- initWriteNameTable + (iface_tbl, iface_w) <- initWriteIfaceType compression - -- remember where the symbol table pointer will go - symtab_p_p <- tellBinWriter bh0 - put_ bh0 symtab_p_p + let bh = setWriterUserData bh0 $ mkWriterUserData + [ mkSomeBinaryWriter @IfaceType iface_w + , mkSomeBinaryWriter @Name name_w + , mkSomeBinaryWriter @BindingName (simpleBindingNameWriter name_w) + , mkSomeBinaryWriter @FastString fs_w + ] - -- Make some initial state - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM :: IO (IORef (UniqFM Name (Int, HieName))) - let hie_symtab = HieSymbolTable { - hie_symtab_next = symtab_next, - hie_symtab_map = symtab_map } - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let hie_dict = HieDictionary { - hie_dict_next = dict_next_ref, - hie_dict_map = dict_map_ref } - - -- put the main thing - let bh = setWriterUserData bh0 - $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) - put_ bh hiefile - - -- write the symtab pointer at the front of the file - symtab_p <- tellBinWriter bh - putAt bh symtab_p_p symtab_p - seekBinWriter bh symtab_p - - -- write the symbol table itself - symtab_next' <- readFastMutInt symtab_next - symtab_map' <- readIORef symtab_map - putSymbolTable bh symtab_next' symtab_map' - - -- write the dictionary pointer at the front of the file - dict_p <- tellBinWriter bh - putAt bh dict_p_p dict_p - seekBinWriter bh dict_p - - -- write the dictionary itself - dict_next <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh dict_next dict_map + -- Discard number of written elements + -- Order matters! See Note [Order of deduplication tables during iface binary serialisation] + _ <- putAllTables bh [fs_tbl, name_tbl, iface_tbl] $ do + put_ bh hiefile -- and send the result to the file createDirectoryIfMissing True (takeDirectory hie_file_path) writeBinMem bh hie_file_path return () +initWriteNameTable :: IO (WriterTable, BinaryWriter Name) +initWriteNameTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + HieSymbolTable + { hie_symtab_next = symtab_next + , hie_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + +initReadNameTable :: NameCache -> IO (ReaderTable Name) +initReadNameTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymTabName tbl) + } + data HieFileResult = HieFileResult { hie_file_result_version :: Integer @@ -216,50 +215,32 @@ readHieFileHeader file bh0 = do readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do - dict <- get_dictionary bh0 + bhRef <- newIORef (error "used too soon") + -- It is important this is passed to 'getTable' + ud <- unsafeInterleaveIO (readIORef bhRef) + + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initReadNameTable name_cache + ifaceTypeReaderTable <- initReadIfaceTypeTable ud + -- read the symbol table so we are capable of reading the actual data - bh1 <- do - let bh1 = setReaderUserData bh0 - $ newReadState (error "getSymtabName") - (getDictFastString dict) - symtab <- get_symbol_table bh1 - let bh1' = setReaderUserData bh1 - $ newReadState (getSymTabName symtab) - (getDictFastString dict) - return bh1' + bh1 <- + foldM (\bh tblReader -> tblReader bh) bh0 + [ get_dictionary fsReaderTable + , get_dictionary nameReaderTable + , get_dictionary ifaceTypeReaderTable + ] -- load the actual data get bh1 where - get_dictionary bin_handle = do - dict_p <- get bin_handle - data_p <- tellBinReader bin_handle - seekBinReader bin_handle dict_p - dict <- getDictionary bin_handle - seekBinReader bin_handle data_p - return dict - - get_symbol_table bh1 = do - symtab_p <- get bh1 - data_p' <- tellBinReader bh1 - seekBinReader bh1 symtab_p - symtab <- getSymbolTable bh1 name_cache - seekBinReader bh1 data_p' - return symtab - -putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () -putFastString HieDictionary { hie_dict_next = j_r, - hie_dict_map = out_r} bh f - = do - out <- readIORef out_r - let !unique = getUnique f - case lookupUFM_Directly out unique of - Just (j, _) -> put_ bh (fromIntegral j :: Word32) - Nothing -> do - j <- readFastMutInt j_r - put_ bh (fromIntegral j :: Word32) - writeFastMutInt j_r (j + 1) - writeIORef out_r $! addToUFM_Directly out unique (j, f) + get_dictionary tbl bin_handle = do + fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + let + fsReader = mkReaderFromTable tbl fsTable + bhFs = addReaderToUserData fsReader bin_handle + pure bhFs + putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Iface.Load ( loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, findAndReadIface, readIface, writeIface, + flagsToIfCompression, moduleFreeHolesPrecise, needWiredInHomeIface, loadWiredInHomeIface, @@ -965,11 +966,18 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do -- | Write interface file -writeIface :: Logger -> Profile -> FilePath -> ModIface -> IO () -writeIface logger profile hi_file_path new_iface +writeIface :: Logger -> Profile -> CompressionIFace -> FilePath -> ModIface -> IO () +writeIface logger profile compression_level hi_file_path new_iface = do createDirectoryIfMissing True (takeDirectory hi_file_path) let printer = TraceBinIFace (debugTraceMsg logger 3) - writeBinIface profile printer hi_file_path new_iface + writeBinIface profile printer compression_level hi_file_path new_iface + +flagsToIfCompression :: DynFlags -> CompressionIFace +flagsToIfCompression dflags = case ifCompression dflags of + 0 -> NormalCompression + 1 -> NormalCompression + 2 -> SafeExtraCompression + _ -> MaximalCompression -- | @readIface@ tries just the one file. -- ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Utils.Fingerprint import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain +import GHC.Iface.Type (putIfaceType) fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f @@ -34,8 +35,12 @@ computeFingerprint put_nonbinding_name a = do put_ bh a fingerprintBinMem bh where - set_user_data bh = - setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + set_user_data bh = setWriterUserData bh $ mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter putIfaceType + , mkSomeBinaryWriter $ mkWriter put_nonbinding_name + , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally + , mkSomeBinaryWriter $ mkWriter putFS + ] -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -33,6 +33,8 @@ module GHC.Iface.Type ( ifForAllBndrVar, ifForAllBndrName, ifaceBndrName, ifTyConBinderVar, ifTyConBinderName, + -- Binary utilities + putIfaceType, getIfaceType, ifaceTypeSharedByte, -- Equality testing isIfaceLiftedTypeKind, @@ -90,11 +92,13 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) +import Data.Maybe (isJust) +import Data.Proxy +import qualified Data.Semigroup as Semi +import Data.Word (Word8) +import Control.Arrow (first) import Control.DeepSeq import Control.Monad ((<$!>)) -import Control.Arrow (first) -import qualified Data.Semigroup as Semi -import Data.Maybe( isJust ) {- ************************************************************************ @@ -109,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName @@ -2191,38 +2199,70 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ _ (IfaceFreeTyVar tv) - = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + put_ bh ty = + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ty - put_ bh (IfaceForAllTy aa ab) = do - putByte bh 0 - put_ bh aa - put_ bh ab - put_ bh (IfaceTyVar ad) = do - putByte bh 1 - put_ bh ad - put_ bh (IfaceAppTy ae af) = do - putByte bh 2 - put_ bh ae - put_ bh af - put_ bh (IfaceFunTy af aw ag ah) = do - putByte bh 3 - put_ bh af - put_ bh aw - put_ bh ag - put_ bh ah - put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 5; put_ bh tc; put_ bh tys } - put_ bh (IfaceCastTy a b) - = do { putByte bh 6; put_ bh a; put_ bh b } - put_ bh (IfaceCoercionTy a) - = do { putByte bh 7; put_ bh a } - put_ bh (IfaceTupleTy s i tys) - = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } - put_ bh (IfaceLitTy n) - = do { putByte bh 9; put_ bh n } + get bh = getIfaceTypeShared bh - get bh = do +-- | This is the byte tag we expect to read when the next +-- value is not an 'IfaceType' value, but an offset into a +-- lookup value. +-- +-- Must not overlap with any byte tag in 'getIfaceType'. +ifaceTypeSharedByte :: Word8 +ifaceTypeSharedByte = 99 + +-- | Like 'getIfaceType' but checks for a specific byte tag +-- that indicates that we won't be able to read a 'IfaceType' value +-- but rather an offset into a lookup table. Consequentially, +-- we look up the value for the 'IfaceType' in the look up table. +-- +-- See Note [Deduplication during iface binary serialisation] +-- for details. +getIfaceTypeShared :: ReadBinHandle -> IO IfaceType +getIfaceTypeShared bh = do + start <- tellBinReader bh + tag <- getByte bh + if ifaceTypeSharedByte == tag + then case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + else seekBinReader bh start >> getIfaceType bh + +putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType _ (IfaceFreeTyVar tv) + = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) + +putIfaceType bh (IfaceForAllTy aa ab) = do + putByte bh 0 + put_ bh aa + put_ bh ab +putIfaceType bh (IfaceTyVar ad) = do + putByte bh 1 + put_ bh ad +putIfaceType bh (IfaceAppTy ae af) = do + putByte bh 2 + put_ bh ae + put_ bh af +putIfaceType bh (IfaceFunTy af aw ag ah) = do + putByte bh 3 + put_ bh af + put_ bh aw + put_ bh ag + put_ bh ah +putIfaceType bh (IfaceTyConApp tc tys) + = do { putByte bh 5; put_ bh tc; put_ bh tys } +putIfaceType bh (IfaceCastTy a b) + = do { putByte bh 6; put_ bh a; put_ bh b } +putIfaceType bh (IfaceCoercionTy a) + = do { putByte bh 7; put_ bh a } +putIfaceType bh (IfaceTupleTy s i tys) + = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys } +putIfaceType bh (IfaceLitTy n) + = do { putByte bh 9; put_ bh n } + +getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType +getIfaceType bh = do h <- getByte bh case h of 0 -> do aa <- get bh ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -124,7 +124,7 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } -type LiteralMap a = Map.Map Literal a +type LiteralMap = Map.Map Literal -- TODO(22292): derive instance Functor StgArgMap where ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -314,7 +314,7 @@ putObject bh mod_name deps os = do put_ bh (moduleNameString mod_name) (fs_tbl, fs_writer) <- initFastStringWriterTable - let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh + let bh_fs = addWriterToUserData fs_writer bh forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -65,6 +65,8 @@ module GHC.Utils.Binary -- * Lazy Binary I/O lazyGet, lazyPut, + lazyGet', + lazyPut', lazyGetMaybe, lazyPutMaybe, @@ -87,10 +89,17 @@ module GHC.Utils.Binary initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, FSTable(..), getDictFastString, putDictFastString, + -- * Generic deduplication table + GenericSymbolTable(..), + initGenericSymbolTable, + getGenericSymtab, putGenericSymTab, + getGenericSymbolTable, putGenericSymbolTable, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..), -- * Newtypes for types that have canonically more than one valid encoding BindingName(..), + simpleBindingNameWriter, + simpleBindingNameReader, ) where import GHC.Prelude @@ -103,11 +112,11 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint -import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) +import GHC.Utils.Misc ( HasCallStack, HasDebugCallStack ) import Control.DeepSeq import Control.Monad ( when, (<$!>), unless, forM_, void ) @@ -133,6 +142,7 @@ import Data.List (unfoldr) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import Type.Reflection ( Typeable, SomeTypeRep(..) ) import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) @@ -143,6 +153,8 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) +import GHC.Data.TrieMap + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -231,20 +243,28 @@ setReaderUserData bh us = bh { rbm_userData = us } -- | Add 'SomeBinaryReader' as a known binary decoder. -- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', -- it is overwritten. -addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle -addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh +addReaderToUserData :: forall a. Typeable a => BinaryReader a -> ReadBinHandle -> ReadBinHandle +addReaderToUserData reader bh = bh { rbm_userData = (rbm_userData bh) - { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + { ud_reader_data = + let + typRep = Refl.typeRep @a + in + Map.insert (SomeTypeRep typRep) (SomeBinaryReader typRep reader) (ud_reader_data (rbm_userData bh)) } } -- | Add 'SomeBinaryWriter' as a known binary encoder. -- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', -- it is overwritten. -addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle -addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh +addWriterToUserData :: forall a . Typeable a => BinaryWriter a -> WriteBinHandle -> WriteBinHandle +addWriterToUserData writer bh = bh { wbm_userData = (wbm_userData bh) - { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + { ud_writer_data = + let + typRep = Refl.typeRep @a + in + Map.insert (SomeTypeRep typRep) (SomeBinaryWriter typRep writer) (ud_writer_data (wbm_userData bh)) } } @@ -1103,24 +1123,32 @@ forwardGet bh get_A = do -- Lazy reading/writing lazyPut :: Binary a => WriteBinHandle -> a -> IO () -lazyPut bh a = do +lazyPut = lazyPut' put_ + +lazyGet :: Binary a => ReadBinHandle -> IO a +lazyGet = lazyGet' get + +lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr - put_ bh a -- dump the object + f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => ReadBinHandle -> IO a -lazyGet bh = do +lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' f bh = do p <- get bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do - -- NB: Use a fresh off_r variable in the child thread, for thread + -- NB: Use a fresh rbm_off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { rbm_off_r = off_r } p_a + let bh' = bh { rbm_off_r = off_r } + seekBinReader bh' p_a + f bh' seekBinReader bh p -- skip over the object for now return a @@ -1174,6 +1202,12 @@ lazyGetMaybe bh = do newtype BindingName = BindingName { getBindingName :: Name } deriving ( Eq ) +simpleBindingNameWriter :: BinaryWriter Name -> BinaryWriter BindingName +simpleBindingNameWriter = coerce + +simpleBindingNameReader :: BinaryReader Name -> BinaryReader BindingName +simpleBindingNameReader = coerce + -- | Existential for 'BinaryWriter' with a type witness. data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) @@ -1185,7 +1219,7 @@ data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryRead -- See Note [Binary UserData] data WriterUserData = WriterUserData { - ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + ud_writer_data :: Map SomeTypeRep SomeBinaryWriter -- ^ A mapping from a type witness to the 'Writer' for the associated type. -- This is a 'Map' because microbenchmarks indicated this is more efficient -- than other representations for less than ten elements. @@ -1202,7 +1236,7 @@ data WriterUserData = -- See Note [Binary UserData] data ReaderUserData = ReaderUserData { - ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + ud_reader_data :: Map SomeTypeRep SomeBinaryReader -- ^ A mapping from a type witness to the 'Reader' for the associated type. -- This is a 'Map' because microbenchmarks indicated this is more efficient -- than other representations for less than ten elements. @@ -1216,12 +1250,12 @@ data ReaderUserData = mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData mkWriterUserData caches = noWriterUserData - { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (SomeTypeRep typRep, cache)) caches } mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData mkReaderUserData caches = noReaderUserData - { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (SomeTypeRep typRep, cache)) caches } mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter @@ -1347,6 +1381,110 @@ newtype WriterTable = WriterTable -- ^ Serialise a table to disk. Returns the number of written elements. } +-- ---------------------------------------------------------------------------- +-- Common data structures for constructing and maintaining lookup tables for +-- binary serialisation and deserialisation. +-- ---------------------------------------------------------------------------- + +-- | The 'GenericSymbolTable' stores a mapping from already seen elements to an index. +-- If an element wasn't seen before, it is added to the mapping together with a fresh +-- index. +-- +-- 'GenericSymbolTable' is a variant of a 'BinSymbolTable' that is polymorphic in the table implementation. +-- As such it can be used with any container that implements the 'TrieMap' type class. +-- +-- While 'GenericSymbolTable' is similar to the 'BinSymbolTable', it supports storing tree-like +-- structures such as 'Type' and 'IfaceType' more efficiently. +-- +data GenericSymbolTable m = GenericSymbolTable + { gen_symtab_next :: !FastMutInt + -- ^ The next index to use. + , gen_symtab_map :: !(IORef (m Int)) + -- ^ Given a symbol, find the symbol and return its index. + , gen_symtab_to_write :: !(IORef [Key m]) + -- ^ Reversed list of values to write into the buffer. + -- This is an optimisation, as it allows us to write out quickly all + -- newly discovered values that are discovered when serialising 'Key m' + -- to disk. + } + +-- | Initialise a 'GenericSymbolTable', initialising the index to '0'. +initGenericSymbolTable :: TrieMap m => IO (GenericSymbolTable m) +initGenericSymbolTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyTM + symtab_todo <- newIORef [] + pure $ GenericSymbolTable + { gen_symtab_next = symtab_next + , gen_symtab_map = symtab_map + , gen_symtab_to_write = symtab_todo + } + +-- | Serialise the 'GenericSymbolTable' to disk. +-- +-- Since 'GenericSymbolTable' stores tree-like structures, such as 'IfaceType', +-- serialising an element can add new elements to the mapping. +-- Thus, 'putGenericSymbolTable' first serialises all values, and then checks whether any +-- new elements have been discovered. If so, repeat the loop. +putGenericSymbolTable :: forall m. (TrieMap m) => GenericSymbolTable m -> (WriteBinHandle -> Key m -> IO ()) -> WriteBinHandle -> IO Int +{-# INLINE putGenericSymbolTable #-} +putGenericSymbolTable gen_sym_tab serialiser bh = do + putGenericSymbolTable bh + where + symtab_next = gen_symtab_next gen_sym_tab + symtab_to_write = gen_symtab_to_write gen_sym_tab + putGenericSymbolTable :: WriteBinHandle -> IO Int + putGenericSymbolTable bh = do + let loop = do + vs <- atomicModifyIORef' symtab_to_write (\a -> ([], a)) + case vs of + [] -> readFastMutInt symtab_next + todo -> do + mapM_ (\n -> serialiser bh n) (reverse todo) + loop + snd <$> + (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + loop) + +-- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. +getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) +getGenericSymbolTable deserialiser bh = do + sz <- forwardGet bh (get bh) :: IO Int + mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) + forM_ [0..(sz-1)] $ \i -> do + f <- deserialiser bh + writeArray mut_arr i f + unsafeFreeze mut_arr + +-- | Write an element 'Key m' to the given 'WriteBinHandle'. +-- +-- If the element was seen before, we simply write the index of that element to the +-- 'WriteBinHandle'. If we haven't seen it before, we add the element to +-- the 'GenericSymbolTable', increment the index, and return this new index. +putGenericSymTab :: (TrieMap m) => GenericSymbolTable m -> WriteBinHandle -> Key m -> IO () +{-# INLINE putGenericSymTab #-} +putGenericSymTab GenericSymbolTable{ + gen_symtab_map = symtab_map_ref, + gen_symtab_next = symtab_next, + gen_symtab_to_write = symtab_todo } + bh val = do + symtab_map <- readIORef symtab_map_ref + case lookupTM val symtab_map of + Just off -> put_ bh (fromIntegral off :: Word32) + Nothing -> do + off <- readFastMutInt symtab_next + writeFastMutInt symtab_next (off+1) + writeIORef symtab_map_ref + $! insertTM val off symtab_map + atomicModifyIORef symtab_todo (\todo -> (val : todo, ())) + put_ bh (fromIntegral off :: Word32) + +-- | Read a value from a 'SymbolTable'. +getGenericSymtab :: Binary a => SymbolTable a -> ReadBinHandle -> IO a +getGenericSymtab symtab bh = do + i :: Word32 <- get bh + return $! symtab ! fromIntegral i + --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- ===================================== compiler/ghc.cabal.in ===================================== @@ -594,6 +594,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1777,3 +1777,12 @@ as such you shouldn't need to set any of them explicitly. A flag This flag sets the size (in bytes) threshold above which the second approach is used. You can disable the second approach entirely by setting the threshold to 0. + +.. ghc-flag:: -fwrite-if-compression=⟨n⟩ + :shortdesc: *default: 2.* Tweak the level of interface file compression. + :type: dynamic + :category: optimization + + :default: 2 + + TODO ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkVisFunTyMany` wordTy `mkVisFunTyMany` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 9177f04899f0d770f4b393edcc3d1761f91a0a14 +Subproject commit 709c7f41af32c3085ed2e6d57a76e250bd68f24b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fc1995a1704d41a3bea6cac7edd172979a5c5e1...00c8808be5f9a57ab2d9f294a8d782ffe428300f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fc1995a1704d41a3bea6cac7edd172979a5c5e1...00c8808be5f9a57ab2d9f294a8d782ffe428300f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 10:28:46 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 06:28:46 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] Reuse the 'ReadBinMem' after sharing to avoid recomputations Message-ID: <66263bdee089_7a389352e0ec114571@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 384a1c56 by Fendor at 2024-04-22T12:28:32+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 7 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -166,14 +167,18 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- get bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start pure mod_iface { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData } @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -158,7 +158,7 @@ shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } @@ -318,40 +318,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -20,7 +20,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,9 +33,10 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, - castBin, + castBin, castRelBin, withBinBuffer, freezeWriteHandle, thawReadHandle, @@ -48,6 +49,7 @@ module GHC.Utils.Binary putAt, getAt, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -102,6 +104,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -126,7 +132,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -156,7 +162,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -196,6 +201,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -289,9 +351,15 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +newtype RelBin a = RelBin (Bin a) + deriving (Eq, Ord, Show, Bounded) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +castRelBin :: RelBin a -> RelBin b +castRelBin (RelBin bin) = RelBin $ castBin bin + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -382,12 +450,19 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !p)) = do + ix <- readFastMutInt ix_r + if (ix + p > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (ix + p) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1108,6 +1183,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBin a) where + put_ bh (RelBin (BinPtr i)) = putWord32 bh (fromIntegral i :: Word32) + get bh = do i <- getWord32 bh; return (RelBin $ BinPtr (fromIntegral (i :: Word32))) -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1136,7 +1216,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1148,6 +1228,48 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + let + BinPtr end = a + BinPtr start = pre_a + putAt bh pre_a (RelBin $ BinPtr $ end - start) + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + (BinPtr s) <- tellBinReader bh + -- read forward reference + p@(BinPtr off) <- get bh -- a BinPtr + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh (BinPtr $ s + off) + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1157,19 +1279,21 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' Nothing (\_ -> get) -lazyPut' :: HasCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBinWriter bh + pre_a@(BinPtr start) <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object - q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + q@(BinPtr end) <- tellBinWriter bh -- q = ptr to after object + putAt bh pre_a (RelBin $ BinPtr $ end - start) -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q -lazyGet' :: HasCallStack => Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a +lazyGet' :: Maybe (IORef ReadBinHandle) -> (Bin () -> ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' mbh f bh = do - p <- get bh -- a BinPtr + BinPtr s <- tellBinReader bh + BinPtr off <- get bh -- a BinPtr + let p_abs = BinPtr (s + off) p_a <- tellBinReader bh -- Do this before to avoid retaining reference to old BH inside the unsafeInterleaveIO. let !get_inner_bh = maybe (pure bh) readIORef mbh @@ -1180,8 +1304,8 @@ lazyGet' mbh f bh = do off_r <- newFastMutInt 0 let bh' = inner_bh { rbm_off_r = off_r } seekBinReader bh' p_a - f p bh' - seekBinReader bh p -- skip over the object for now + f p_abs bh' + seekBinReader bh p_abs -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1475,13 +1599,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) -- Using lazyPut/lazyGet is quite space inefficient as each usage will allocate a large closure -- (6 arguments-ish). View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/384a1c567d8d1c26118eb7060a5f2ff96e47c952 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/384a1c567d8d1c26118eb7060a5f2ff96e47c952 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 12:29:11 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 08:29:11 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 6 commits: Add Eq and Ord instance to `IfaceType` Message-ID: <6626581768a9_260ecfbb0cec276f6@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 1b2f0ff0 by Fendor at 2024-04-22T14:27:42+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - dd01fcb4 by Fendor at 2024-04-22T14:27:47+02:00 Break cyclic module dependency - - - - - 7e5a678d by Fendor at 2024-04-22T14:28:57+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - a98ae613 by Matthew Pickering at 2024-04-22T14:29:02+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 45e812de by Matthew Pickering at 2024-04-22T14:29:02+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - f6d5a5c2 by Fendor at 2024-04-22T14:29:02+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - compiler/Language/Haskell/Syntax/Type.hs - compiler/Language/Haskell/Syntax/Type.hs-boot - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00c8808be5f9a57ab2d9f294a8d782ffe428300f...f6d5a5c2a34a43d216eb0b0ad478cfdd9e6d1bd0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00c8808be5f9a57ab2d9f294a8d782ffe428300f...f6d5a5c2a34a43d216eb0b0ad478cfdd9e6d1bd0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 12:49:19 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 22 Apr 2024 08:49:19 -0400 Subject: [Git][ghc/ghc][wip/clyring/seqHash-DmdTransformer] try being a bit less stupid about absent demands Message-ID: <66265ccf1ec87_260ecfe97bcc2963b@gitlab.mail> Matthew Craven pushed to branch wip/clyring/seqHash-DmdTransformer at Glasgow Haskell Compiler / GHC Commits: 3bd15939 by Matthew Craven at 2024-04-22T08:48:39-04:00 try being a bit less stupid about absent demands - - - - - 4 changed files: - compiler/GHC/Types/Demand.hs - testsuite/tests/dmdanal/should_compile/all.T - testsuite/tests/dmdanal/should_compile/DmdAnal_evaluate.hs → testsuite/tests/dmdanal/sigs/DmdAnal_evaluate.hs - testsuite/tests/dmdanal/sigs/all.T Changes: ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -658,7 +658,7 @@ viewDmdPair (D n sd) = (n, sd) -- If the matched demand was 'BotDmd', it will match as @C_10 :* botSubDmd at . -- The builder of this pattern synonym simply /discards/ the 'SubDemand' if the -- 'Card' was absent and returns 'AbsDmd' or 'BotDmd' instead. It will assert --- that the discarded sub-demand was 'seqSubDmd' and 'botSubDmd', respectively. +-- that the discarded sub-demand was 'botSubDmd'. -- -- Call sites should consider whether they really want to look at the -- 'SubDemand' of an absent demand and match on 'AbsDmd' and/or 'BotDmd' @@ -2361,16 +2361,22 @@ dmdTransformSeqHash :: DmdTransformer dmdTransformSeqHash sd0 = let !(n1, sd1) = peelCallDmd sd0 !(n2, sd2) = peelCallDmd sd1 - !result_card = n1 `multCard` n2 `multCard` C_01 + !num_calls = n1 `multCard` n2 + arg_SubDmd = case viewProd 2 sd2 of + Just (_, [_state_token_dmd, result_dmd]) + -> case trimBoxity result_dmd of + -- trimBoxity: We can't unbox through seq# yet. (But see #24334.) + AbsDmd -> seqSubDmd + _ :* result_SubDmd -> result_SubDmd + _ -> topSubDmd + !arg_dmd = num_calls `multDmd` (C_01 :* arg_SubDmd) -- Why C_01? A call to seq# always evaluates its argument exactly once, -- but since the evalaution it performs is well-sequenced -- we must not consider it strict. See Note [seq# magic], (SEQ3) - in case viewProd 2 sd2 of - Just (_, [_state_token_dmd, result_dmd]) - | _ :* !result_SubDmd <- trimBoxity result_dmd - -- trimBoxity: We can't unbox through seq# yet. (But see #24334.) - -> DmdType nopDmdEnv [result_card :* result_SubDmd, topDmd] - _ -> DmdType nopDmdEnv [result_card :* topSubDmd , topDmd] + !tok_dmd = num_calls `multDmd` topDmd + in --pprTrace "dmdTransformSeqHash" + --(ppr sd0 $$ ppr (num_calls, sd2) $$ ppr arg_dmd $$ ppr tok_dmd) + DmdType nopDmdEnv [arg_dmd, tok_dmd] {- Note [What are demand signatures?] ===================================== testsuite/tests/dmdanal/should_compile/all.T ===================================== @@ -16,7 +16,6 @@ test('test', normal, compile, ['']) test('tst', normal, compile, ['']) test('unu', normal, compile, ['']) test('newtype', req_profiling, compile, ['-prof -fprof-auto']) -test('DmdAnal_evaluate', normal, compile, ['-ddump-dmdanal -dsuppress-uniques -dno-typeable-binds']) test('T1988', normal, compile, ['']) test('T8467', normal, compile, ['']) test('T8037', normal, compile, ['']) ===================================== testsuite/tests/dmdanal/should_compile/DmdAnal_evaluate.hs → testsuite/tests/dmdanal/sigs/DmdAnal_evaluate.hs ===================================== @@ -20,3 +20,9 @@ funD :: (Int, Int) -> IO Int funD p = do (x, y) <- evaluate p evaluate (x + y) + +funE :: a -> b -> IO a +funE x y = do + x' <- evaluate x + _ <- evaluate y + pure x' ===================================== testsuite/tests/dmdanal/sigs/all.T ===================================== @@ -40,3 +40,4 @@ test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) test('T22241', normal, compile, ['']) test('T21737', normal, compile, ['']) +test('DmdAnal_evaluate', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bd159396a4450ae074f013207e23dc729078fb2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bd159396a4450ae074f013207e23dc729078fb2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 13:01:26 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 22 Apr 2024 09:01:26 -0400 Subject: [Git][ghc/ghc][wip/clyring/seqHash-DmdTransformer] fixup? Message-ID: <66265fa64f107_260ecf10afe503426d@gitlab.mail> Matthew Craven pushed to branch wip/clyring/seqHash-DmdTransformer at Glasgow Haskell Compiler / GHC Commits: e59e4342 by Matthew Craven at 2024-04-22T09:01:06-04:00 fixup? - - - - - 1 changed file: - compiler/GHC/Types/Demand.hs Changes: ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -2364,9 +2364,8 @@ dmdTransformSeqHash sd0 = let !num_calls = n1 `multCard` n2 arg_SubDmd = case viewProd 2 sd2 of Just (_, [_state_token_dmd, result_dmd]) - -> case trimBoxity result_dmd of + -> case trimBoxity (strictifyDmd result_dmd) of -- trimBoxity: We can't unbox through seq# yet. (But see #24334.) - AbsDmd -> seqSubDmd _ :* result_SubDmd -> result_SubDmd _ -> topSubDmd !arg_dmd = num_calls `multDmd` (C_01 :* arg_SubDmd) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e59e4342276ecc9bd980143ad4b98e6b9b1a0c1e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e59e4342276ecc9bd980143ad4b98e6b9b1a0c1e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 13:16:20 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Mon, 22 Apr 2024 09:16:20 -0400 Subject: [Git][ghc/ghc][wip/fendor/lazier-corebindings] Typecheck corebindings lazily during bytecode generation Message-ID: <66266324efd33_260ecf1300b8c46634@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/lazier-corebindings at Glasgow Haskell Compiler / GHC Commits: e84ada86 by Fendor at 2024-04-22T15:10:02+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 1 changed file: - compiler/GHC/Driver/Main.hs Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e84ada866413275db906807622d049e49054a837 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e84ada866413275db906807622d049e49054a837 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 13:49:03 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 22 Apr 2024 09:49:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/reinstallable-th Message-ID: <66266acfe587e_260ecf17725d0616f7@gitlab.mail> Teo Camarasu pushed new branch wip/reinstallable-th at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/reinstallable-th You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 13:55:47 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 22 Apr 2024 09:55:47 -0400 Subject: [Git][ghc/ghc][wip/reinstallable-th] wip: try moving Language.Haskell.TH.Syntax into ghc-internal Message-ID: <66266c637cd31_260ecf18d5684661a1@gitlab.mail> Teo Camarasu pushed to branch wip/reinstallable-th at Glasgow Haskell Compiler / GHC Commits: b992f345 by Teo Camarasu at 2024-04-22T14:54:44+01:00 wip: try moving Language.Haskell.TH.Syntax into ghc-internal - - - - - 3 changed files: - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-internal/ghc-internal.cabal - + libraries/ghc-internal/src/Language/Haskell/TH/Lib/Syntax.hs Changes: ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,7 +36,6 @@ Flag bootstrap Manual: True Library - hs-source-dirs: @SourceRoot@ default-language: Haskell2010 other-extensions: DeriveGeneric default-extensions: NoImplicitPrelude @@ -45,7 +44,6 @@ Library GHC.LanguageExtensions.Type GHC.ForeignSrcLang.Type GHC.Lexeme - Language.Haskell.TH.Lib.Syntax Language.Haskell.TH.Lib.Internal Language.Haskell.TH.Lib.Map Language.Haskell.TH.Quote @@ -55,7 +53,17 @@ Library build-depends: base >= 4.7 && < 4.21 , ghc-prim , pretty - if !flag(bootstrap) + if flag(bootstrap) + cpp-options: -DBOOTSTRAP_TH + hs-source-dirs: @SourceRoot@ ../ghc-internal/src + exposed-modules: + Language.Haskell.TH.Lib.Syntax + else + build-depends: + ghc-internal + reexported-modules: + Language.Haskell.TH.Lib.Syntax + hs-source-dirs: @SourceRoot@ -- We need to set the unit ID to template-haskell (without a -- version number) as it's magic. ghc-options: -this-unit-id ghc-boot-th ===================================== libraries/ghc-internal/ghc-internal.cabal ===================================== @@ -91,6 +91,7 @@ Library ghc-bignum >= 1.0 && < 2.0 exposed-modules: + Language.Haskell.TH.Lib.Syntax GHC.Internal.ClosureTypes GHC.Internal.Control.Arrow GHC.Internal.Control.Category ===================================== libraries/ghc-internal/src/Language/Haskell/TH/Lib/Syntax.hs ===================================== @@ -0,0 +1,2607 @@ +{-# OPTIONS_HADDOCK not-home #-} -- we want users to import Language.Haskell.TH.Syntax instead +{-# LANGUAGE CPP, DeriveDataTypeable, + DeriveGeneric, FlexibleInstances, DefaultSignatures, + RankNTypes, RoleAnnotations, ScopedTypeVariables, + MagicHash, KindSignatures, PolyKinds, TypeApplications, DataKinds, + GADTs, UnboxedTuples, UnboxedSums, TypeOperators, + Trustworthy, DeriveFunctor, DeriveTraversable, + BangPatterns, RecordWildCards, ImplicitParams #-} + +{-# LANGUAGE StandaloneKindSignatures #-} + +----------------------------------------------------------------------------- +-- | +-- Module : Language.Haskell.Syntax +-- Copyright : (c) The University of Glasgow 2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : libraries at haskell.org +-- Stability : experimental +-- Portability : portable +-- +-- Abstract syntax definitions for Template Haskell. +-- +----------------------------------------------------------------------------- + +module Language.Haskell.TH.Lib.Syntax + ( module Language.Haskell.TH.Lib.Syntax + -- * Language extensions + , Extension(..) + , ForeignSrcLang(..) + -- * Notes + -- ** Unresolved Infix + -- $infix + ) where + +#ifndef BOOTSTRAP_TH +import GHC.Internal.Base hiding (Module, Type) +import GHC.Internal.Generics (Generic) +import GHC.Internal.Show +import GHC.Internal.Data.Data +import GHC.Internal.Word +#else +import Prelude +import Data.Data hiding (Fixity(..)) +import Data.IORef +import System.IO.Unsafe ( unsafePerformIO ) +import GHC.IO.Unsafe ( unsafeDupableInterleaveIO ) +import Control.Monad.IO.Class (MonadIO (..)) +import Control.Monad.Fix (MonadFix (..)) +import Control.Exception (BlockedIndefinitelyOnMVar (..), catch, throwIO) +import Control.Exception.Base (FixIOException (..)) +import Control.Concurrent.MVar (newEmptyMVar, readMVar, putMVar) +import System.IO ( hPutStrLn, stderr ) +import Data.Char ( isAlpha, isAlphaNum, isUpper ) +import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.Word +import GHC.Generics ( Generic ) +import qualified Data.Kind as Kind (Type) +import GHC.Ptr ( Ptr, plusPtr ) +import GHC.Lexeme ( startsVarSym, startsVarId ) +import GHC.ForeignSrcLang.Type +import GHC.LanguageExtensions.Type (Extension(..)) +import Prelude hiding (Applicative(..)) +import Foreign.ForeignPtr +import Foreign.C.String +import Foreign.C.Types +import GHC.Types (TYPE, RuntimeRep(..), Levity(..)) +#endif + + +----------------------------------------------------- +-- +-- The Quasi class +-- +----------------------------------------------------- + +class (MonadIO m, MonadFail m) => Quasi m where + qNewName :: String -> m Name + -- ^ Fresh names + + -- Error reporting and recovery + qReport :: Bool -> String -> m () -- ^ Report an error (True) or warning (False) + -- ...but carry on; use 'fail' to stop + qRecover :: m a -- ^ the error handler + -> m a -- ^ action which may fail + -> m a -- ^ Recover from the monadic 'fail' + + -- Inspect the type-checker's environment + qLookupName :: Bool -> String -> m (Maybe Name) + -- True <=> type namespace, False <=> value namespace + qReify :: Name -> m Info + qReifyFixity :: Name -> m (Maybe Fixity) + qReifyType :: Name -> m Type + qReifyInstances :: Name -> [Type] -> m [Dec] + -- Is (n tys) an instance? + -- Returns list of matching instance Decs + -- (with empty sub-Decs) + -- Works for classes and type functions + qReifyRoles :: Name -> m [Role] + qReifyAnnotations :: Data a => AnnLookup -> m [a] + qReifyModule :: Module -> m ModuleInfo + qReifyConStrictness :: Name -> m [DecidedStrictness] + + qLocation :: m Loc + + qRunIO :: IO a -> m a + qRunIO = liftIO + -- ^ Input/output (dangerous) + qGetPackageRoot :: m FilePath + + qAddDependentFile :: FilePath -> m () + + qAddTempFile :: String -> m FilePath + + qAddTopDecls :: [Dec] -> m () + + qAddForeignFilePath :: ForeignSrcLang -> String -> m () + + qAddModFinalizer :: Q () -> m () + + qAddCorePlugin :: String -> m () + + qGetQ :: Typeable a => m (Maybe a) + + qPutQ :: Typeable a => a -> m () + + qIsExtEnabled :: Extension -> m Bool + qExtsEnabled :: m [Extension] + + qPutDoc :: DocLoc -> String -> m () + qGetDoc :: DocLoc -> m (Maybe String) + +----------------------------------------------------- +-- The IO instance of Quasi +-- +-- This instance is used only when running a Q +-- computation in the IO monad, usually just to +-- print the result. There is no interesting +-- type environment, so reification isn't going to +-- work. +-- +----------------------------------------------------- + +instance Quasi IO where + qNewName = newNameIO + + qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) + qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) + + qLookupName _ _ = badIO "lookupName" + qReify _ = badIO "reify" + qReifyFixity _ = badIO "reifyFixity" + qReifyType _ = badIO "reifyFixity" + qReifyInstances _ _ = badIO "reifyInstances" + qReifyRoles _ = badIO "reifyRoles" + qReifyAnnotations _ = badIO "reifyAnnotations" + qReifyModule _ = badIO "reifyModule" + qReifyConStrictness _ = badIO "reifyConStrictness" + qLocation = badIO "currentLocation" + qRecover _ _ = badIO "recover" -- Maybe we could fix this? + qGetPackageRoot = badIO "getProjectRoot" + qAddDependentFile _ = badIO "addDependentFile" + qAddTempFile _ = badIO "addTempFile" + qAddTopDecls _ = badIO "addTopDecls" + qAddForeignFilePath _ _ = badIO "addForeignFilePath" + qAddModFinalizer _ = badIO "addModFinalizer" + qAddCorePlugin _ = badIO "addCorePlugin" + qGetQ = badIO "getQ" + qPutQ _ = badIO "putQ" + qIsExtEnabled _ = badIO "isExtEnabled" + qExtsEnabled = badIO "extsEnabled" + qPutDoc _ _ = badIO "putDoc" + qGetDoc _ = badIO "getDoc" + +instance Quote IO where + newName = newNameIO + +newNameIO :: String -> IO Name +newNameIO s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x)) + ; pure (mkNameU s n) } + +badIO :: String -> IO a +badIO op = do { qReport True ("Can't do `" ++ op ++ "' in the IO monad") + ; fail "Template Haskell failure" } + +-- Global variable to generate unique symbols +counter :: IORef Uniq +{-# NOINLINE counter #-} +counter = unsafePerformIO (newIORef 0) + + +----------------------------------------------------- +-- +-- The Q monad +-- +----------------------------------------------------- + +newtype Q a = Q { unQ :: forall m. Quasi m => m a } + +-- \"Runs\" the 'Q' monad. Normal users of Template Haskell +-- should not need this function, as the splice brackets @$( ... )@ +-- are the usual way of running a 'Q' computation. +-- +-- This function is primarily used in GHC internals, and for debugging +-- splices by running them in 'IO'. +-- +-- Note that many functions in 'Q', such as 'reify' and other compiler +-- queries, are not supported when running 'Q' in 'IO'; these operations +-- simply fail at runtime. Indeed, the only operations guaranteed to succeed +-- are 'newName', 'runIO', 'reportError' and 'reportWarning'. +runQ :: Quasi m => Q a -> m a +runQ (Q m) = m + +instance Monad Q where + Q m >>= k = Q (m >>= \x -> unQ (k x)) + (>>) = (*>) + +instance MonadFail Q where + fail s = report True s >> Q (fail "Q monad failure") + +instance Functor Q where + fmap f (Q x) = Q (fmap f x) + +instance Applicative Q where + pure x = Q (pure x) + Q f <*> Q x = Q (f <*> x) + Q m *> Q n = Q (m *> n) + +-- | @since 2.17.0.0 +instance Semigroup a => Semigroup (Q a) where + (<>) = liftA2 (<>) + +-- | @since 2.17.0.0 +instance Monoid a => Monoid (Q a) where + mempty = pure mempty + +-- | If the function passed to 'mfix' inspects its argument, +-- the resulting action will throw a 'FixIOException'. +-- +-- @since 2.17.0.0 +instance MonadFix Q where + -- We use the same blackholing approach as in fixIO. + -- See Note [Blackholing in fixIO] in System.IO in base. + mfix k = do + m <- runIO newEmptyMVar + ans <- runIO (unsafeDupableInterleaveIO + (readMVar m `catch` \BlockedIndefinitelyOnMVar -> + throwIO FixIOException)) + result <- k ans + runIO (putMVar m result) + return result + + +----------------------------------------------------- +-- +-- The Quote class +-- +----------------------------------------------------- + + + +-- | The 'Quote' class implements the minimal interface which is necessary for +-- desugaring quotations. +-- +-- * The @Monad m@ superclass is needed to stitch together the different +-- AST fragments. +-- * 'newName' is used when desugaring binding structures such as lambdas +-- to generate fresh names. +-- +-- Therefore the type of an untyped quotation in GHC is `Quote m => m Exp` +-- +-- For many years the type of a quotation was fixed to be `Q Exp` but by +-- more precisely specifying the minimal interface it enables the `Exp` to +-- be extracted purely from the quotation without interacting with `Q`. +class Monad m => Quote m where + {- | + Generate a fresh name, which cannot be captured. + + For example, this: + + @f = $(do + nm1 <- newName \"x\" + let nm2 = 'mkName' \"x\" + return ('LamE' ['VarP' nm1] (LamE [VarP nm2] ('VarE' nm1))) + )@ + + will produce the splice + + >f = \x0 -> \x -> x0 + + In particular, the occurrence @VarE nm1@ refers to the binding @VarP nm1@, + and is not captured by the binding @VarP nm2 at . + + Although names generated by @newName@ cannot /be captured/, they can + /capture/ other names. For example, this: + + >g = $(do + > nm1 <- newName "x" + > let nm2 = mkName "x" + > return (LamE [VarP nm2] (LamE [VarP nm1] (VarE nm2))) + > ) + + will produce the splice + + >g = \x -> \x0 -> x0 + + since the occurrence @VarE nm2@ is captured by the innermost binding + of @x@, namely @VarP nm1 at . + -} + newName :: String -> m Name + +instance Quote Q where + newName s = Q (qNewName s) + +----------------------------------------------------- +-- +-- The TExp type +-- +----------------------------------------------------- + +type TExp :: TYPE r -> Kind.Type +type role TExp nominal -- See Note [Role of TExp] +newtype TExp a = TExp + { unType :: Exp -- ^ Underlying untyped Template Haskell expression + } +-- ^ Typed wrapper around an 'Exp'. +-- +-- This is the typed representation of terms produced by typed quotes. +-- +-- Representation-polymorphic since /template-haskell-2.16.0.0/. + +-- | Discard the type annotation and produce a plain Template Haskell +-- expression +-- +-- Representation-polymorphic since /template-haskell-2.16.0.0/. +unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m => m (TExp a) -> m Exp +unTypeQ m = do { TExp e <- m + ; return e } + +-- | Annotate the Template Haskell expression with a type +-- +-- This is unsafe because GHC cannot check for you that the expression +-- really does have the type you claim it has. +-- +-- Representation-polymorphic since /template-haskell-2.16.0.0/. +unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> m (TExp a) +unsafeTExpCoerce m = do { e <- m + ; return (TExp e) } + +{- Note [Role of TExp] +~~~~~~~~~~~~~~~~~~~~~~ +TExp's argument must have a nominal role, not phantom as would +be inferred (#8459). Consider + + e :: Code Q Age + e = [|| MkAge 3 ||] + + foo = $(coerce e) + 4::Int + +The splice will evaluate to (MkAge 3) and you can't add that to +4::Int. So you can't coerce a (Code Q Age) to a (Code Q Int). -} + +-- Code constructor +#if __GLASGOW_HASKELL__ >= 909 +type Code :: (Kind.Type -> Kind.Type) -> forall r. TYPE r -> Kind.Type + -- See Note [Foralls to the right in Code] +#else +type Code :: (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type +#endif +type role Code representational nominal -- See Note [Role of TExp] +newtype Code m a = Code + { examineCode :: m (TExp a) -- ^ Underlying monadic value + } +-- ^ Represents an expression which has type @a@, built in monadic context @m at . Built on top of 'TExp', typed +-- expressions allow for type-safe splicing via: +-- +-- - typed quotes, written as @[|| ... ||]@ where @...@ is an expression; if +-- that expression has type @a@, then the quotation has type +-- @Quote m => Code m a@ +-- +-- - typed splices inside of typed quotes, written as @$$(...)@ where @...@ +-- is an arbitrary expression of type @Quote m => Code m a@ +-- +-- Traditional expression quotes and splices let us construct ill-typed +-- expressions: +-- +-- >>> fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |]) +-- GHC.Types.True GHC.Classes.== "foo" +-- >>> GHC.Types.True GHC.Classes.== "foo" +-- error: +-- • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ +-- • In the second argument of ‘(==)’, namely ‘"foo"’ +-- In the expression: True == "foo" +-- In an equation for ‘it’: it = True == "foo" +-- +-- With typed expressions, the type error occurs when /constructing/ the +-- Template Haskell expression: +-- +-- >>> fmap ppr $ runQ (unTypeCode [|| True == $$( [|| "foo" ||] ) ||]) +-- error: +-- • Couldn't match type ‘[Char]’ with ‘Bool’ +-- Expected type: Code Q Bool +-- Actual type: Code Q [Char] +-- • In the Template Haskell quotation [|| "foo" ||] +-- In the expression: [|| "foo" ||] +-- In the Template Haskell splice $$([|| "foo" ||]) + + +{- Note [Foralls to the right in Code] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Code has the following type signature: + type Code :: (Kind.Type -> Kind.Type) -> forall r. TYPE r -> Kind.Type + +This allows us to write + data T (f :: forall r . (TYPE r) -> Type) = MkT (f Int) (f Int#) + + tcodeq :: T (Code Q) + tcodeq = MkT [||5||] [||5#||] + +If we used the slightly more straightforward signature + type Code :: foral r. (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type + +then the example above would become ill-typed. (See #23592 for some discussion.) +-} + +-- | Unsafely convert an untyped code representation into a typed code +-- representation. +unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> Code m a +unsafeCodeCoerce m = Code (unsafeTExpCoerce m) + +-- | Lift a monadic action producing code into the typed 'Code' +-- representation +liftCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . m (TExp a) -> Code m a +liftCode = Code + +-- | Extract the untyped representation from the typed representation +unTypeCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m + => Code m a -> m Exp +unTypeCode = unTypeQ . examineCode + +-- | Modify the ambient monad used during code generation. For example, you +-- can use `hoistCode` to handle a state effect: +-- @ +-- handleState :: Code (StateT Int Q) a -> Code Q a +-- handleState = hoistCode (flip runState 0) +-- @ +hoistCode :: forall m n (r :: RuntimeRep) (a :: TYPE r) . Monad m + => (forall x . m x -> n x) -> Code m a -> Code n a +hoistCode f (Code a) = Code (f a) + + +-- | Variant of (>>=) which allows effectful computations to be injected +-- into code generation. +bindCode :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> (a -> Code m b) -> Code m b +bindCode q k = liftCode (q >>= examineCode . k) + +-- | Variant of (>>) which allows effectful computations to be injected +-- into code generation. +bindCode_ :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> Code m b -> Code m b +bindCode_ q c = liftCode ( q >> examineCode c) + +-- | A useful combinator for embedding monadic actions into 'Code' +-- @ +-- myCode :: ... => Code m a +-- myCode = joinCode $ do +-- x <- someSideEffect +-- return (makeCodeWith x) +-- @ +joinCode :: forall m (r :: RuntimeRep) (a :: TYPE r) . Monad m + => m (Code m a) -> Code m a +joinCode = flip bindCode id + +---------------------------------------------------- +-- Packaged versions for the programmer, hiding the Quasi-ness + + +-- | Report an error (True) or warning (False), +-- but carry on; use 'fail' to stop. +report :: Bool -> String -> Q () +report b s = Q (qReport b s) +{-# DEPRECATED report "Use reportError or reportWarning instead" #-} -- deprecated in 7.6 + +-- | Report an error to the user, but allow the current splice's computation to carry on. To abort the computation, use 'fail'. +reportError :: String -> Q () +reportError = report True + +-- | Report a warning to the user, and carry on. +reportWarning :: String -> Q () +reportWarning = report False + +-- | Recover from errors raised by 'reportError' or 'fail'. +recover :: Q a -- ^ handler to invoke on failure + -> Q a -- ^ computation to run + -> Q a +recover (Q r) (Q m) = Q (qRecover r m) + +-- We don't export lookupName; the Bool isn't a great API +-- Instead we export lookupTypeName, lookupValueName +lookupName :: Bool -> String -> Q (Maybe Name) +lookupName ns s = Q (qLookupName ns s) + +-- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details. +lookupTypeName :: String -> Q (Maybe Name) +lookupTypeName s = Q (qLookupName True s) + +-- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details. +lookupValueName :: String -> Q (Maybe Name) +lookupValueName s = Q (qLookupName False s) + +{- +Note [Name lookup] +~~~~~~~~~~~~~~~~~~ +-} +{- $namelookup #namelookup# +The functions 'lookupTypeName' and 'lookupValueName' provide +a way to query the current splice's context for what names +are in scope. The function 'lookupTypeName' queries the type +namespace, whereas 'lookupValueName' queries the value namespace, +but the functions are otherwise identical. + +A call @lookupValueName s@ will check if there is a value +with name @s@ in scope at the current splice's location. If +there is, the @Name@ of this value is returned; +if not, then @Nothing@ is returned. + +The returned name cannot be \"captured\". +For example: + +> f = "global" +> g = $( do +> Just nm <- lookupValueName "f" +> [| let f = "local" in $( varE nm ) |] + +In this case, @g = \"global\"@; the call to @lookupValueName@ +returned the global @f@, and this name was /not/ captured by +the local definition of @f at . + +The lookup is performed in the context of the /top-level/ splice +being run. For example: + +> f = "global" +> g = $( [| let f = "local" in +> $(do +> Just nm <- lookupValueName "f" +> varE nm +> ) |] ) + +Again in this example, @g = \"global\"@, because the call to + at lookupValueName@ queries the context of the outer-most @$(...)@. + +Operators should be queried without any surrounding parentheses, like so: + +> lookupValueName "+" + +Qualified names are also supported, like so: + +> lookupValueName "Prelude.+" +> lookupValueName "Prelude.map" + +-} + + +{- | 'reify' looks up information about the 'Name'. It will fail with +a compile error if the 'Name' is not visible. A 'Name' is visible if it is +imported or defined in a prior top-level declaration group. See the +documentation for 'newDeclarationGroup' for more details. + +It is sometimes useful to construct the argument name using 'lookupTypeName' or 'lookupValueName' +to ensure that we are reifying from the right namespace. For instance, in this context: + +> data D = D + +which @D@ does @reify (mkName \"D\")@ return information about? (Answer: @D at -the-type, but don't rely on it.) +To ensure we get information about @D at -the-value, use 'lookupValueName': + +> do +> Just nm <- lookupValueName "D" +> reify nm + +and to get information about @D at -the-type, use 'lookupTypeName'. +-} +reify :: Name -> Q Info +reify v = Q (qReify v) + +{- | @reifyFixity nm@ attempts to find a fixity declaration for @nm at . For +example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then + at reifyFixity 'foo@ would return @'Just' ('Fixity' 7 'InfixR')@. If the function + at bar@ does not have a fixity declaration, then @reifyFixity 'bar@ returns +'Nothing', so you may assume @bar@ has 'defaultFixity'. +-} +reifyFixity :: Name -> Q (Maybe Fixity) +reifyFixity nm = Q (qReifyFixity nm) + +{- | @reifyType nm@ attempts to find the type or kind of @nm at . For example, + at reifyType 'not@ returns @Bool -> Bool@, and + at reifyType ''Bool@ returns @Type at . +This works even if there's no explicit signature and the type or kind is inferred. +-} +reifyType :: Name -> Q Type +reifyType nm = Q (qReifyType nm) + +{- | Template Haskell is capable of reifying information about types and +terms defined in previous declaration groups. Top-level declaration splices break up +declaration groups. + +For an example, consider this code block. We define a datatype @X@ and +then try to call 'reify' on the datatype. + +@ +module Check where + +data X = X + deriving Eq + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +This code fails to compile, noting that @X@ is not available for reification at the site of 'reify'. We can fix this by creating a new declaration group using an empty top-level splice: + +@ +data X = X + deriving Eq + +$(pure []) + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +We provide 'newDeclarationGroup' as a means of documenting this behavior +and providing a name for the pattern. + +Since top level splices infer the presence of the @$( ... )@ brackets, we can also write: + +@ +data X = X + deriving Eq + +newDeclarationGroup + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +-} +newDeclarationGroup :: Q [Dec] +newDeclarationGroup = pure [] + +{- | @reifyInstances nm tys@ returns a list of all visible instances (see below for "visible") +of @nm tys at . That is, +if @nm@ is the name of a type class, then all instances of this class at the types @tys@ +are returned. Alternatively, if @nm@ is the name of a data family or type family, +all instances of this family at the types @tys@ are returned. + +Note that this is a \"shallow\" test; the declarations returned merely have +instance heads which unify with @nm tys@, they need not actually be satisfiable. + + - @reifyInstances ''Eq [ 'TupleT' 2 \``AppT`\` 'ConT' ''A \``AppT`\` 'ConT' ''B ]@ contains + the @instance (Eq a, Eq b) => Eq (a, b)@ regardless of whether @A@ and + @B@ themselves implement 'Eq' + + - @reifyInstances ''Show [ 'VarT' ('mkName' "a") ]@ produces every available + instance of 'Show' + +There is one edge case: @reifyInstances ''Typeable tys@ currently always +produces an empty list (no matter what @tys@ are given). + +In principle, the *visible* instances are +* all instances defined in a prior top-level declaration group + (see docs on @newDeclarationGroup@), or +* all instances defined in any module transitively imported by the + module being compiled + +However, actually searching all modules transitively below the one being +compiled is unreasonably expensive, so @reifyInstances@ will report only the +instance for modules that GHC has had some cause to visit during this +compilation. This is a shortcoming: @reifyInstances@ might fail to report +instances for a type that is otherwise unusued, or instances defined in a +different component. You can work around this shortcoming by explicitly importing the modules +whose instances you want to be visible. GHC issue +has some discussion around this. + +-} +reifyInstances :: Name -> [Type] -> Q [InstanceDec] +reifyInstances cls tys = Q (qReifyInstances cls tys) + +{- | @reifyRoles nm@ returns the list of roles associated with the parameters +(both visible and invisible) of +the tycon @nm at . Fails if @nm@ cannot be found or is not a tycon. +The returned list should never contain 'InferR'. + +An invisible parameter to a tycon is often a kind parameter. For example, if +we have + +@ +type Proxy :: forall k. k -> Type +data Proxy a = MkProxy +@ + +and @reifyRoles Proxy@, we will get @['NominalR', 'PhantomR']@. The 'NominalR' is +the role of the invisible @k@ parameter. Kind parameters are always nominal. +-} +reifyRoles :: Name -> Q [Role] +reifyRoles nm = Q (qReifyRoles nm) + +-- | @reifyAnnotations target@ returns the list of annotations +-- associated with @target at . Only the annotations that are +-- appropriately typed is returned. So if you have @Int@ and @String@ +-- annotations for the same target, you have to call this function twice. +reifyAnnotations :: Data a => AnnLookup -> Q [a] +reifyAnnotations an = Q (qReifyAnnotations an) + +-- | @reifyModule mod@ looks up information about module @mod at . To +-- look up the current module, call this function with the return +-- value of 'Language.Haskell.TH.Lib.thisModule'. +reifyModule :: Module -> Q ModuleInfo +reifyModule m = Q (qReifyModule m) + +-- | @reifyConStrictness nm@ looks up the strictness information for the fields +-- of the constructor with the name @nm at . Note that the strictness information +-- that 'reifyConStrictness' returns may not correspond to what is written in +-- the source code. For example, in the following data declaration: +-- +-- @ +-- data Pair a = Pair a a +-- @ +-- +-- 'reifyConStrictness' would return @['DecidedLazy', DecidedLazy]@ under most +-- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the +-- @-XStrictData@ language extension was enabled. +reifyConStrictness :: Name -> Q [DecidedStrictness] +reifyConStrictness n = Q (qReifyConStrictness n) + +-- | Is the list of instances returned by 'reifyInstances' nonempty? +-- +-- If you're confused by an instance not being visible despite being +-- defined in the same module and above the splice in question, see the +-- docs for 'newDeclarationGroup' for a possible explanation. +isInstance :: Name -> [Type] -> Q Bool +isInstance nm tys = do { decs <- reifyInstances nm tys + ; return (not (null decs)) } + +-- | The location at which this computation is spliced. +location :: Q Loc +location = Q qLocation + +-- |The 'runIO' function lets you run an I\/O computation in the 'Q' monad. +-- Take care: you are guaranteed the ordering of calls to 'runIO' within +-- a single 'Q' computation, but not about the order in which splices are run. +-- +-- Note: for various murky reasons, stdout and stderr handles are not +-- necessarily flushed when the compiler finishes running, so you should +-- flush them yourself. +runIO :: IO a -> Q a +runIO m = Q (qRunIO m) + +-- | Get the package root for the current package which is being compiled. +-- This can be set explicitly with the -package-root flag but is normally +-- just the current working directory. +-- +-- The motivation for this flag is to provide a principled means to remove the +-- assumption from splices that they will be executed in the directory where the +-- cabal file resides. Projects such as haskell-language-server can't and don't +-- change directory when compiling files but instead set the -package-root flag +-- appropriately. +getPackageRoot :: Q FilePath +getPackageRoot = Q qGetPackageRoot + +-- | Record external files that runIO is using (dependent upon). +-- The compiler can then recognize that it should re-compile the Haskell file +-- when an external file changes. +-- +-- Expects an absolute file path. +-- +-- Notes: +-- +-- * ghc -M does not know about these dependencies - it does not execute TH. +-- +-- * The dependency is based on file content, not a modification time +addDependentFile :: FilePath -> Q () +addDependentFile fp = Q (qAddDependentFile fp) + +-- | Obtain a temporary file path with the given suffix. The compiler will +-- delete this file after compilation. +addTempFile :: String -> Q FilePath +addTempFile suffix = Q (qAddTempFile suffix) + +-- | Add additional top-level declarations. The added declarations will be type +-- checked along with the current declaration group. +addTopDecls :: [Dec] -> Q () +addTopDecls ds = Q (qAddTopDecls ds) + +-- | +addForeignFile :: ForeignSrcLang -> String -> Q () +addForeignFile = addForeignSource +{-# DEPRECATED addForeignFile + "Use 'Language.Haskell.TH.Syntax.addForeignSource' instead" + #-} -- deprecated in 8.6 + +-- | Emit a foreign file which will be compiled and linked to the object for +-- the current module. Currently only languages that can be compiled with +-- the C compiler are supported, and the flags passed as part of -optc will +-- be also applied to the C compiler invocation that will compile them. +-- +-- Note that for non-C languages (for example C++) @extern "C"@ directives +-- must be used to get symbols that we can access from Haskell. +-- +-- To get better errors, it is recommended to use #line pragmas when +-- emitting C files, e.g. +-- +-- > {-# LANGUAGE CPP #-} +-- > ... +-- > addForeignSource LangC $ unlines +-- > [ "#line " ++ show (__LINE__ + 1) ++ " " ++ show __FILE__ +-- > , ... +-- > ] +addForeignSource :: ForeignSrcLang -> String -> Q () +addForeignSource lang src = do + let suffix = case lang of + LangC -> "c" + LangCxx -> "cpp" + LangObjc -> "m" + LangObjcxx -> "mm" + LangAsm -> "s" + LangJs -> "js" + RawObject -> "a" + path <- addTempFile suffix + runIO $ writeFile path src + addForeignFilePath lang path + +-- | Same as 'addForeignSource', but expects to receive a path pointing to the +-- foreign file instead of a 'String' of its contents. Consider using this in +-- conjunction with 'addTempFile'. +-- +-- This is a good alternative to 'addForeignSource' when you are trying to +-- directly link in an object file. +addForeignFilePath :: ForeignSrcLang -> FilePath -> Q () +addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp) + +-- | Add a finalizer that will run in the Q monad after the current module has +-- been type checked. This only makes sense when run within a top-level splice. +-- +-- The finalizer is given the local type environment at the splice point. Thus +-- 'reify' is able to find the local definitions when executed inside the +-- finalizer. +addModFinalizer :: Q () -> Q () +addModFinalizer act = Q (qAddModFinalizer (unQ act)) + +-- | Adds a core plugin to the compilation pipeline. +-- +-- @addCorePlugin m@ has almost the same effect as passing @-fplugin=m@ to ghc +-- in the command line. The major difference is that the plugin module @m@ +-- must not belong to the current package. When TH executes, it is too late +-- to tell the compiler that we needed to compile first a plugin module in the +-- current package. +addCorePlugin :: String -> Q () +addCorePlugin plugin = Q (qAddCorePlugin plugin) + +-- | Get state from the 'Q' monad. Note that the state is local to the +-- Haskell module in which the Template Haskell expression is executed. +getQ :: Typeable a => Q (Maybe a) +getQ = Q qGetQ + +-- | Replace the state in the 'Q' monad. Note that the state is local to the +-- Haskell module in which the Template Haskell expression is executed. +putQ :: Typeable a => a -> Q () +putQ x = Q (qPutQ x) + +-- | Determine whether the given language extension is enabled in the 'Q' monad. +isExtEnabled :: Extension -> Q Bool +isExtEnabled ext = Q (qIsExtEnabled ext) + +-- | List all enabled language extensions. +extsEnabled :: Q [Extension] +extsEnabled = Q qExtsEnabled + +-- | Add Haddock documentation to the specified location. This will overwrite +-- any documentation at the location if it already exists. This will reify the +-- specified name, so it must be in scope when you call it. If you want to add +-- documentation to something that you are currently splicing, you can use +-- 'addModFinalizer' e.g. +-- +-- > do +-- > let nm = mkName "x" +-- > addModFinalizer $ putDoc (DeclDoc nm) "Hello" +-- > [d| $(varP nm) = 42 |] +-- +-- The helper functions 'withDecDoc' and 'withDecsDoc' will do this for you, as +-- will the 'funD_doc' and other @_doc@ combinators. +-- You most likely want to have the @-haddock@ flag turned on when using this. +-- Adding documentation to anything outside of the current module will cause an +-- error. +putDoc :: DocLoc -> String -> Q () +putDoc t s = Q (qPutDoc t s) + +-- | Retrieves the Haddock documentation at the specified location, if one +-- exists. +-- It can be used to read documentation on things defined outside of the current +-- module, provided that those modules were compiled with the @-haddock@ flag. +getDoc :: DocLoc -> Q (Maybe String) +getDoc n = Q (qGetDoc n) + +instance MonadIO Q where + liftIO = runIO + +instance Quasi Q where + qNewName = newName + qReport = report + qRecover = recover + qReify = reify + qReifyFixity = reifyFixity + qReifyType = reifyType + qReifyInstances = reifyInstances + qReifyRoles = reifyRoles + qReifyAnnotations = reifyAnnotations + qReifyModule = reifyModule + qReifyConStrictness = reifyConStrictness + qLookupName = lookupName + qLocation = location + qGetPackageRoot = getPackageRoot + qAddDependentFile = addDependentFile + qAddTempFile = addTempFile + qAddTopDecls = addTopDecls + qAddForeignFilePath = addForeignFilePath + qAddModFinalizer = addModFinalizer + qAddCorePlugin = addCorePlugin + qGetQ = getQ + qPutQ = putQ + qIsExtEnabled = isExtEnabled + qExtsEnabled = extsEnabled + qPutDoc = putDoc + qGetDoc = getDoc + + +---------------------------------------------------- +-- The following operations are used solely in GHC.HsToCore.Quote when +-- desugaring brackets. They are not necessary for the user, who can use +-- ordinary return and (>>=) etc + +sequenceQ :: forall m . Monad m => forall a . [m a] -> m [a] +sequenceQ = sequence + + +----------------------------------------------------- +-- +-- The Lift class +-- +----------------------------------------------------- + +-- | A 'Lift' instance can have any of its values turned into a Template +-- Haskell expression. This is needed when a value used within a Template +-- Haskell quotation is bound outside the Oxford brackets (@[| ... |]@ or +-- @[|| ... ||]@) but not at the top level. As an example: +-- +-- > add1 :: Int -> Code Q Int +-- > add1 x = [|| x + 1 ||] +-- +-- Template Haskell has no way of knowing what value @x@ will take on at +-- splice-time, so it requires the type of @x@ to be an instance of 'Lift'. +-- +-- A 'Lift' instance must satisfy @$(lift x) ≡ x@ and @$$(liftTyped x) ≡ x@ +-- for all @x@, where @$(...)@ and @$$(...)@ are Template Haskell splices. +-- It is additionally expected that @'lift' x ≡ 'unTypeCode' ('liftTyped' x)@. +-- +-- 'Lift' instances can be derived automatically by use of the @-XDeriveLift@ +-- GHC language extension: +-- +-- > {-# LANGUAGE DeriveLift #-} +-- > module Foo where +-- > +-- > import Language.Haskell.TH.Syntax +-- > +-- > data Bar a = Bar1 a (Bar a) | Bar2 String +-- > deriving Lift +-- +-- Representation-polymorphic since /template-haskell-2.16.0.0/. +class Lift (t :: TYPE r) where + -- | Turn a value into a Template Haskell expression, suitable for use in + -- a splice. + lift :: Quote m => t -> m Exp + default lift :: (r ~ ('BoxedRep 'Lifted), Quote m) => t -> m Exp + lift = unTypeCode . liftTyped + + -- | Turn a value into a Template Haskell typed expression, suitable for use + -- in a typed splice. + -- + -- @since 2.16.0.0 + liftTyped :: Quote m => t -> Code m t + +oneName, manyName :: Name +oneName = mkNameG DataName "ghc-prim" "GHC.Types" "One" +manyName = mkNameG DataName "ghc-prim" "GHC.Types" "Many" + +----------------------------------------------------- +-- +-- Generic Lift implementations +-- +----------------------------------------------------- + +-- | 'dataToQa' is an internal utility function for constructing generic +-- conversion functions from types with 'Data' instances to various +-- quasi-quoting representations. See the source of 'dataToExpQ' and +-- 'dataToPatQ' for two example usages: @mkCon@, @mkLit@ +-- and @appQ@ are overloadable to account for different syntax for +-- expressions and patterns; @antiQ@ allows you to override type-specific +-- cases, a common usage is just @const Nothing@, which results in +-- no overloading. +dataToQa :: forall m a k q. (Quote m, Data a) + => (Name -> k) + -> (Lit -> m q) + -> (k -> [m q] -> m q) + -> (forall b . Data b => b -> Maybe (m q)) + -> a + -> m q +dataToQa mkCon mkLit appCon antiQ t = + case antiQ t of + Nothing -> + case constrRep constr of + AlgConstr _ -> + appCon (mkCon funOrConName) conArgs + where + funOrConName :: Name + funOrConName = + case showConstr constr of + "(:)" -> Name (mkOccName ":") + (NameG DataName + (mkPkgName "ghc-prim") + (mkModName "GHC.Types")) + con@"[]" -> Name (mkOccName con) + (NameG DataName + (mkPkgName "ghc-prim") + (mkModName "GHC.Types")) + con@('(':_) -> Name (mkOccName con) + (NameG DataName + (mkPkgName "ghc-prim") + (mkModName "GHC.Tuple")) + + -- Tricky case: see Note [Data for non-algebraic types] + fun@(x:_) | startsVarSym x || startsVarId x + -> mkNameG_v tyconPkg tyconMod fun + con -> mkNameG_d tyconPkg tyconMod con + + where + tycon :: TyCon + tycon = (typeRepTyCon . typeOf) t + + tyconPkg, tyconMod :: String + tyconPkg = tyConPackage tycon + tyconMod = tyConModule tycon + + conArgs :: [m q] + conArgs = gmapQ (dataToQa mkCon mkLit appCon antiQ) t + IntConstr n -> + mkLit $ IntegerL n + FloatConstr n -> + mkLit $ RationalL n + CharConstr c -> + mkLit $ CharL c + where + constr :: Constr + constr = toConstr t + + Just y -> y + + +{- Note [Data for non-algebraic types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Class Data was originally intended for algebraic data types. But +it is possible to use it for abstract types too. For example, in +package `text` we find + + instance Data Text where + ... + toConstr _ = packConstr + + packConstr :: Constr + packConstr = mkConstr textDataType "pack" [] Prefix + +Here `packConstr` isn't a real data constructor, it's an ordinary +function. Two complications + +* In such a case, we must take care to build the Name using + mkNameG_v (for values), not mkNameG_d (for data constructors). + See #10796. + +* The pseudo-constructor is named only by its string, here "pack". + But 'dataToQa' needs the TyCon of its defining module, and has + to assume it's defined in the same module as the TyCon itself. + But nothing enforces that; #12596 shows what goes wrong if + "pack" is defined in a different module than the data type "Text". + -} + +-- | 'dataToExpQ' converts a value to a 'Exp' representation of the +-- same value, in the SYB style. It is generalized to take a function +-- override type-specific cases; see 'liftData' for a more commonly +-- used variant. +dataToExpQ :: (Quote m, Data a) + => (forall b . Data b => b -> Maybe (m Exp)) + -> a + -> m Exp +dataToExpQ = dataToQa varOrConE litE (foldl appE) + where + -- Make sure that VarE is used if the Constr value relies on a + -- function underneath the surface (instead of a constructor). + -- See #10796. + varOrConE s = + case nameSpace s of + Just VarName -> return (VarE s) + Just (FldName {}) -> return (VarE s) + Just DataName -> return (ConE s) + _ -> error $ "Can't construct an expression from name " + ++ showName s + appE x y = do { a <- x; b <- y; return (AppE a b)} + litE c = return (LitE c) + +-- | 'liftData' is a variant of 'lift' in the 'Lift' type class which +-- works for any type with a 'Data' instance. +liftData :: (Quote m, Data a) => a -> m Exp +liftData = dataToExpQ (const Nothing) + +-- | 'dataToPatQ' converts a value to a 'Pat' representation of the same +-- value, in the SYB style. It takes a function to handle type-specific cases, +-- alternatively, pass @const Nothing@ to get default behavior. +dataToPatQ :: (Quote m, Data a) + => (forall b . Data b => b -> Maybe (m Pat)) + -> a + -> m Pat +dataToPatQ = dataToQa id litP conP + where litP l = return (LitP l) + conP n ps = + case nameSpace n of + Just DataName -> do + ps' <- sequence ps + return (ConP n [] ps') + _ -> error $ "Can't construct a pattern from name " + ++ showName n + +----------------------------------------------------- +-- Names and uniques +----------------------------------------------------- + +newtype ModName = ModName String -- Module name + deriving (Show,Eq,Ord,Data,Generic) + +newtype PkgName = PkgName String -- package name + deriving (Show,Eq,Ord,Data,Generic) + +-- | Obtained from 'reifyModule' and 'Language.Haskell.TH.Lib.thisModule'. +data Module = Module PkgName ModName -- package qualified module name + deriving (Show,Eq,Ord,Data,Generic) + +newtype OccName = OccName String + deriving (Show,Eq,Ord,Data,Generic) + +mkModName :: String -> ModName +mkModName s = ModName s + +modString :: ModName -> String +modString (ModName m) = m + + +mkPkgName :: String -> PkgName +mkPkgName s = PkgName s + +pkgString :: PkgName -> String +pkgString (PkgName m) = m + + +----------------------------------------------------- +-- OccName +----------------------------------------------------- + +mkOccName :: String -> OccName +mkOccName s = OccName s + +occString :: OccName -> String +occString (OccName occ) = occ + + +----------------------------------------------------- +-- Names +----------------------------------------------------- +-- +-- For "global" names ('NameG') we need a totally unique name, +-- so we must include the name-space of the thing +-- +-- For unique-numbered things ('NameU'), we've got a unique reference +-- anyway, so no need for name space +-- +-- For dynamically bound thing ('NameS') we probably want them to +-- in a context-dependent way, so again we don't want the name +-- space. For example: +-- +-- > let v = mkName "T" in [| data $v = $v |] +-- +-- Here we use the same Name for both type constructor and data constructor +-- +-- +-- NameL and NameG are bound *outside* the TH syntax tree +-- either globally (NameG) or locally (NameL). Ex: +-- +-- > f x = $(h [| (map, x) |]) +-- +-- The 'map' will be a NameG, and 'x' wil be a NameL +-- +-- These Names should never appear in a binding position in a TH syntax tree + +{- $namecapture #namecapture# +Much of 'Name' API is concerned with the problem of /name capture/, which +can be seen in the following example. + +> f expr = [| let x = 0 in $expr |] +> ... +> g x = $( f [| x |] ) +> h y = $( f [| y |] ) + +A naive desugaring of this would yield: + +> g x = let x = 0 in x +> h y = let x = 0 in y + +All of a sudden, @g@ and @h@ have different meanings! In this case, +we say that the @x@ in the RHS of @g@ has been /captured/ +by the binding of @x@ in @f at . + +What we actually want is for the @x@ in @f@ to be distinct from the + at x@ in @g@, so we get the following desugaring: + +> g x = let x' = 0 in x +> h y = let x' = 0 in y + +which avoids name capture as desired. + +In the general case, we say that a @Name@ can be captured if +the thing it refers to can be changed by adding new declarations. +-} + +{- | +An abstract type representing names in the syntax tree. + +'Name's can be constructed in several ways, which come with different +name-capture guarantees (see "Language.Haskell.TH.Syntax#namecapture" for +an explanation of name capture): + + * the built-in syntax @'f@ and @''T@ can be used to construct names, + The expression @'f@ gives a @Name@ which refers to the value @f@ + currently in scope, and @''T@ gives a @Name@ which refers to the + type @T@ currently in scope. These names can never be captured. + + * 'lookupValueName' and 'lookupTypeName' are similar to @'f@ and + @''T@ respectively, but the @Name at s are looked up at the point + where the current splice is being run. These names can never be + captured. + + * 'newName' monadically generates a new name, which can never + be captured. + + * 'mkName' generates a capturable name. + +Names constructed using @newName@ and @mkName@ may be used in bindings +(such as @let x = ...@ or @\x -> ...@), but names constructed using + at lookupValueName@, @lookupTypeName@, @'f@, @''T@ may not. +-} +data Name = Name OccName NameFlavour deriving (Data, Eq, Generic) + +instance Ord Name where + -- check if unique is different before looking at strings + (Name o1 f1) `compare` (Name o2 f2) = (f1 `compare` f2) `thenCmp` + (o1 `compare` o2) + +data NameFlavour + = NameS -- ^ An unqualified name; dynamically bound + | NameQ ModName -- ^ A qualified name; dynamically bound + | NameU !Uniq -- ^ A unique local name + | NameL !Uniq -- ^ Local name bound outside of the TH AST + | NameG NameSpace PkgName ModName -- ^ Global name bound outside of the TH AST: + -- An original name (occurrences only, not binders) + -- Need the namespace too to be sure which + -- thing we are naming + deriving ( Data, Eq, Ord, Show, Generic ) + +data NameSpace = VarName -- ^ Variables + | DataName -- ^ Data constructors + | TcClsName -- ^ Type constructors and classes; Haskell has them + -- in the same name space for now. + | FldName + { fldParent :: !String + -- ^ The textual name of the parent of the field. + -- + -- - For a field of a datatype, this is the name of the first constructor + -- of the datatype (regardless of whether this constructor has this field). + -- - For a field of a pattern synonym, this is the name of the pattern synonym. + } + deriving( Eq, Ord, Show, Data, Generic ) + +-- | @Uniq@ is used by GHC to distinguish names from each other. +type Uniq = Integer + +-- | The name without its module prefix. +-- +-- ==== __Examples__ +-- +-- >>> nameBase ''Data.Either.Either +-- "Either" +-- >>> nameBase (mkName "foo") +-- "foo" +-- >>> nameBase (mkName "Module.foo") +-- "foo" +nameBase :: Name -> String +nameBase (Name occ _) = occString occ + +-- | Module prefix of a name, if it exists. +-- +-- ==== __Examples__ +-- +-- >>> nameModule ''Data.Either.Either +-- Just "Data.Either" +-- >>> nameModule (mkName "foo") +-- Nothing +-- >>> nameModule (mkName "Module.foo") +-- Just "Module" +nameModule :: Name -> Maybe String +nameModule (Name _ (NameQ m)) = Just (modString m) +nameModule (Name _ (NameG _ _ m)) = Just (modString m) +nameModule _ = Nothing + +-- | A name's package, if it exists. +-- +-- ==== __Examples__ +-- +-- >>> namePackage ''Data.Either.Either +-- Just "base" +-- >>> namePackage (mkName "foo") +-- Nothing +-- >>> namePackage (mkName "Module.foo") +-- Nothing +namePackage :: Name -> Maybe String +namePackage (Name _ (NameG _ p _)) = Just (pkgString p) +namePackage _ = Nothing + +-- | Returns whether a name represents an occurrence of a top-level variable +-- ('VarName'), data constructor ('DataName'), type constructor, or type class +-- ('TcClsName'). If we can't be sure, it returns 'Nothing'. +-- +-- ==== __Examples__ +-- +-- >>> nameSpace 'Prelude.id +-- Just VarName +-- >>> nameSpace (mkName "id") +-- Nothing -- only works for top-level variable names +-- >>> nameSpace 'Data.Maybe.Just +-- Just DataName +-- >>> nameSpace ''Data.Maybe.Maybe +-- Just TcClsName +-- >>> nameSpace ''Data.Ord.Ord +-- Just TcClsName +nameSpace :: Name -> Maybe NameSpace +nameSpace (Name _ (NameG ns _ _)) = Just ns +nameSpace _ = Nothing + +{- | +Generate a capturable name. Occurrences of such names will be +resolved according to the Haskell scoping rules at the occurrence +site. + +For example: + +> f = [| pi + $(varE (mkName "pi")) |] +> ... +> g = let pi = 3 in $f + +In this case, @g@ is desugared to + +> g = Prelude.pi + 3 + +Note that @mkName@ may be used with qualified names: + +> mkName "Prelude.pi" + +See also 'Language.Haskell.TH.Lib.dyn' for a useful combinator. The above example could +be rewritten using 'Language.Haskell.TH.Lib.dyn' as + +> f = [| pi + $(dyn "pi") |] +-} +mkName :: String -> Name +-- The string can have a '.', thus "Foo.baz", +-- giving a dynamically-bound qualified name, +-- in which case we want to generate a NameQ +-- +-- Parse the string to see if it has a "." in it +-- so we know whether to generate a qualified or unqualified name +-- It's a bit tricky because we need to parse +-- +-- > Foo.Baz.x as Qual Foo.Baz x +-- +-- So we parse it from back to front +mkName str + = split [] (reverse str) + where + split occ [] = Name (mkOccName occ) NameS + split occ ('.':rev) | not (null occ) + , is_rev_mod_name rev + = Name (mkOccName occ) (NameQ (mkModName (reverse rev))) + -- The 'not (null occ)' guard ensures that + -- mkName "&." = Name "&." NameS + -- The 'is_rev_mod' guards ensure that + -- mkName ".&" = Name ".&" NameS + -- mkName "^.." = Name "^.." NameS -- #8633 + -- mkName "Data.Bits..&" = Name ".&" (NameQ "Data.Bits") + -- This rather bizarre case actually happened; (.&.) is in Data.Bits + split occ (c:rev) = split (c:occ) rev + + -- Recognises a reversed module name xA.yB.C, + -- with at least one component, + -- and each component looks like a module name + -- (i.e. non-empty, starts with capital, all alpha) + is_rev_mod_name rev_mod_str + | (compt, rest) <- break (== '.') rev_mod_str + , not (null compt), isUpper (last compt), all is_mod_char compt + = case rest of + [] -> True + (_dot : rest') -> is_rev_mod_name rest' + | otherwise + = False + + is_mod_char c = isAlphaNum c || c == '_' || c == '\'' + +-- | Only used internally +mkNameU :: String -> Uniq -> Name +mkNameU s u = Name (mkOccName s) (NameU u) + +-- | Only used internally +mkNameL :: String -> Uniq -> Name +mkNameL s u = Name (mkOccName s) (NameL u) + +-- | Only used internally +mkNameQ :: String -> String -> Name +mkNameQ mn occ = Name (mkOccName occ) (NameQ (mkModName mn)) + +-- | Used for 'x etc, but not available to the programmer +mkNameG :: NameSpace -> String -> String -> String -> Name +mkNameG ns pkg modu occ + = Name (mkOccName occ) (NameG ns (mkPkgName pkg) (mkModName modu)) + +mkNameS :: String -> Name +mkNameS n = Name (mkOccName n) NameS + +mkNameG_v, mkNameG_tc, mkNameG_d :: String -> String -> String -> Name +mkNameG_v = mkNameG VarName +mkNameG_tc = mkNameG TcClsName +mkNameG_d = mkNameG DataName + +mkNameG_fld :: String -- ^ package + -> String -- ^ module + -> String -- ^ parent (first constructor of parent type) + -> String -- ^ field name + -> Name +mkNameG_fld pkg modu con occ = mkNameG (FldName con) pkg modu occ + +data NameIs = Alone | Applied | Infix + +showName :: Name -> String +showName = showName' Alone + +showName' :: NameIs -> Name -> String +showName' ni nm + = case ni of + Alone -> nms + Applied + | pnam -> nms + | otherwise -> "(" ++ nms ++ ")" + Infix + | pnam -> "`" ++ nms ++ "`" + | otherwise -> nms + where + -- For now, we make the NameQ and NameG print the same, even though + -- NameQ is a qualified name (so what it means depends on what the + -- current scope is), and NameG is an original name (so its meaning + -- should be independent of what's in scope. + -- We may well want to distinguish them in the end. + -- Ditto NameU and NameL + nms = case nm of + Name occ NameS -> occString occ + Name occ (NameQ m) -> modString m ++ "." ++ occString occ + Name occ (NameG _ _ m) -> modString m ++ "." ++ occString occ + Name occ (NameU u) -> occString occ ++ "_" ++ show u + Name occ (NameL u) -> occString occ ++ "_" ++ show u + + pnam = classify nms + + -- True if we are function style, e.g. f, [], (,) + -- False if we are operator style, e.g. +, :+ + classify "" = False -- shouldn't happen; . operator is handled below + classify (x:xs) | isAlpha x || (x `elem` "_[]()") = + case dropWhile (/='.') xs of + (_:xs') -> classify xs' + [] -> True + | otherwise = False + +instance Show Name where + show = showName + +-- Tuple data and type constructors +-- | Tuple data constructor +tupleDataName :: Int -> Name +-- | Tuple type constructor +tupleTypeName :: Int -> Name + +tupleDataName n = mk_tup_name n DataName True +tupleTypeName n = mk_tup_name n TcClsName True + +-- Unboxed tuple data and type constructors +-- | Unboxed tuple data constructor +unboxedTupleDataName :: Int -> Name +-- | Unboxed tuple type constructor +unboxedTupleTypeName :: Int -> Name + +unboxedTupleDataName n = mk_tup_name n DataName False +unboxedTupleTypeName n = mk_tup_name n TcClsName False + +mk_tup_name :: Int -> NameSpace -> Bool -> Name +mk_tup_name n space boxed + = Name (mkOccName tup_occ) (NameG space (mkPkgName "ghc-prim") tup_mod) + where + withParens thing + | boxed = "(" ++ thing ++ ")" + | otherwise = "(#" ++ thing ++ "#)" + tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" + | n == 1 = if boxed then solo else "Solo#" + | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" + | otherwise = withParens (replicate n_commas ',') + n_commas = n - 1 + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + solo + | space == DataName = "MkSolo" + | otherwise = "Solo" + +-- Unboxed sum data and type constructors +-- | Unboxed sum data constructor +unboxedSumDataName :: SumAlt -> SumArity -> Name +-- | Unboxed sum type constructor +unboxedSumTypeName :: SumArity -> Name + +unboxedSumDataName alt arity + | alt > arity + = error $ prefix ++ "Index out of bounds." ++ debug_info + + | alt <= 0 + = error $ prefix ++ "Alt must be > 0." ++ debug_info + + | arity < 2 + = error $ prefix ++ "Arity must be >= 2." ++ debug_info + + | otherwise + = Name (mkOccName sum_occ) + (NameG DataName (mkPkgName "ghc-prim") (mkModName "GHC.Prim")) + + where + prefix = "unboxedSumDataName: " + debug_info = " (alt: " ++ show alt ++ ", arity: " ++ show arity ++ ")" + + -- Synced with the definition of mkSumDataConOcc in GHC.Builtin.Types + sum_occ = '(' : '#' : bars nbars_before ++ '_' : bars nbars_after ++ "#)" + bars i = replicate i '|' + nbars_before = alt - 1 + nbars_after = arity - alt + +unboxedSumTypeName arity + | arity < 2 + = error $ "unboxedSumTypeName: Arity must be >= 2." + ++ " (arity: " ++ show arity ++ ")" + + | otherwise + = Name (mkOccName sum_occ) + (NameG TcClsName (mkPkgName "ghc-prim") (mkModName "GHC.Prim")) + + where + -- Synced with the definition of mkSumTyConOcc in GHC.Builtin.Types + sum_occ = '(' : '#' : replicate (arity - 1) '|' ++ "#)" + +----------------------------------------------------- +-- Locations +----------------------------------------------------- + +data Loc + = Loc { loc_filename :: String + , loc_package :: String + , loc_module :: String + , loc_start :: CharPos + , loc_end :: CharPos } + deriving( Show, Eq, Ord, Data, Generic ) + +type CharPos = (Int, Int) -- ^ Line and character position + + +----------------------------------------------------- +-- +-- The Info returned by reification +-- +----------------------------------------------------- + +-- | Obtained from 'reify' in the 'Q' Monad. +data Info + = + -- | A class, with a list of its visible instances + ClassI + Dec + [InstanceDec] + + -- | A class method + | ClassOpI + Name + Type + ParentName + + -- | A \"plain\" type constructor. \"Fancier\" type constructors are returned + -- using 'PrimTyConI' or 'FamilyI' as appropriate. At present, this reified + -- declaration will never have derived instances attached to it (if you wish + -- to check for an instance, see 'reifyInstances'). + | TyConI + Dec + + -- | A type or data family, with a list of its visible instances. A closed + -- type family is returned with 0 instances. + | FamilyI + Dec + [InstanceDec] + + -- | A \"primitive\" type constructor, which can't be expressed with a 'Dec'. + -- Examples: @(->)@, @Int#@. + | PrimTyConI + Name + Arity + Unlifted + + -- | A data constructor + | DataConI + Name + Type + ParentName + + -- | A pattern synonym + | PatSynI + Name + PatSynType + + {- | + A \"value\" variable (as opposed to a type variable, see 'TyVarI'). + + The @Maybe Dec@ field contains @Just@ the declaration which + defined the variable - including the RHS of the declaration - + or else @Nothing@, in the case where the RHS is unavailable to + the compiler. At present, this value is /always/ @Nothing@: + returning the RHS has not yet been implemented because of + lack of interest. + -} + | VarI + Name + Type + (Maybe Dec) + + {- | + A type variable. + + The @Type@ field contains the type which underlies the variable. + At present, this is always @'VarT' theName@, but future changes + may permit refinement of this. + -} + | TyVarI -- Scoped type variable + Name + Type -- What it is bound to + deriving( Show, Eq, Ord, Data, Generic ) + +-- | Obtained from 'reifyModule' in the 'Q' Monad. +data ModuleInfo = + -- | Contains the import list of the module. + ModuleInfo [Module] + deriving( Show, Eq, Ord, Data, Generic ) + +{- | +In 'ClassOpI' and 'DataConI', name of the parent class or type +-} +type ParentName = Name + +-- | In 'UnboxedSumE' and 'UnboxedSumP', the number associated with a +-- particular data constructor. 'SumAlt's are one-indexed and should never +-- exceed the value of its corresponding 'SumArity'. For example: +-- +-- * @(\#_|\#)@ has 'SumAlt' 1 (out of a total 'SumArity' of 2) +-- +-- * @(\#|_\#)@ has 'SumAlt' 2 (out of a total 'SumArity' of 2) +type SumAlt = Int + +-- | In 'UnboxedSumE', 'UnboxedSumT', and 'UnboxedSumP', the total number of +-- 'SumAlt's. For example, @(\#|\#)@ has a 'SumArity' of 2. +type SumArity = Int + +-- | In 'PrimTyConI', arity of the type constructor +type Arity = Int + +-- | In 'PrimTyConI', is the type constructor unlifted? +type Unlifted = Bool + +-- | 'InstanceDec' describes a single instance of a class or type function. +-- It is just a 'Dec', but guaranteed to be one of the following: +-- +-- * 'InstanceD' (with empty @['Dec']@) +-- +-- * 'DataInstD' or 'NewtypeInstD' (with empty derived @['Name']@) +-- +-- * 'TySynInstD' +type InstanceDec = Dec + +data Fixity = Fixity Int FixityDirection + deriving( Eq, Ord, Show, Data, Generic ) +data FixityDirection = InfixL | InfixR | InfixN + deriving( Eq, Ord, Show, Data, Generic ) + +-- | Highest allowed operator precedence for 'Fixity' constructor (answer: 9) +maxPrecedence :: Int +maxPrecedence = (9::Int) + +-- | Default fixity: @infixl 9@ +defaultFixity :: Fixity +defaultFixity = Fixity maxPrecedence InfixL + + +{- +Note [Unresolved infix] +~~~~~~~~~~~~~~~~~~~~~~~ +-} +{- $infix #infix# + +When implementing antiquotation for quasiquoters, one often wants +to parse strings into expressions: + +> parse :: String -> Maybe Exp + +But how should we parse @a + b * c@? If we don't know the fixities of + at +@ and @*@, we don't know whether to parse it as @a + (b * c)@ or @(a ++ b) * c at . + +In cases like this, use 'UInfixE', 'UInfixP', 'UInfixT', or 'PromotedUInfixT', +which stand for \"unresolved infix expression/pattern/type/promoted +constructor\", respectively. When the compiler is given a splice containing a +tree of @UInfixE@ applications such as + +> UInfixE +> (UInfixE e1 op1 e2) +> op2 +> (UInfixE e3 op3 e4) + +it will look up and the fixities of the relevant operators and +reassociate the tree as necessary. + + * trees will not be reassociated across 'ParensE', 'ParensP', or 'ParensT', + which are of use for parsing expressions like + + > (a + b * c) + d * e + + * 'InfixE', 'InfixP', 'InfixT', and 'PromotedInfixT' expressions are never + reassociated. + + * The 'UInfixE' constructor doesn't support sections. Sections + such as @(a *)@ have no ambiguity, so 'InfixE' suffices. For longer + sections such as @(a + b * c -)@, use an 'InfixE' constructor for the + outer-most section, and use 'UInfixE' constructors for all + other operators: + + > InfixE + > Just (UInfixE ...a + b * c...) + > op + > Nothing + + Sections such as @(a + b +)@ and @((a + b) +)@ should be rendered + into 'Exp's differently: + + > (+ a + b) ---> InfixE Nothing + (Just $ UInfixE a + b) + > -- will result in a fixity error if (+) is left-infix + > (+ (a + b)) ---> InfixE Nothing + (Just $ ParensE $ UInfixE a + b) + > -- no fixity errors + + * Quoted expressions such as + + > [| a * b + c |] :: Q Exp + > [p| a : b : c |] :: Q Pat + > [t| T + T |] :: Q Type + + will never contain 'UInfixE', 'UInfixP', 'UInfixT', 'PromotedUInfixT', + 'InfixT', 'PromotedInfixT, 'ParensE', 'ParensP', or 'ParensT' constructors. + +-} + +----------------------------------------------------- +-- +-- The main syntax data types +-- +----------------------------------------------------- + +data Lit = CharL Char + | StringL String + | IntegerL Integer -- ^ Used for overloaded and non-overloaded + -- literals. We don't have a good way to + -- represent non-overloaded literals at + -- the moment. Maybe that doesn't matter? + | RationalL Rational -- Ditto + | IntPrimL Integer + | WordPrimL Integer + | FloatPrimL Rational + | DoublePrimL Rational + | StringPrimL [Word8] -- ^ A primitive C-style string, type 'Addr#' + | BytesPrimL Bytes -- ^ Some raw bytes, type 'Addr#': + | CharPrimL Char + deriving( Show, Eq, Ord, Data, Generic ) + + -- We could add Int, Float, Double etc, as we do in HsLit, + -- but that could complicate the + -- supposedly-simple TH.Syntax literal type + +-- | Raw bytes embedded into the binary. +-- +-- Avoid using Bytes constructor directly as it is likely to change in the +-- future. Use helpers such as `mkBytes` in Language.Haskell.TH.Lib instead. +data Bytes = Bytes + { bytesPtr :: ForeignPtr Word8 -- ^ Pointer to the data + , bytesOffset :: Word -- ^ Offset from the pointer + , bytesSize :: Word -- ^ Number of bytes + + -- Maybe someday: + -- , bytesAlignement :: Word -- ^ Alignement constraint + -- , bytesReadOnly :: Bool -- ^ Shall we embed into a read-only + -- -- section or not + -- , bytesInitialized :: Bool -- ^ False: only use `bytesSize` to allocate + -- -- an uninitialized region + } + deriving (Data,Generic) + +-- We can't derive Show instance for Bytes because we don't want to show the +-- pointer value but the actual bytes (similarly to what ByteString does). See +-- #16457. +instance Show Bytes where + show b = unsafePerformIO $ withForeignPtr (bytesPtr b) $ \ptr -> + peekCStringLen ( ptr `plusPtr` fromIntegral (bytesOffset b) + , fromIntegral (bytesSize b) + ) + +-- We can't derive Eq and Ord instances for Bytes because we don't want to +-- compare pointer values but the actual bytes (similarly to what ByteString +-- does). See #16457 +instance Eq Bytes where + (==) = eqBytes + +instance Ord Bytes where + compare = compareBytes + +eqBytes :: Bytes -> Bytes -> Bool +eqBytes a@(Bytes fp off len) b@(Bytes fp' off' len') + | len /= len' = False -- short cut on length + | fp == fp' && off == off' = True -- short cut for the same bytes + | otherwise = compareBytes a b == EQ + +compareBytes :: Bytes -> Bytes -> Ordering +compareBytes (Bytes _ _ 0) (Bytes _ _ 0) = EQ -- short cut for empty Bytes +compareBytes (Bytes fp1 off1 len1) (Bytes fp2 off2 len2) = + unsafePerformIO $ + withForeignPtr fp1 $ \p1 -> + withForeignPtr fp2 $ \p2 -> do + i <- memcmp (p1 `plusPtr` fromIntegral off1) + (p2 `plusPtr` fromIntegral off2) + (fromIntegral (min len1 len2)) + return $! (i `compare` 0) <> (len1 `compare` len2) + +foreign import ccall unsafe "memcmp" + memcmp :: Ptr a -> Ptr b -> CSize -> IO CInt + + +-- | Pattern in Haskell given in @{}@ +data Pat + = LitP Lit -- ^ @{ 5 or \'c\' }@ + | VarP Name -- ^ @{ x }@ + | TupP [Pat] -- ^ @{ (p1,p2) }@ + | UnboxedTupP [Pat] -- ^ @{ (\# p1,p2 \#) }@ + | UnboxedSumP Pat SumAlt SumArity -- ^ @{ (\#|p|\#) }@ + | ConP Name [Type] [Pat] -- ^ @data T1 = C1 t1 t2; {C1 \@ty1 p1 p2} = e@ + | InfixP Pat Name Pat -- ^ @foo ({x :+ y}) = e@ + | UInfixP Pat Name Pat -- ^ @foo ({x :+ y}) = e@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | ParensP Pat -- ^ @{(p)}@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | TildeP Pat -- ^ @{ ~p }@ + | BangP Pat -- ^ @{ !p }@ + | AsP Name Pat -- ^ @{ x \@ p }@ + | WildP -- ^ @{ _ }@ + | RecP Name [FieldPat] -- ^ @f (Pt { pointx = x }) = g x@ + | ListP [ Pat ] -- ^ @{ [1,2,3] }@ + | SigP Pat Type -- ^ @{ p :: t }@ + | ViewP Exp Pat -- ^ @{ e -> p }@ + | TypeP Type -- ^ @{ type p }@ + | InvisP Type -- ^ @{ @p }@ + deriving( Show, Eq, Ord, Data, Generic ) + +type FieldPat = (Name,Pat) + +data Match = Match Pat Body [Dec] -- ^ @case e of { pat -> body where decs }@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Clause = Clause [Pat] Body [Dec] + -- ^ @f { p1 p2 = body where decs }@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Exp + = VarE Name -- ^ @{ x }@ + | ConE Name -- ^ @data T1 = C1 t1 t2; p = {C1} e1 e2 @ + | LitE Lit -- ^ @{ 5 or \'c\'}@ + | AppE Exp Exp -- ^ @{ f x }@ + | AppTypeE Exp Type -- ^ @{ f \@Int }@ + + | InfixE (Maybe Exp) Exp (Maybe Exp) -- ^ @{x + y} or {(x+)} or {(+ x)} or {(+)}@ + + -- It's a bit gruesome to use an Exp as the operator when a Name + -- would suffice. Historically, Exp was used to make it easier to + -- distinguish between infix constructors and non-constructors. + -- This is a bit overkill, since one could just as well call + -- `startsConId` or `startsConSym` (from `GHC.Lexeme`) on a Name. + -- Unfortunately, changing this design now would involve lots of + -- code churn for consumers of the TH API, so we continue to use + -- an Exp as the operator and perform an extra check during conversion + -- to ensure that the Exp is a constructor or a variable (#16895). + + | UInfixE Exp Exp Exp -- ^ @{x + y}@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | ParensE Exp -- ^ @{ (e) }@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | LamE [Pat] Exp -- ^ @{ \\ p1 p2 -> e }@ + | LamCaseE [Match] -- ^ @{ \\case m1; m2 }@ + | LamCasesE [Clause] -- ^ @{ \\cases m1; m2 }@ + | TupE [Maybe Exp] -- ^ @{ (e1,e2) } @ + -- + -- The 'Maybe' is necessary for handling + -- tuple sections. + -- + -- > (1,) + -- + -- translates to + -- + -- > TupE [Just (LitE (IntegerL 1)),Nothing] + + | UnboxedTupE [Maybe Exp] -- ^ @{ (\# e1,e2 \#) } @ + -- + -- The 'Maybe' is necessary for handling + -- tuple sections. + -- + -- > (# 'c', #) + -- + -- translates to + -- + -- > UnboxedTupE [Just (LitE (CharL 'c')),Nothing] + + | UnboxedSumE Exp SumAlt SumArity -- ^ @{ (\#|e|\#) }@ + | CondE Exp Exp Exp -- ^ @{ if e1 then e2 else e3 }@ + | MultiIfE [(Guard, Exp)] -- ^ @{ if | g1 -> e1 | g2 -> e2 }@ + | LetE [Dec] Exp -- ^ @{ let { x=e1; y=e2 } in e3 }@ + | CaseE Exp [Match] -- ^ @{ case e of m1; m2 }@ + | DoE (Maybe ModName) [Stmt] -- ^ @{ do { p <- e1; e2 } }@ or a qualified do if + -- the module name is present + | MDoE (Maybe ModName) [Stmt] -- ^ @{ mdo { x <- e1 y; y <- e2 x; } }@ or a qualified + -- mdo if the module name is present + | CompE [Stmt] -- ^ @{ [ (x,y) | x <- xs, y <- ys ] }@ + -- + -- The result expression of the comprehension is + -- the /last/ of the @'Stmt'@s, and should be a 'NoBindS'. + -- + -- E.g. translation: + -- + -- > [ f x | x <- xs ] + -- + -- > CompE [BindS (VarP x) (VarE xs), NoBindS (AppE (VarE f) (VarE x))] + + | ArithSeqE Range -- ^ @{ [ 1 ,2 .. 10 ] }@ + | ListE [ Exp ] -- ^ @{ [1,2,3] }@ + | SigE Exp Type -- ^ @{ e :: t }@ + | RecConE Name [FieldExp] -- ^ @{ T { x = y, z = w } }@ + | RecUpdE Exp [FieldExp] -- ^ @{ (f x) { z = w } }@ + | StaticE Exp -- ^ @{ static e }@ + | UnboundVarE Name -- ^ @{ _x }@ + -- + -- This is used for holes or unresolved + -- identifiers in AST quotes. Note that + -- it could either have a variable name + -- or constructor name. + | LabelE String -- ^ @{ #x }@ ( Overloaded label ) + | ImplicitParamVarE String -- ^ @{ ?x }@ ( Implicit parameter ) + | GetFieldE Exp String -- ^ @{ exp.field }@ ( Overloaded Record Dot ) + | ProjectionE (NonEmpty String) -- ^ @(.x)@ or @(.x.y)@ (Record projections) + | TypedBracketE Exp -- ^ @[|| e ||]@ + | TypedSpliceE Exp -- ^ @$$e@ + | TypeE Type -- ^ @{ type t }@ + deriving( Show, Eq, Ord, Data, Generic ) + +type FieldExp = (Name,Exp) + +-- Omitted: implicit parameters + +data Body + = GuardedB [(Guard,Exp)] -- ^ @f p { | e1 = e2 + -- | e3 = e4 } + -- where ds@ + | NormalB Exp -- ^ @f p { = e } where ds@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Guard + = NormalG Exp -- ^ @f x { | odd x } = x@ + | PatG [Stmt] -- ^ @f x { | Just y <- x, Just z <- y } = z@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Stmt + = BindS Pat Exp -- ^ @p <- e@ + | LetS [ Dec ] -- ^ @{ let { x=e1; y=e2 } }@ + | NoBindS Exp -- ^ @e@ + | ParS [[Stmt]] -- ^ @x <- e1 | s2, s3 | s4@ (in 'CompE') + | RecS [Stmt] -- ^ @rec { s1; s2 }@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Range = FromR Exp | FromThenR Exp Exp + | FromToR Exp Exp | FromThenToR Exp Exp Exp + deriving( Show, Eq, Ord, Data, Generic ) + +data Dec + = FunD Name [Clause] -- ^ @{ f p1 p2 = b where decs }@ + | ValD Pat Body [Dec] -- ^ @{ p = b where decs }@ + | DataD Cxt Name [TyVarBndr BndrVis] + (Maybe Kind) -- Kind signature (allowed only for GADTs) + [Con] [DerivClause] + -- ^ @{ data Cxt x => T x = A x | B (T x) + -- deriving (Z,W) + -- deriving stock Eq }@ + | NewtypeD Cxt Name [TyVarBndr BndrVis] + (Maybe Kind) -- Kind signature + Con [DerivClause] -- ^ @{ newtype Cxt x => T x = A (B x) + -- deriving (Z,W Q) + -- deriving stock Eq }@ + | TypeDataD Name [TyVarBndr BndrVis] + (Maybe Kind) -- Kind signature (allowed only for GADTs) + [Con] -- ^ @{ type data T x = A x | B (T x) }@ + | TySynD Name [TyVarBndr BndrVis] Type -- ^ @{ type T x = (x,x) }@ + | ClassD Cxt Name [TyVarBndr BndrVis] + [FunDep] [Dec] -- ^ @{ class Eq a => Ord a where ds }@ + | InstanceD (Maybe Overlap) Cxt Type [Dec] + -- ^ @{ instance {\-\# OVERLAPS \#-\} + -- Show w => Show [w] where ds }@ + | SigD Name Type -- ^ @{ length :: [a] -> Int }@ + | KiSigD Name Kind -- ^ @{ type TypeRep :: k -> Type }@ + | ForeignD Foreign -- ^ @{ foreign import ... } + --{ foreign export ... }@ + + | InfixD Fixity NamespaceSpecifier Name + -- ^ @{ infix 3 data foo }@ + | DefaultD [Type] -- ^ @{ default (Integer, Double) }@ + + -- | pragmas + | PragmaD Pragma -- ^ @{ {\-\# INLINE [1] foo \#-\} }@ + + -- | data families (may also appear in [Dec] of 'ClassD' and 'InstanceD') + | DataFamilyD Name [TyVarBndr BndrVis] + (Maybe Kind) + -- ^ @{ data family T a b c :: * }@ + + | DataInstD Cxt (Maybe [TyVarBndr ()]) Type + (Maybe Kind) -- Kind signature + [Con] [DerivClause] -- ^ @{ data instance Cxt x => T [x] + -- = A x | B (T x) + -- deriving (Z,W) + -- deriving stock Eq }@ + + | NewtypeInstD Cxt (Maybe [TyVarBndr ()]) Type -- Quantified type vars + (Maybe Kind) -- Kind signature + Con [DerivClause] -- ^ @{ newtype instance Cxt x => T [x] + -- = A (B x) + -- deriving (Z,W) + -- deriving stock Eq }@ + | TySynInstD TySynEqn -- ^ @{ type instance ... }@ + + -- | open type families (may also appear in [Dec] of 'ClassD' and 'InstanceD') + | OpenTypeFamilyD TypeFamilyHead + -- ^ @{ type family T a b c = (r :: *) | r -> a b }@ + + | ClosedTypeFamilyD TypeFamilyHead [TySynEqn] + -- ^ @{ type family F a b = (r :: *) | r -> a where ... }@ + + | RoleAnnotD Name [Role] -- ^ @{ type role T nominal representational }@ + | StandaloneDerivD (Maybe DerivStrategy) Cxt Type + -- ^ @{ deriving stock instance Ord a => Ord (Foo a) }@ + | DefaultSigD Name Type -- ^ @{ default size :: Data a => a -> Int }@ + + -- | Pattern Synonyms + | PatSynD Name PatSynArgs PatSynDir Pat + -- ^ @{ pattern P v1 v2 .. vn <- p }@ unidirectional or + -- @{ pattern P v1 v2 .. vn = p }@ implicit bidirectional or + -- @{ pattern P v1 v2 .. vn <- p + -- where P v1 v2 .. vn = e }@ explicit bidirectional + -- + -- also, besides prefix pattern synonyms, both infix and record + -- pattern synonyms are supported. See 'PatSynArgs' for details + + | PatSynSigD Name PatSynType -- ^ A pattern synonym's type signature. + + | ImplicitParamBindD String Exp + -- ^ @{ ?x = expr }@ + -- + -- Implicit parameter binding declaration. Can only be used in let + -- and where clauses which consist entirely of implicit bindings. + deriving( Show, Eq, Ord, Data, Generic ) + +-- | A way to specify a namespace to look in when GHC needs to find +-- a name's source +data NamespaceSpecifier + = NoNamespaceSpecifier -- ^ Name may be everything; If there are two + -- names in different namespaces, then consider both + | TypeNamespaceSpecifier -- ^ Name should be a type-level entity, such as a + -- data type, type alias, type family, type class, + -- or type variable + | DataNamespaceSpecifier -- ^ Name should be a term-level entity, such as a + -- function, data constructor, or pattern synonym + deriving( Show, Eq, Ord, Data, Generic ) + +-- | Varieties of allowed instance overlap. +data Overlap = Overlappable -- ^ May be overlapped by more specific instances + | Overlapping -- ^ May overlap a more general instance + | Overlaps -- ^ Both 'Overlapping' and 'Overlappable' + | Incoherent -- ^ Both 'Overlapping' and 'Overlappable', and + -- pick an arbitrary one if multiple choices are + -- available. + deriving( Show, Eq, Ord, Data, Generic ) + +-- | A single @deriving@ clause at the end of a datatype. +data DerivClause = DerivClause (Maybe DerivStrategy) Cxt + -- ^ @{ deriving stock (Eq, Ord) }@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | What the user explicitly requests when deriving an instance. +data DerivStrategy = StockStrategy -- ^ A \"standard\" derived instance + | AnyclassStrategy -- ^ @-XDeriveAnyClass@ + | NewtypeStrategy -- ^ @-XGeneralizedNewtypeDeriving@ + | ViaStrategy Type -- ^ @-XDerivingVia@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | A pattern synonym's type. Note that a pattern synonym's /fully/ +-- specified type has a peculiar shape coming with two forall +-- quantifiers and two constraint contexts. For example, consider the +-- pattern synonym +-- +-- > pattern P x1 x2 ... xn = +-- +-- P's complete type is of the following form +-- +-- > pattern P :: forall universals. required constraints +-- > => forall existentials. provided constraints +-- > => t1 -> t2 -> ... -> tn -> t +-- +-- consisting of four parts: +-- +-- 1. the (possibly empty lists of) universally quantified type +-- variables and required constraints on them. +-- 2. the (possibly empty lists of) existentially quantified +-- type variables and the provided constraints on them. +-- 3. the types @t1@, @t2@, .., @tn@ of @x1@, @x2@, .., @xn@, respectively +-- 4. the type @t@ of @\@, mentioning only universals. +-- +-- Pattern synonym types interact with TH when (a) reifying a pattern +-- synonym, (b) pretty printing, or (c) specifying a pattern synonym's +-- type signature explicitly: +-- +-- * Reification always returns a pattern synonym's /fully/ specified +-- type in abstract syntax. +-- +-- * Pretty printing via 'Language.Haskell.TH.Ppr.pprPatSynType' abbreviates +-- a pattern synonym's type unambiguously in concrete syntax: The rule of +-- thumb is to print initial empty universals and the required +-- context as @() =>@, if existentials and a provided context +-- follow. If only universals and their required context, but no +-- existentials are specified, only the universals and their +-- required context are printed. If both or none are specified, so +-- both (or none) are printed. +-- +-- * When specifying a pattern synonym's type explicitly with +-- 'PatSynSigD' either one of the universals, the existentials, or +-- their contexts may be left empty. +-- +-- See the GHC user's guide for more information on pattern synonyms +-- and their types: +-- . +type PatSynType = Type + +-- | Common elements of 'OpenTypeFamilyD' and 'ClosedTypeFamilyD'. By +-- analogy with "head" for type classes and type class instances as +-- defined in /Type classes: an exploration of the design space/, the +-- @TypeFamilyHead@ is defined to be the elements of the declaration +-- between @type family@ and @where at . +data TypeFamilyHead = + TypeFamilyHead Name [TyVarBndr BndrVis] FamilyResultSig (Maybe InjectivityAnn) + deriving( Show, Eq, Ord, Data, Generic ) + +-- | One equation of a type family instance or closed type family. The +-- arguments are the left-hand-side type and the right-hand-side result. +-- +-- For instance, if you had the following type family: +-- +-- @ +-- type family Foo (a :: k) :: k where +-- forall k (a :: k). Foo \@k a = a +-- @ +-- +-- The @Foo \@k a = a@ equation would be represented as follows: +-- +-- @ +-- 'TySynEqn' ('Just' ['PlainTV' k, 'KindedTV' a ('VarT' k)]) +-- ('AppT' ('AppKindT' ('ConT' ''Foo) ('VarT' k)) ('VarT' a)) +-- ('VarT' a) +-- @ +data TySynEqn = TySynEqn (Maybe [TyVarBndr ()]) Type Type + deriving( Show, Eq, Ord, Data, Generic ) + +data FunDep = FunDep [Name] [Name] + deriving( Show, Eq, Ord, Data, Generic ) + +data Foreign = ImportF Callconv Safety String Name Type + | ExportF Callconv String Name Type + deriving( Show, Eq, Ord, Data, Generic ) + +-- keep Callconv in sync with module ForeignCall in ghc/compiler/GHC/Types/ForeignCall.hs +data Callconv = CCall | StdCall | CApi | Prim | JavaScript + deriving( Show, Eq, Ord, Data, Generic ) + +data Safety = Unsafe | Safe | Interruptible + deriving( Show, Eq, Ord, Data, Generic ) + +data Pragma = InlineP Name Inline RuleMatch Phases + | OpaqueP Name + | SpecialiseP Name Type (Maybe Inline) Phases + | SpecialiseInstP Type + | RuleP String (Maybe [TyVarBndr ()]) [RuleBndr] Exp Exp Phases + | AnnP AnnTarget Exp + | LineP Int String + | CompleteP [Name] (Maybe Name) + -- ^ @{ {\-\# COMPLETE C_1, ..., C_i [ :: T ] \#-} }@ + | SCCP Name (Maybe String) + -- ^ @{ {\-\# SCC fun "optional_name" \#-} }@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Inline = NoInline + | Inline + | Inlinable + deriving (Show, Eq, Ord, Data, Generic) + +data RuleMatch = ConLike + | FunLike + deriving (Show, Eq, Ord, Data, Generic) + +data Phases = AllPhases + | FromPhase Int + | BeforePhase Int + deriving (Show, Eq, Ord, Data, Generic) + +data RuleBndr = RuleVar Name + | TypedRuleVar Name Type + deriving (Show, Eq, Ord, Data, Generic) + +data AnnTarget = ModuleAnnotation + | TypeAnnotation Name + | ValueAnnotation Name + deriving (Show, Eq, Ord, Data, Generic) + +type Cxt = [Pred] -- ^ @(Eq a, Ord b)@ + +-- | Since the advent of @ConstraintKinds@, constraints are really just types. +-- Equality constraints use the 'EqualityT' constructor. Constraints may also +-- be tuples of other constraints. +type Pred = Type + +-- | 'SourceUnpackedness' corresponds to unpack annotations found in the source code. +-- +-- This may not agree with the annotations returned by 'reifyConStrictness'. +-- See 'reifyConStrictness' for more information. +data SourceUnpackedness + = NoSourceUnpackedness -- ^ @C a@ + | SourceNoUnpack -- ^ @C { {\-\# NOUNPACK \#-\} } a@ + | SourceUnpack -- ^ @C { {\-\# UNPACK \#-\} } a@ + deriving (Show, Eq, Ord, Data, Generic) + +-- | 'SourceStrictness' corresponds to strictness annotations found in the source code. +-- +-- This may not agree with the annotations returned by 'reifyConStrictness'. +-- See 'reifyConStrictness' for more information. +data SourceStrictness = NoSourceStrictness -- ^ @C a@ + | SourceLazy -- ^ @C {~}a@ + | SourceStrict -- ^ @C {!}a@ + deriving (Show, Eq, Ord, Data, Generic) + +-- | Unlike 'SourceStrictness' and 'SourceUnpackedness', 'DecidedStrictness' +-- refers to the strictness annotations that the compiler chooses for a data constructor +-- field, which may be different from what is written in source code. +-- +-- Note that non-unpacked strict fields are assigned 'DecidedLazy' when a bang would be inappropriate, +-- such as the field of a newtype constructor and fields that have an unlifted type. +-- +-- See 'reifyConStrictness' for more information. +data DecidedStrictness = DecidedLazy -- ^ Field inferred to not have a bang. + | DecidedStrict -- ^ Field inferred to have a bang. + | DecidedUnpack -- ^ Field inferred to be unpacked. + deriving (Show, Eq, Ord, Data, Generic) + +-- | A data constructor. +-- +-- The constructors for 'Con' can roughly be divided up into two categories: +-- those for constructors with \"vanilla\" syntax ('NormalC', 'RecC', and +-- 'InfixC'), and those for constructors with GADT syntax ('GadtC' and +-- 'RecGadtC'). The 'ForallC' constructor, which quantifies additional type +-- variables and class contexts, can surround either variety of constructor. +-- However, the type variables that it quantifies are different depending +-- on what constructor syntax is used: +-- +-- * If a 'ForallC' surrounds a constructor with vanilla syntax, then the +-- 'ForallC' will only quantify /existential/ type variables. For example: +-- +-- @ +-- data Foo a = forall b. MkFoo a b +-- @ +-- +-- In @MkFoo@, 'ForallC' will quantify @b@, but not @a at . +-- +-- * If a 'ForallC' surrounds a constructor with GADT syntax, then the +-- 'ForallC' will quantify /all/ type variables used in the constructor. +-- For example: +-- +-- @ +-- data Bar a b where +-- MkBar :: (a ~ b) => c -> MkBar a b +-- @ +-- +-- In @MkBar@, 'ForallC' will quantify @a@, @b@, and @c at . +-- +-- Multiplicity annotations for data types are currently not supported +-- in Template Haskell (i.e. all fields represented by Template Haskell +-- will be linear). +data Con = + -- | @C Int a@ + NormalC Name [BangType] + + -- | @C { v :: Int, w :: a }@ + | RecC Name [VarBangType] + + -- | @Int :+ a@ + | InfixC BangType Name BangType + + -- | @forall a. Eq a => C [a]@ + | ForallC [TyVarBndr Specificity] Cxt Con + + -- @C :: a -> b -> T b Int@ + | GadtC [Name] + -- ^ The list of constructors, corresponding to the GADT constructor + -- syntax @C1, C2 :: a -> T b at . + -- + -- Invariant: the list must be non-empty. + [BangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] + + -- | @C :: { v :: Int } -> T b Int@ + | RecGadtC [Name] + -- ^ The list of constructors, corresponding to the GADT record + -- constructor syntax @C1, C2 :: { fld :: a } -> T b at . + -- + -- Invariant: the list must be non-empty. + [VarBangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] + deriving (Show, Eq, Ord, Data, Generic) + +-- Note [GADT return type] +-- ~~~~~~~~~~~~~~~~~~~~~~~ +-- The return type of a GADT constructor does not necessarily match the name of +-- the data type: +-- +-- type S = T +-- +-- data T a where +-- MkT :: S Int +-- +-- +-- type S a = T +-- +-- data T a where +-- MkT :: S Char Int +-- +-- +-- type Id a = a +-- type S a = T +-- +-- data T a where +-- MkT :: Id (S Char Int) +-- +-- +-- That is why we allow the return type stored by a constructor to be an +-- arbitrary type. See also #11341 + +data Bang = Bang SourceUnpackedness SourceStrictness + -- ^ @C { {\-\# UNPACK \#-\} !}a@ + deriving (Show, Eq, Ord, Data, Generic) + +type BangType = (Bang, Type) +type VarBangType = (Name, Bang, Type) + +-- | As of @template-haskell-2.11.0.0@, 'Strict' has been replaced by 'Bang'. +type Strict = Bang + +-- | As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by +-- 'BangType'. +type StrictType = BangType + +-- | As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by +-- 'VarBangType'. +type VarStrictType = VarBangType + +-- | A pattern synonym's directionality. +data PatSynDir + = Unidir -- ^ @pattern P x {<-} p@ + | ImplBidir -- ^ @pattern P x {=} p@ + | ExplBidir [Clause] -- ^ @pattern P x {<-} p where P x = e@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | A pattern synonym's argument type. +data PatSynArgs + = PrefixPatSyn [Name] -- ^ @pattern P {x y z} = p@ + | InfixPatSyn Name Name -- ^ @pattern {x P y} = p@ + | RecordPatSyn [Name] -- ^ @pattern P { {x,y,z} } = p@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Type = ForallT [TyVarBndr Specificity] Cxt Type -- ^ @forall \. \ => \@ + | ForallVisT [TyVarBndr ()] Type -- ^ @forall \ -> \@ + | AppT Type Type -- ^ @T a b@ + | AppKindT Type Kind -- ^ @T \@k t@ + | SigT Type Kind -- ^ @t :: k@ + | VarT Name -- ^ @a@ + | ConT Name -- ^ @T@ + | PromotedT Name -- ^ @'T@ + | InfixT Type Name Type -- ^ @T + T@ + | UInfixT Type Name Type -- ^ @T + T@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | PromotedInfixT Type Name Type -- ^ @T :+: T@ + | PromotedUInfixT Type Name Type -- ^ @T :+: T@ + -- + -- See "Language.Haskell.TH.Syntax#infix" + | ParensT Type -- ^ @(T)@ + + -- See Note [Representing concrete syntax in types] + | TupleT Int -- ^ @(,)@, @(,,)@, etc. + | UnboxedTupleT Int -- ^ @(\#,\#)@, @(\#,,\#)@, etc. + | UnboxedSumT SumArity -- ^ @(\#|\#)@, @(\#||\#)@, etc. + | ArrowT -- ^ @->@ + | MulArrowT -- ^ @%n ->@ + -- + -- Generalised arrow type with multiplicity argument + | EqualityT -- ^ @~@ + | ListT -- ^ @[]@ + | PromotedTupleT Int -- ^ @'()@, @'(,)@, @'(,,)@, etc. + | PromotedNilT -- ^ @'[]@ + | PromotedConsT -- ^ @'(:)@ + | StarT -- ^ @*@ + | ConstraintT -- ^ @Constraint@ + | LitT TyLit -- ^ @0@, @1@, @2@, etc. + | WildCardT -- ^ @_@ + | ImplicitParamT String Type -- ^ @?x :: t@ + deriving( Show, Eq, Ord, Data, Generic ) + +data Specificity = SpecifiedSpec -- ^ @a@ + | InferredSpec -- ^ @{a}@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | The @flag@ type parameter is instantiated to one of the following types: +-- +-- * 'Specificity' (examples: 'ForallC', 'ForallT') +-- * 'BndrVis' (examples: 'DataD', 'ClassD', etc.) +-- * '()', a catch-all type for other forms of binders, including 'ForallVisT', 'DataInstD', 'RuleP', and 'TyVarSig' +-- +data TyVarBndr flag = PlainTV Name flag -- ^ @a@ + | KindedTV Name flag Kind -- ^ @(a :: k)@ + deriving( Show, Eq, Ord, Data, Generic, Functor, Foldable, Traversable ) + +data BndrVis = BndrReq -- ^ @a@ + | BndrInvis -- ^ @\@a@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | Type family result signature +data FamilyResultSig = NoSig -- ^ no signature + | KindSig Kind -- ^ @k@ + | TyVarSig (TyVarBndr ()) -- ^ @= r, = (r :: k)@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | Injectivity annotation +data InjectivityAnn = InjectivityAnn Name [Name] + deriving ( Show, Eq, Ord, Data, Generic ) + +data TyLit = NumTyLit Integer -- ^ @2@ + | StrTyLit String -- ^ @\"Hello\"@ + | CharTyLit Char -- ^ @\'C\'@, @since 4.16.0.0 + deriving ( Show, Eq, Ord, Data, Generic ) + +-- | Role annotations +data Role = NominalR -- ^ @nominal@ + | RepresentationalR -- ^ @representational@ + | PhantomR -- ^ @phantom@ + | InferR -- ^ @_@ + deriving( Show, Eq, Ord, Data, Generic ) + +-- | Annotation target for reifyAnnotations +data AnnLookup = AnnLookupModule Module + | AnnLookupName Name + deriving( Show, Eq, Ord, Data, Generic ) + +-- | To avoid duplication between kinds and types, they +-- are defined to be the same. Naturally, you would never +-- have a type be 'StarT' and you would never have a kind +-- be 'SigT', but many of the other constructors are shared. +-- Note that the kind @Bool@ is denoted with 'ConT', not +-- 'PromotedT'. Similarly, tuple kinds are made with 'TupleT', +-- not 'PromotedTupleT'. + +type Kind = Type + +{- Note [Representing concrete syntax in types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Haskell has a rich concrete syntax for types, including + t1 -> t2, (t1,t2), [t], and so on +In TH we represent all of this using AppT, with a distinguished +type constructor at the head. So, + Type TH representation + ----------------------------------------------- + t1 -> t2 ArrowT `AppT` t2 `AppT` t2 + [t] ListT `AppT` t + (t1,t2) TupleT 2 `AppT` t1 `AppT` t2 + '(t1,t2) PromotedTupleT 2 `AppT` t1 `AppT` t2 + +But if the original HsSyn used prefix application, we won't use +these special TH constructors. For example + [] t ConT "[]" `AppT` t + (->) t ConT "->" `AppT` t +In this way we can faithfully represent in TH whether the original +HsType used concrete syntax or not. + +The one case that doesn't fit this pattern is that of promoted lists + '[ Maybe, IO ] PromotedListT 2 `AppT` t1 `AppT` t2 +but it's very smelly because there really is no type constructor +corresponding to PromotedListT. So we encode HsExplicitListTy with +PromotedConsT and PromotedNilT (which *do* have underlying type +constructors): + '[ Maybe, IO ] PromotedConsT `AppT` Maybe `AppT` + (PromotedConsT `AppT` IO `AppT` PromotedNilT) +-} + +-- | A location at which to attach Haddock documentation. +-- Note that adding documentation to a 'Name' defined oustide of the current +-- module will cause an error. +data DocLoc + = ModuleDoc -- ^ At the current module's header. + | DeclDoc Name -- ^ At a declaration, not necessarily top level. + | ArgDoc Name Int -- ^ At a specific argument of a function, indexed by its + -- position. + | InstDoc Type -- ^ At a class or family instance. + deriving ( Show, Eq, Ord, Data, Generic ) + +----------------------------------------------------- +-- Internal helper functions +----------------------------------------------------- + +cmpEq :: Ordering -> Bool +cmpEq EQ = True +cmpEq _ = False + +thenCmp :: Ordering -> Ordering -> Ordering +thenCmp EQ o2 = o2 +thenCmp o1 _ = o1 + +get_cons_names :: Con -> [Name] +get_cons_names (NormalC n _) = [n] +get_cons_names (RecC n _) = [n] +get_cons_names (InfixC _ n _) = [n] +get_cons_names (ForallC _ _ con) = get_cons_names con +-- GadtC can have multiple names, e.g +-- > data Bar a where +-- > MkBar1, MkBar2 :: a -> Bar a +-- Will have one GadtC with [MkBar1, MkBar2] as names +get_cons_names (GadtC ns _ _) = ns +get_cons_names (RecGadtC ns _ _) = ns View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b992f34551d25f74aa76b047d6800183382a30c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b992f34551d25f74aa76b047d6800183382a30c7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 18:47:32 2024 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 22 Apr 2024 14:47:32 -0400 Subject: [Git][ghc/ghc][wip/clyring/seqHash-DmdTransformer] Why is seq# absent in its own defining module??? Message-ID: <6626b0c4a39eb_e9ec71d4940449080@gitlab.mail> Matthew Craven pushed to branch wip/clyring/seqHash-DmdTransformer at Glasgow Haskell Compiler / GHC Commits: be5dfb89 by Matthew Craven at 2024-04-22T14:46:45-04:00 Why is seq# absent in its own defining module??? - - - - - 1 changed file: - compiler/GHC/Core/Opt/DmdAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -1025,7 +1025,10 @@ dmdTransform env var sd = -- pprTrace "dmdTransform:DictSel" (ppr var $$ ppr (idDmdSig var) $$ ppr sd) $ dmdTransformDictSelSig (idDmdSig var) sd | var `hasKey` seqHashKey - = dmdTransformSeqHash sd + = if isGlobalId var + then dmdTransformSeqHash sd + else -- stupid hack to make sure seq# isn't found absent in its own module + addVarDmd (dmdTransformSeqHash sd) var topDmd -- Imported functions | isGlobalId var , let res = dmdTransformSig (idDmdSig var) sd View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be5dfb893fa82043bc56443cbc457ea886719e42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be5dfb893fa82043bc56443cbc457ea886719e42 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 22 21:26:13 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Mon, 22 Apr 2024 17:26:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/T24707-epa-casealt-comments Message-ID: <6626d5f5b3625_e9ec73146a74548de@gitlab.mail> Alan Zimmerman pushed new branch wip/az/T24707-epa-casealt-comments at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/T24707-epa-casealt-comments You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 08:29:04 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 04:29:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: fix link in CODEOWNERS Message-ID: <66277150ab347_38ab92f6d22c869c0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - ff891016 by Fendor at 2024-04-23T04:28:48-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 2a955884 by Fendor at 2024-04-23T04:28:48-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 3ebc5057 by Alan Zimmerman at 2024-04-23T04:28:49-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - 10 changed files: - CODEOWNERS - compiler/GHC/Driver/Main.hs - compiler/GHC/Parser.y - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore - + testsuite/tests/printer/CaseAltComments.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T Changes: ===================================== CODEOWNERS ===================================== @@ -1,5 +1,5 @@ # Confused about what this is? See -# https://gitlab.haskell.org/help/user/project/code_owners +# https://docs.gitlab.com/ee/user/project/codeowners/ # Catch-all * @bgamari ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== compiler/GHC/Parser.y ===================================== @@ -3342,7 +3342,7 @@ alts1(PATS) :: { forall b. DisambECP b => PV (Located ([AddEpAnn],[LMatch GhcPs alt(PATS) :: { forall b. DisambECP b => PV (LMatch GhcPs (LocatedA b)) } : PATS alt_rhs { $2 >>= \ $2 -> - acsA (sLLAsl $1 $> ()) (\loc cs -> L (locA loc) + amsA' (sLLAsl $1 $> (Match { m_ext = [] , m_ctxt = CaseAlt -- for \case and \cases, this will be changed during post-processing , m_pats = $1 ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done ===================================== testsuite/tests/printer/CaseAltComments.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PatternGuards #-} +module CaseAltComments where + +nfCom = case expr of + x :*: y -- comment + | x' <= y' -> x' :*: y' + _ -> blah ===================================== testsuite/tests/printer/Makefile ===================================== @@ -826,3 +826,8 @@ Test24533: PprLetIn: $(CHECK_PPR) $(LIBDIR) PprLetIn.hs $(CHECK_EXACT) $(LIBDIR) PprLetIn.hs + +.PHONY: CaseAltComments +CaseAltComments: + $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs + $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -198,3 +198,4 @@ test('ListTuplePuns', extra_files(['ListTuplePuns.hs']), ghci_script, ['ListTupl test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, ['AnnotationNoListTuplePuns']) test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) +test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d521ff2bf235705abdf08bca9fc68498c1ca730...3ebc50577413429b7f6facade9a5885d932bacfa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d521ff2bf235705abdf08bca9fc68498c1ca730...3ebc50577413429b7f6facade9a5885d932bacfa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 08:41:44 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 23 Apr 2024 04:41:44 -0400 Subject: [Git][ghc/ghc][wip/fendor/iface-sharing] 10 commits: Refactor the Binary serialisation interface Message-ID: <6627744821f18_38ab9211ac0749064f@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/iface-sharing at Glasgow Haskell Compiler / GHC Commits: eee8f0d6 by Fendor at 2024-04-22T12:13:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - eda3aa6e by Fendor at 2024-04-22T12:14:44+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 1b2f0ff0 by Fendor at 2024-04-22T14:27:42+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - dd01fcb4 by Fendor at 2024-04-22T14:27:47+02:00 Break cyclic module dependency - - - - - 7e5a678d by Fendor at 2024-04-22T14:28:57+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - a98ae613 by Matthew Pickering at 2024-04-22T14:29:02+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 45e812de by Matthew Pickering at 2024-04-22T14:29:02+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - f6d5a5c2 by Fendor at 2024-04-22T14:29:02+02:00 Implement TrieMap for IfaceType - - - - - 0a4288eb by Fendor at 2024-04-23T09:50:48+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 7c969743 by Fendor at 2024-04-23T10:41:30+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85a7dab9570e417e5760af3ff3c049461ddc96f5...7c969743c9d7fe5827300c970c3245d8f6fcbded -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85a7dab9570e417e5760af3ff3c049461ddc96f5...7c969743c9d7fe5827300c970c3245d8f6fcbded You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 08:43:39 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 23 Apr 2024 04:43:39 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 11 commits: Refactor the Binary serialisation interface Message-ID: <662774bba37d5_38ab92121441c90872@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: eee8f0d6 by Fendor at 2024-04-22T12:13:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - eda3aa6e by Fendor at 2024-04-22T12:14:44+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 1b2f0ff0 by Fendor at 2024-04-22T14:27:42+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - dd01fcb4 by Fendor at 2024-04-22T14:27:47+02:00 Break cyclic module dependency - - - - - 7e5a678d by Fendor at 2024-04-22T14:28:57+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - a98ae613 by Matthew Pickering at 2024-04-22T14:29:02+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 45e812de by Matthew Pickering at 2024-04-22T14:29:02+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - f6d5a5c2 by Fendor at 2024-04-22T14:29:02+02:00 Implement TrieMap for IfaceType - - - - - 0a4288eb by Fendor at 2024-04-23T09:50:48+02:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 7c969743 by Fendor at 2024-04-23T10:41:30+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 0d24bd29 by Fendor at 2024-04-23T10:43:31+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/384a1c567d8d1c26118eb7060a5f2ff96e47c952...0d24bd294fa7822a7f2c047b8adeb3c5d1e0c99e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/384a1c567d8d1c26118eb7060a5f2ff96e47c952...0d24bd294fa7822a7f2c047b8adeb3c5d1e0c99e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 11:29:18 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 07:29:18 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <66279b8e6ce23_df3401fdd80496ed@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c10aa9c2 by Fendor at 2024-04-23T07:29:08-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 3ef14446 by Fendor at 2024-04-23T07:29:08-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 7648fd9c by Alan Zimmerman at 2024-04-23T07:29:09-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - 9 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Parser.y - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore - + testsuite/tests/printer/CaseAltComments.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== compiler/GHC/Parser.y ===================================== @@ -3342,7 +3342,7 @@ alts1(PATS) :: { forall b. DisambECP b => PV (Located ([AddEpAnn],[LMatch GhcPs alt(PATS) :: { forall b. DisambECP b => PV (LMatch GhcPs (LocatedA b)) } : PATS alt_rhs { $2 >>= \ $2 -> - acsA (sLLAsl $1 $> ()) (\loc cs -> L (locA loc) + amsA' (sLLAsl $1 $> (Match { m_ext = [] , m_ctxt = CaseAlt -- for \case and \cases, this will be changed during post-processing , m_pats = $1 ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done ===================================== testsuite/tests/printer/CaseAltComments.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PatternGuards #-} +module CaseAltComments where + +nfCom = case expr of + x :*: y -- comment + | x' <= y' -> x' :*: y' + _ -> blah ===================================== testsuite/tests/printer/Makefile ===================================== @@ -826,3 +826,8 @@ Test24533: PprLetIn: $(CHECK_PPR) $(LIBDIR) PprLetIn.hs $(CHECK_EXACT) $(LIBDIR) PprLetIn.hs + +.PHONY: CaseAltComments +CaseAltComments: + $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs + $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -198,3 +198,4 @@ test('ListTuplePuns', extra_files(['ListTuplePuns.hs']), ghci_script, ['ListTupl test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, ['AnnotationNoListTuplePuns']) test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) +test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ebc50577413429b7f6facade9a5885d932bacfa...7648fd9cd93b0f686452f0b5e3c7900447893ec5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ebc50577413429b7f6facade9a5885d932bacfa...7648fd9cd93b0f686452f0b5e3c7900447893ec5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 11:55:57 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 23 Apr 2024 07:55:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/testsuite-error Message-ID: <6627a1cd890ab_df3405b786856539@gitlab.mail> Zubin pushed new branch wip/testsuite-error at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/testsuite-error You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 11:57:19 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 23 Apr 2024 07:57:19 -0400 Subject: [Git][ghc/ghc][wip/testsuite-error] testsuite: Handle exceptions in framework_fail when testdir is not initialised Message-ID: <6627a21f6d93e_df340680b64583f5@gitlab.mail> Zubin pushed to branch wip/testsuite-error at Glasgow Haskell Compiler / GHC Commits: 35560664 by Zubin Duggal at 2024-04-23T17:27:12+05:30 testsuite: Handle exceptions in framework_fail when testdir is not initialised When `framework_fail` is called before initialising testdir, it would fail with an exception reporting the testdir not being initialised instead of the actual failure. Ensure we report the actual reason for the failure instead of failing in this way. One way this can manifest is when trying to run a test that doesn't exist using `--only` - - - - - 1 changed file: - testsuite/driver/testlib.py Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -1542,7 +1542,13 @@ def override_options(pre_cmd): def framework_fail(name: Optional[TestName], way: Optional[WayName], reason: str) -> None: opts = getTestOpts() - directory = re.sub(r'^\.[/\\]', '', str(opts.testdir)) + # framework_fail can be called before testdir is initialised, + # so we need to take care not to blow up with the wrong way + # and report the actual reason for the failure. + try: + directory = re.sub(r'^\.[/\\]', '', str(opts.testdir)) + except: + directory = '' full_name = '%s(%s)' % (name, way) if_verbose(1, '*** framework failure for %s %s ' % (full_name, reason)) name2 = name if name is not None else TestName('none') View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/355606641f44557342d6d66af9089dad2af72a5d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/355606641f44557342d6d66af9089dad2af72a5d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 12:08:37 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 23 Apr 2024 08:08:37 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/corefile-recomp Message-ID: <6627a4c52c0d6_df3408518946117f@gitlab.mail> Zubin pushed new branch wip/corefile-recomp at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/corefile-recomp You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 12:36:12 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 23 Apr 2024 08:36:12 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] Reuse the 'ReadBinMem' after sharing to avoid recomputations Message-ID: <6627ab3c63b28_df340c8b4a06458b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: d073db1e by Fendor at 2024-04-23T13:56:51+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 7 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -166,14 +167,18 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start pure mod_iface { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData } @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -158,7 +158,7 @@ shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } @@ -318,40 +318,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -20,7 +20,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,6 +33,7 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, @@ -48,6 +49,7 @@ module GHC.Utils.Binary putAt, getAt, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -102,6 +104,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -126,7 +132,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -156,7 +162,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -196,6 +201,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -289,9 +351,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr ()) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -382,12 +465,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1108,6 +1197,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1136,7 +1230,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1148,6 +1242,45 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + let relBin = toRelBin pre_a a + putAt bh pre_a (makeRelativeBin relBin) + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1157,19 +1290,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAt bh pre_a (makeRelativeBin $ toRelBin pre_a q) -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1178,7 +1311,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1472,13 +1605,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d073db1e92b5d41d1b7e07dcc57d467976ceac08 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d073db1e92b5d41d1b7e07dcc57d467976ceac08 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 14:19:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 10:19:45 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <6627c38185e76_df3401b7855810157f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - 5 changed files: - compiler/GHC/Driver/Main.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e1cf8dc2c941d36dc92139faa07ee6baf2599e38...1ba39b05e31ccc361440ebd73bbf99fabb1b6ce5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e1cf8dc2c941d36dc92139faa07ee6baf2599e38...1ba39b05e31ccc361440ebd73bbf99fabb1b6ce5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 14:20:41 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 10:20:41 -0400 Subject: [Git][ghc/ghc][master] EPA: Keep comments in a CaseAlt match Message-ID: <6627c3b9129db_df3401a4c88c106260@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - 4 changed files: - compiler/GHC/Parser.y - + testsuite/tests/printer/CaseAltComments.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -3342,7 +3342,7 @@ alts1(PATS) :: { forall b. DisambECP b => PV (Located ([AddEpAnn],[LMatch GhcPs alt(PATS) :: { forall b. DisambECP b => PV (LMatch GhcPs (LocatedA b)) } : PATS alt_rhs { $2 >>= \ $2 -> - acsA (sLLAsl $1 $> ()) (\loc cs -> L (locA loc) + amsA' (sLLAsl $1 $> (Match { m_ext = [] , m_ctxt = CaseAlt -- for \case and \cases, this will be changed during post-processing , m_pats = $1 ===================================== testsuite/tests/printer/CaseAltComments.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PatternGuards #-} +module CaseAltComments where + +nfCom = case expr of + x :*: y -- comment + | x' <= y' -> x' :*: y' + _ -> blah ===================================== testsuite/tests/printer/Makefile ===================================== @@ -826,3 +826,8 @@ Test24533: PprLetIn: $(CHECK_PPR) $(LIBDIR) PprLetIn.hs $(CHECK_EXACT) $(LIBDIR) PprLetIn.hs + +.PHONY: CaseAltComments +CaseAltComments: + $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs + $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -198,3 +198,4 @@ test('ListTuplePuns', extra_files(['ListTuplePuns.hs']), ghci_script, ['ListTupl test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, ['AnnotationNoListTuplePuns']) test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) +test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e916fc9215e66b15c7e2387cc087a9d1cc57bf77 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e916fc9215e66b15c7e2387cc087a9d1cc57bf77 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 14:51:26 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 10:51:26 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <6627caee7f878_df34021ffd901255e0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - f4894722 by Cheng Shao at 2024-04-23T10:51:07-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - c6b0e030 by Julian Ospald at 2024-04-23T10:51:12-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - d1b92a39 by Matthew Pickering at 2024-04-23T10:51:13-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - 12 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Parser.y - configure.ac - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore - + testsuite/tests/printer/CaseAltComments.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -1040,13 +1040,22 @@ this is accomplished with the `ld -r` command. We rely on this for two ends: The command used for object linking is set using the -pgmlm and -optlm command-line options. -Sadly, the LLD linker that we use on Windows does not support the `-r` flag -needed to support object merging (see #21068). For this reason on Windows we do -not support GHCi objects. To deal with foreign stubs we build a static archive -of all of a module's object files instead merging them. Consequently, we can -end up producing `.o` files which are in fact static archives. However, -toolchains generally don't have a problem with this as they use file headers, -not the filename, to determine the nature of inputs. +However, `ld -r` is broken in some cases: + + * The LLD linker that we use on Windows does not support the `-r` + flag needed to support object merging (see #21068). For this reason + on Windows we do not support GHCi objects. + * `wasm-ld -r` is prohibitively slow, especially when handling large + input objects (e.g. profiled objects). + +In these cases, we bundle a module's own object file with its foreign +stub's object file, instead of merging them. Consequently, we can end +up producing `.o` files which are in fact static archives. This can +only work if `ar -L` is supported, so the archive `.o` files can be +properly added to the final static library. We must also take care not +to produce archive `.dyn_o` when building dynamic objects, otherwise +we end up with broken `.so` files when GHC is built with `llvm-ar` +(#22210). Note that this has somewhat non-obvious consequences when producing initializers and finalizers. See Note [Initializers and finalizers in Cmm] @@ -1072,7 +1081,7 @@ via gcc. -- | See Note [Object merging]. joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO () joinObjectFiles hsc_env o_files output_fn - | can_merge_objs && not dashLSupported = do + | can_merge_objs && (not dashLSupported || is_dyn) = do let toolSettings' = toolSettings dflags ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings' ld_r args = GHC.SysTools.runMergeObjects (hsc_logger hsc_env) (hsc_tmpfs hsc_env) (hsc_dflags hsc_env) ( @@ -1100,6 +1109,7 @@ joinObjectFiles hsc_env o_files output_fn withAtomicRename output_fn $ \tmp_ar -> liftIO $ runAr logger dflags Nothing $ map Option $ ["qc" ++ dashL, tmp_ar] ++ o_files where + is_dyn = ways dflags `hasWay` WayDyn dashLSupported = sArSupportsDashL (settings dflags) dashL = if dashLSupported then "L" else "" can_merge_objs = isJust (pgm_lm (hsc_dflags hsc_env)) ===================================== compiler/GHC/Parser.y ===================================== @@ -3342,7 +3342,7 @@ alts1(PATS) :: { forall b. DisambECP b => PV (Located ([AddEpAnn],[LMatch GhcPs alt(PATS) :: { forall b. DisambECP b => PV (LMatch GhcPs (LocatedA b)) } : PATS alt_rhs { $2 >>= \ $2 -> - acsA (sLLAsl $1 $> ()) (\loc cs -> L (locA loc) + amsA' (sLLAsl $1 $> (Match { m_ext = [] , m_ctxt = CaseAlt -- for \case and \cases, this will be changed during post-processing , m_pats = $1 ===================================== configure.ac ===================================== @@ -97,11 +97,11 @@ dnl use either is considered a Feature. dnl ** What command to use to compile compiler sources ? dnl -------------------------------------------------------------- -AC_ARG_VAR(GHC,[Use as the full path to GHC. [default=autodetect]]) -AC_PATH_PROG([GHC], [ghc]) +AC_ARG_VAR(GHC,[Use as the bootstrap GHC. [default=autodetect]]) +AC_CHECK_PROG([GHC], [ghc], [ghc]) AC_ARG_WITH([ghc], - AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the full path to ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), - AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' or 'GHC=$withval ./configure' instead)])) + AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the bootstrap ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), + AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' instead)])) AC_SUBST(WithGhc,$GHC) AC_ARG_ENABLE(bootstrap-with-devel-snapshot, ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -31,6 +31,7 @@ import qualified Distribution.PackageDescription.Parsec as C import qualified Distribution.Simple.Compiler as C import qualified Distribution.Simple.Program.Db as C import qualified Distribution.Simple as C +import qualified Distribution.Simple.GHC as GHC import qualified Distribution.Simple.Program.Builtin as C import qualified Distribution.Simple.Utils as C import qualified Distribution.Simple.Program.Types as C @@ -363,12 +364,11 @@ registerPackage rs context = do need [setupConfig] -- This triggers 'configurePackage' pd <- packageDescription <$> readContextData context db_path <- packageDbPath (PackageDbLoc (stage context) (iplace context)) - dist_dir <- Context.buildPath context pid <- pkgUnitId (stage context) (package context) -- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path -- from the local build info @lbi at . lbi <- liftIO $ C.getPersistBuildConfig cPath - liftIO $ register db_path pid dist_dir pd lbi + liftIO $ register db_path pid pd lbi -- Then after the register, which just writes the .conf file, do the recache step. buildWithResources rs $ target context (GhcPkg Recache (stage context)) [] [] @@ -377,25 +377,23 @@ registerPackage rs context = do -- into a different package database to the one it was configured against. register :: FilePath -> String -- ^ Package Identifier - -> FilePath -> C.PackageDescription -> LocalBuildInfo -> IO () -register pkg_db pid build_dir pd lbi +register pkg_db pid pd lbi = withLibLBI pd lbi $ \lib clbi -> do - absPackageDBs <- C.absolutePackageDBPaths packageDbs - installedPkgInfo <- C.generateRegistrationInfo - C.silent pd lib lbi clbi False reloc build_dir - (C.registrationPackageDB absPackageDBs) - + when reloc $ error "register does not support reloc" + installedPkgInfo <- generateRegistrationInfo pd lbi lib clbi writeRegistrationFile installedPkgInfo where regFile = pkg_db pid <.> "conf" reloc = relocatable lbi - -- Using a specific package db here is why we have to copy the function from Cabal. - packageDbs = [C.SpecificPackageDB pkg_db] + + generateRegistrationInfo pkg lbi lib clbi = do + abi_hash <- C.mkAbiHash <$> GHC.libAbiHash C.silent pkg lbi lib clbi + return (C.absoluteInstalledPackageInfo pkg abi_hash lib lbi clbi) writeRegistrationFile installedPkgInfo = do writeUTF8File regFile (CP.showInstalledPackageInfo installedPkgInfo) ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done ===================================== testsuite/tests/printer/CaseAltComments.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PatternGuards #-} +module CaseAltComments where + +nfCom = case expr of + x :*: y -- comment + | x' <= y' -> x' :*: y' + _ -> blah ===================================== testsuite/tests/printer/Makefile ===================================== @@ -826,3 +826,8 @@ Test24533: PprLetIn: $(CHECK_PPR) $(LIBDIR) PprLetIn.hs $(CHECK_EXACT) $(LIBDIR) PprLetIn.hs + +.PHONY: CaseAltComments +CaseAltComments: + $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs + $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -198,3 +198,4 @@ test('ListTuplePuns', extra_files(['ListTuplePuns.hs']), ghci_script, ['ListTupl test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, ['AnnotationNoListTuplePuns']) test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) +test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7648fd9cd93b0f686452f0b5e3c7900447893ec5...d1b92a396fd4201d34d0d7dbe74c3d5dd86ff1fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7648fd9cd93b0f686452f0b5e3c7900447893ec5...d1b92a396fd4201d34d0d7dbe74c3d5dd86ff1fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 19:01:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 15:01:52 -0400 Subject: [Git][ghc/ghc][master] driver: force merge objects when building dynamic objects Message-ID: <662805a07bf98_37cdb58fc99c8413@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 1 changed file: - compiler/GHC/Driver/Pipeline/Execute.hs Changes: ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -1040,13 +1040,22 @@ this is accomplished with the `ld -r` command. We rely on this for two ends: The command used for object linking is set using the -pgmlm and -optlm command-line options. -Sadly, the LLD linker that we use on Windows does not support the `-r` flag -needed to support object merging (see #21068). For this reason on Windows we do -not support GHCi objects. To deal with foreign stubs we build a static archive -of all of a module's object files instead merging them. Consequently, we can -end up producing `.o` files which are in fact static archives. However, -toolchains generally don't have a problem with this as they use file headers, -not the filename, to determine the nature of inputs. +However, `ld -r` is broken in some cases: + + * The LLD linker that we use on Windows does not support the `-r` + flag needed to support object merging (see #21068). For this reason + on Windows we do not support GHCi objects. + * `wasm-ld -r` is prohibitively slow, especially when handling large + input objects (e.g. profiled objects). + +In these cases, we bundle a module's own object file with its foreign +stub's object file, instead of merging them. Consequently, we can end +up producing `.o` files which are in fact static archives. This can +only work if `ar -L` is supported, so the archive `.o` files can be +properly added to the final static library. We must also take care not +to produce archive `.dyn_o` when building dynamic objects, otherwise +we end up with broken `.so` files when GHC is built with `llvm-ar` +(#22210). Note that this has somewhat non-obvious consequences when producing initializers and finalizers. See Note [Initializers and finalizers in Cmm] @@ -1072,7 +1081,7 @@ via gcc. -- | See Note [Object merging]. joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO () joinObjectFiles hsc_env o_files output_fn - | can_merge_objs && not dashLSupported = do + | can_merge_objs && (not dashLSupported || is_dyn) = do let toolSettings' = toolSettings dflags ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings' ld_r args = GHC.SysTools.runMergeObjects (hsc_logger hsc_env) (hsc_tmpfs hsc_env) (hsc_dflags hsc_env) ( @@ -1100,6 +1109,7 @@ joinObjectFiles hsc_env o_files output_fn withAtomicRename output_fn $ \tmp_ar -> liftIO $ runAr logger dflags Nothing $ map Option $ ["qc" ++ dashL, tmp_ar] ++ o_files where + is_dyn = ways dflags `hasWay` WayDyn dashLSupported = sArSupportsDashL (settings dflags) dashL = if dashLSupported then "L" else "" can_merge_objs = isJust (pgm_lm (hsc_dflags hsc_env)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2b17f3258b4d9db1de89c872f1b7cee0a3f9b74 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2b17f3258b4d9db1de89c872f1b7cee0a3f9b74 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 19:02:37 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 15:02:37 -0400 Subject: [Git][ghc/ghc][master] Allow non-absolute values for bootstrap GHC variable Message-ID: <662805cd13324_37cdb5aa9b641388d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 1 changed file: - configure.ac Changes: ===================================== configure.ac ===================================== @@ -97,11 +97,11 @@ dnl use either is considered a Feature. dnl ** What command to use to compile compiler sources ? dnl -------------------------------------------------------------- -AC_ARG_VAR(GHC,[Use as the full path to GHC. [default=autodetect]]) -AC_PATH_PROG([GHC], [ghc]) +AC_ARG_VAR(GHC,[Use as the bootstrap GHC. [default=autodetect]]) +AC_CHECK_PROG([GHC], [ghc], [ghc]) AC_ARG_WITH([ghc], - AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the full path to ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), - AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' or 'GHC=$withval ./configure' instead)])) + AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the bootstrap ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), + AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' instead)])) AC_SUBST(WithGhc,$GHC) AC_ARG_ENABLE(bootstrap-with-devel-snapshot, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/209d09f52363b261b900cf042934ae1e81e2caa7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/209d09f52363b261b900cf042934ae1e81e2caa7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 19:03:15 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 23 Apr 2024 15:03:15 -0400 Subject: [Git][ghc/ghc][master] Don't depend on registerPackage function in Cabal Message-ID: <662805f38ef6_37cdb5c9c59816853@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - 1 changed file: - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs Changes: ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -31,6 +31,7 @@ import qualified Distribution.PackageDescription.Parsec as C import qualified Distribution.Simple.Compiler as C import qualified Distribution.Simple.Program.Db as C import qualified Distribution.Simple as C +import qualified Distribution.Simple.GHC as GHC import qualified Distribution.Simple.Program.Builtin as C import qualified Distribution.Simple.Utils as C import qualified Distribution.Simple.Program.Types as C @@ -363,12 +364,11 @@ registerPackage rs context = do need [setupConfig] -- This triggers 'configurePackage' pd <- packageDescription <$> readContextData context db_path <- packageDbPath (PackageDbLoc (stage context) (iplace context)) - dist_dir <- Context.buildPath context pid <- pkgUnitId (stage context) (package context) -- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path -- from the local build info @lbi at . lbi <- liftIO $ C.getPersistBuildConfig cPath - liftIO $ register db_path pid dist_dir pd lbi + liftIO $ register db_path pid pd lbi -- Then after the register, which just writes the .conf file, do the recache step. buildWithResources rs $ target context (GhcPkg Recache (stage context)) [] [] @@ -377,25 +377,23 @@ registerPackage rs context = do -- into a different package database to the one it was configured against. register :: FilePath -> String -- ^ Package Identifier - -> FilePath -> C.PackageDescription -> LocalBuildInfo -> IO () -register pkg_db pid build_dir pd lbi +register pkg_db pid pd lbi = withLibLBI pd lbi $ \lib clbi -> do - absPackageDBs <- C.absolutePackageDBPaths packageDbs - installedPkgInfo <- C.generateRegistrationInfo - C.silent pd lib lbi clbi False reloc build_dir - (C.registrationPackageDB absPackageDBs) - + when reloc $ error "register does not support reloc" + installedPkgInfo <- generateRegistrationInfo pd lbi lib clbi writeRegistrationFile installedPkgInfo where regFile = pkg_db pid <.> "conf" reloc = relocatable lbi - -- Using a specific package db here is why we have to copy the function from Cabal. - packageDbs = [C.SpecificPackageDB pkg_db] + + generateRegistrationInfo pkg lbi lib clbi = do + abi_hash <- C.mkAbiHash <$> GHC.libAbiHash C.silent pkg lbi lib clbi + return (C.absoluteInstalledPackageInfo pkg abi_hash lib lbi clbi) writeRegistrationFile installedPkgInfo = do writeUTF8File regFile (CP.showInstalledPackageInfo installedPkgInfo) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3fff09779d5830549ae455a15907b7bb9fe7859a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3fff09779d5830549ae455a15907b7bb9fe7859a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 20:30:55 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 23 Apr 2024 16:30:55 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/T24708-epa-match-pats-comments Message-ID: <66281a7f25f3f_37cdb5177cdf0232fe@gitlab.mail> Alan Zimmerman pushed new branch wip/az/T24708-epa-match-pats-comments at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/T24708-epa-match-pats-comments You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 23 22:22:41 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 23 Apr 2024 18:22:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/T24670-epa-compare-source Message-ID: <662834b1bc833_37cdb5244e0b0281a5@gitlab.mail> Alan Zimmerman pushed new branch wip/az/T24670-epa-compare-source at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/T24670-epa-compare-source You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 07:49:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 24 Apr 2024 03:49:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 8 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <6628b97631d6d_1ab6906a63141497e@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - d636f6a2 by Fendor at 2024-04-24T09:47:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - be6836a2 by Fendor at 2024-04-24T09:47:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 27 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - configure.ac - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - testsuite/tests/perf/compiler/Makefile - + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/compiler/genMultiLayerModulesCore - + testsuite/tests/printer/CaseAltComments.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T - utils/haddock Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -990,16 +990,16 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = LM types_var <- newIORef (md_types details) let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)]) let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv } - core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi - -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do - -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone - -- reports a bug. - let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] -- The bytecode generation itself is lazy because otherwise even when doing -- recompilation checking the bytecode will be generated (which slows things down a lot) -- the laziness is OK because generateByteCode just depends on things already loaded -- in the interface file. LoadedBCOs <$> (unsafeInterleaveIO $ do + core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi + -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do + -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone + -- reports a bug. + let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing [] trace_if (hsc_logger hsc_env) (text "Generating ByteCode for" <+> (ppr this_mod)) generateByteCode hsc_env cgi_guts (wcb_mod_location fi)) go ul = return ul ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -1040,13 +1040,22 @@ this is accomplished with the `ld -r` command. We rely on this for two ends: The command used for object linking is set using the -pgmlm and -optlm command-line options. -Sadly, the LLD linker that we use on Windows does not support the `-r` flag -needed to support object merging (see #21068). For this reason on Windows we do -not support GHCi objects. To deal with foreign stubs we build a static archive -of all of a module's object files instead merging them. Consequently, we can -end up producing `.o` files which are in fact static archives. However, -toolchains generally don't have a problem with this as they use file headers, -not the filename, to determine the nature of inputs. +However, `ld -r` is broken in some cases: + + * The LLD linker that we use on Windows does not support the `-r` + flag needed to support object merging (see #21068). For this reason + on Windows we do not support GHCi objects. + * `wasm-ld -r` is prohibitively slow, especially when handling large + input objects (e.g. profiled objects). + +In these cases, we bundle a module's own object file with its foreign +stub's object file, instead of merging them. Consequently, we can end +up producing `.o` files which are in fact static archives. This can +only work if `ar -L` is supported, so the archive `.o` files can be +properly added to the final static library. We must also take care not +to produce archive `.dyn_o` when building dynamic objects, otherwise +we end up with broken `.so` files when GHC is built with `llvm-ar` +(#22210). Note that this has somewhat non-obvious consequences when producing initializers and finalizers. See Note [Initializers and finalizers in Cmm] @@ -1072,7 +1081,7 @@ via gcc. -- | See Note [Object merging]. joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO () joinObjectFiles hsc_env o_files output_fn - | can_merge_objs && not dashLSupported = do + | can_merge_objs && (not dashLSupported || is_dyn) = do let toolSettings' = toolSettings dflags ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings' ld_r args = GHC.SysTools.runMergeObjects (hsc_logger hsc_env) (hsc_tmpfs hsc_env) (hsc_dflags hsc_env) ( @@ -1100,6 +1109,7 @@ joinObjectFiles hsc_env o_files output_fn withAtomicRename output_fn $ \tmp_ar -> liftIO $ runAr logger dflags Nothing $ map Option $ ["qc" ++ dashL, tmp_ar] ++ o_files where + is_dyn = ways dflags `hasWay` WayDyn dashLSupported = sArSupportsDashL (settings dflags) dashL = if dashLSupported then "L" else "" can_merge_objs = isJust (pgm_lm (hsc_dflags hsc_env)) ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/Parser.y ===================================== @@ -3342,7 +3342,7 @@ alts1(PATS) :: { forall b. DisambECP b => PV (Located ([AddEpAnn],[LMatch GhcPs alt(PATS) :: { forall b. DisambECP b => PV (LMatch GhcPs (LocatedA b)) } : PATS alt_rhs { $2 >>= \ $2 -> - acsA (sLLAsl $1 $> ()) (\loc cs -> L (locA loc) + amsA' (sLLAsl $1 $> (Match { m_ext = [] , m_ctxt = CaseAlt -- for \case and \cases, this will be changed during post-processing , m_pats = $1 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,6 +4,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -21,7 +22,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +31,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +69,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +103,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +141,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +174,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +277,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +301,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +363,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +400,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +416,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +437,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +459,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +497,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +510,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +522,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +543,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +569,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +594,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +618,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +646,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1065,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1129,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1147,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1168,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1400,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1434,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1481,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== configure.ac ===================================== @@ -97,11 +97,11 @@ dnl use either is considered a Feature. dnl ** What command to use to compile compiler sources ? dnl -------------------------------------------------------------- -AC_ARG_VAR(GHC,[Use as the full path to GHC. [default=autodetect]]) -AC_PATH_PROG([GHC], [ghc]) +AC_ARG_VAR(GHC,[Use as the bootstrap GHC. [default=autodetect]]) +AC_CHECK_PROG([GHC], [ghc], [ghc]) AC_ARG_WITH([ghc], - AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the full path to ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), - AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' or 'GHC=$withval ./configure' instead)])) + AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the bootstrap ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), + AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' instead)])) AC_SUBST(WithGhc,$GHC) AC_ARG_ENABLE(bootstrap-with-devel-snapshot, ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -31,6 +31,7 @@ import qualified Distribution.PackageDescription.Parsec as C import qualified Distribution.Simple.Compiler as C import qualified Distribution.Simple.Program.Db as C import qualified Distribution.Simple as C +import qualified Distribution.Simple.GHC as GHC import qualified Distribution.Simple.Program.Builtin as C import qualified Distribution.Simple.Utils as C import qualified Distribution.Simple.Program.Types as C @@ -363,12 +364,11 @@ registerPackage rs context = do need [setupConfig] -- This triggers 'configurePackage' pd <- packageDescription <$> readContextData context db_path <- packageDbPath (PackageDbLoc (stage context) (iplace context)) - dist_dir <- Context.buildPath context pid <- pkgUnitId (stage context) (package context) -- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path -- from the local build info @lbi at . lbi <- liftIO $ C.getPersistBuildConfig cPath - liftIO $ register db_path pid dist_dir pd lbi + liftIO $ register db_path pid pd lbi -- Then after the register, which just writes the .conf file, do the recache step. buildWithResources rs $ target context (GhcPkg Recache (stage context)) [] [] @@ -377,25 +377,23 @@ registerPackage rs context = do -- into a different package database to the one it was configured against. register :: FilePath -> String -- ^ Package Identifier - -> FilePath -> C.PackageDescription -> LocalBuildInfo -> IO () -register pkg_db pid build_dir pd lbi +register pkg_db pid pd lbi = withLibLBI pd lbi $ \lib clbi -> do - absPackageDBs <- C.absolutePackageDBPaths packageDbs - installedPkgInfo <- C.generateRegistrationInfo - C.silent pd lib lbi clbi False reloc build_dir - (C.registrationPackageDB absPackageDBs) - + when reloc $ error "register does not support reloc" + installedPkgInfo <- generateRegistrationInfo pd lbi lib clbi writeRegistrationFile installedPkgInfo where regFile = pkg_db pid <.> "conf" reloc = relocatable lbi - -- Using a specific package db here is why we have to copy the function from Cabal. - packageDbs = [C.SpecificPackageDB pkg_db] + + generateRegistrationInfo pkg lbi lib clbi = do + abi_hash <- C.mkAbiHash <$> GHC.libAbiHash C.silent pkg lbi lib clbi + return (C.absoluteInstalledPackageInfo pkg abi_hash lib lbi clbi) writeRegistrationFile installedPkgInfo = do writeUTF8File regFile (CP.showInstalledPackageInfo installedPkgInfo) ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -17,6 +17,12 @@ MultiModulesRecomp: ./genMultiLayerModules '$(TEST_HC)' $(TEST_HC_OPTS) -v0 MultiLayerModules.hs +# -e "" exits the ghci session immediately and merely makes sure, we generated interface files +# containing core expressions, aka `mi_extra_decls` are populated. +MultiModulesRecompDefsWithCore: + ./genMultiLayerModulesCore + '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithCore.script ===================================== @@ -0,0 +1 @@ +:m + MultiLayerModules ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -405,6 +405,20 @@ test('MultiLayerModulesDefsGhci', ghci_script, ['MultiLayerModulesDefsGhci.script']) +test('MultiLayerModulesDefsGhciWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesRecompDefsWithCore'), + extra_files(['genMultiLayerModulesCore', 'MultiLayerModulesDefsGhciWithCore.script']), + compile_timeout_multiplier(5), + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + extra_run_opts('-fwrite-if-simplified-core MultiLayerModules') + ], + ghci_script, + ['MultiLayerModulesDefsGhciWithCore.script']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), ===================================== testsuite/tests/perf/compiler/genMultiLayerModulesCore ===================================== @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Generate $WIDTH modules with one type each $FIELDS type variables. +# The type has $CONSTRS constructors with each $FIELDS fields. +# All types derive 'Generic' to generate a large amount of Types. +# MultiLayerModules.hs imports all the modules +WIDTH=10 +FIELDS=10 +CONSTRS=15 +FIELD_VARS=$(for field in $(seq -w 1 $FIELDS); do echo -n "a${field} "; done) +for i in $(seq -w 1 $WIDTH); do + echo "module DummyLevel$i where" > DummyLevel$i.hs; + echo "import GHC.Generics" >> DummyLevel$i.hs; + echo "data Type_${i} ${FIELD_VARS}" >> DummyLevel$i.hs; + for constr in $(seq -w 1 $CONSTRS); do + if [ $constr -eq 1 ]; then + echo -n " = Constr_${i}_${constr} " >> DummyLevel$i.hs; + else + echo -n " | Constr_${i}_${constr} " >> DummyLevel$i.hs; + fi + echo ${FIELD_VARS} >> DummyLevel$i.hs; + done + echo " deriving (Show, Eq, Ord, Generic)" >> DummyLevel$i.hs; +done + +echo "module MultiLayerModules where" > MultiLayerModules.hs +for j in $(seq -w 1 $WIDTH); do + echo "import DummyLevel$j" >> MultiLayerModules.hs; +done ===================================== testsuite/tests/printer/CaseAltComments.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PatternGuards #-} +module CaseAltComments where + +nfCom = case expr of + x :*: y -- comment + | x' <= y' -> x' :*: y' + _ -> blah ===================================== testsuite/tests/printer/Makefile ===================================== @@ -826,3 +826,8 @@ Test24533: PprLetIn: $(CHECK_PPR) $(LIBDIR) PprLetIn.hs $(CHECK_EXACT) $(LIBDIR) PprLetIn.hs + +.PHONY: CaseAltComments +CaseAltComments: + $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs + $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -198,3 +198,4 @@ test('ListTuplePuns', extra_files(['ListTuplePuns.hs']), ghci_script, ['ListTupl test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, ['AnnotationNoListTuplePuns']) test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) +test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eda3aa6ee1c86bab4c07b81ce758fc4520e72f69...be6836a22245743b736ae1fc88b4c0ba3e2cce6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eda3aa6ee1c86bab4c07b81ce758fc4520e72f69...be6836a22245743b736ae1fc88b4c0ba3e2cce6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 07:49:48 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 24 Apr 2024 03:49:48 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 14 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <6628b99c8319f_1ab69073c1fc153cd@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - d636f6a2 by Fendor at 2024-04-24T09:47:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - be6836a2 by Fendor at 2024-04-24T09:47:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - a0f3d1f7 by Fendor at 2024-04-24T09:49:28+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 61407888 by Fendor at 2024-04-24T09:49:28+02:00 Break cyclic module dependency - - - - - 9932b31d by Fendor at 2024-04-24T09:49:28+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - 7ddf8ecf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 2c32fbcf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 5c18a8b8 by Fendor at 2024-04-24T09:49:28+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Var.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6d5a5c2a34a43d216eb0b0ad478cfdd9e6d1bd0...5c18a8b8dbf12b57bee949fa69de4d8133ca12a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6d5a5c2a34a43d216eb0b0ad478cfdd9e6d1bd0...5c18a8b8dbf12b57bee949fa69de4d8133ca12a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 07:51:26 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 24 Apr 2024 03:51:26 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 16 commits: Add performance regression test for '-fwrite-simplified-core' Message-ID: <6628b9fe3446e_1ab6907d28a015626@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - d636f6a2 by Fendor at 2024-04-24T09:47:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - be6836a2 by Fendor at 2024-04-24T09:47:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - a0f3d1f7 by Fendor at 2024-04-24T09:49:28+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 61407888 by Fendor at 2024-04-24T09:49:28+02:00 Break cyclic module dependency - - - - - 9932b31d by Fendor at 2024-04-24T09:49:28+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - 7ddf8ecf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 2c32fbcf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 5c18a8b8 by Fendor at 2024-04-24T09:49:28+02:00 Implement TrieMap for IfaceType - - - - - 4db39e3c by Fendor at 2024-04-24T09:51:19+02:00 Share duplicated values in ModIface after generation This helps keeping down the peak memory usage while compiling in `--make` mode. - - - - - 5b7e1def by Fendor at 2024-04-24T09:51:19+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 30 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d073db1e92b5d41d1b7e07dcc57d467976ceac08...5b7e1def55d5ac2b6d6d0e2766bf19fb00d24218 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d073db1e92b5d41d1b7e07dcc57d467976ceac08...5b7e1def55d5ac2b6d6d0e2766bf19fb00d24218 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 11:23:56 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Wed, 24 Apr 2024 07:23:56 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] Reuse the 'ReadBinMem' after sharing to avoid recomputations Message-ID: <6628ebccfb62_1ab690248cb0858470@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: e534e60d by Fendor at 2024-04-24T13:23:40+02:00 Reuse the 'ReadBinMem' after sharing to avoid recomputations - - - - - 7 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -166,14 +167,18 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start pure mod_iface { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData } @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -153,17 +153,33 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface return final_iface +-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. +-- +-- We compress the 'ModIface' by serialising the 'ModIface' to an in-memory byte array, and then deserialising it. +-- The deserialisation will deduplicate certain values depending on the 'CompressionIFace' level. +-- See Note [Deduplication during iface binary serialisation] for how we do that. +-- +-- Additionally, we cache the serialised byte array, so if the 'ModIface' is not modified +-- after calling 'shareIface', 'writeBinIface' will reuse that buffer without serialising the 'ModIface' again. +-- Modifying the 'ModIface' forces us to re-serialise it again. shareIface :: NameCache -> CompressionIFace -> ModIface -> IO ModIface +shareIface _ NormalCompression mi = do + -- In 'NormalCompression', the sharing isn't reducing the memory usage, as 'Name's and 'FastString's are + -- already shared, and at this compression level, we don't compress/share anything else. + -- Thus, for a brief moment we simply double the memory residency for no reason. + -- Therefore, we only try to share expensive values if the compression mode is higher than + -- 'NormalCompression' + pure mi shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } forceModIface resiface - return resiface + pure resiface updateDecl :: [IfaceDecl] -> Maybe StgCgInfos -> Maybe CmmCgInfos -> [IfaceDecl] @@ -318,40 +334,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -20,7 +20,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,6 +33,7 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, @@ -48,6 +49,7 @@ module GHC.Utils.Binary putAt, getAt, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -102,6 +104,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -126,7 +132,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -156,7 +162,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -196,6 +201,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -289,9 +351,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr ()) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -382,12 +465,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1108,6 +1197,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1136,7 +1230,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1148,6 +1242,45 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + let relBin = toRelBin pre_a a + putAt bh pre_a (makeRelativeBin relBin) + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1157,19 +1290,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAt bh pre_a (makeRelativeBin $ toRelBin pre_a q) -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1178,7 +1311,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1472,13 +1605,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e534e60d2574d7d6603b62b0aa7c58778535effd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e534e60d2574d7d6603b62b0aa7c58778535effd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 12:10:05 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 24 Apr 2024 08:10:05 -0400 Subject: [Git][ghc/ghc][wip/T24676] Fix bugs Message-ID: <6628f69db52ea_2d9bf152e5f4528a@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: 18712afb by Simon Peyton Jones at 2024-04-24T14:09:20+02:00 Fix bugs expanding EValArgQL - - - - - 6 changed files: - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -151,7 +151,7 @@ tcInferSigma inst (L loc rn_expr) do { (fun@(rn_fun,fun_ctxt), rn_args) <- splitHsApps rn_expr ; do_ql <- wantQuickLook rn_fun ; (tc_fun, fun_sigma) <- tcInferAppHead fun - ; (_delta, inst_args, app_res_sigma) <- tcInstFun do_ql inst (tc_fun, fun_ctxt) fun_sigma rn_args + ; (_delta, inst_args, app_res_sigma) <- tcInstFun do_ql inst fun_ctxt tc_fun fun_sigma rn_args ; _tc_args <- tcValArgs do_ql inst_args ; return app_res_sigma } @@ -319,7 +319,10 @@ The latter is much better. That is why we call unifyExpectedType before tcValArgs. -} -tcApp :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) +tcApp :: HsExpr GhcRn + -> ExpRhoType -- DeepSubsumption <=> when checking, this type + -- is deeply skolemised + -> TcM (HsExpr GhcTc) -- See Note [tcApp: typechecking applications] tcApp rn_expr exp_res_ty = do { (fun@(rn_fun, fun_ctxt), rn_args) <- splitHsApps rn_expr @@ -333,30 +336,29 @@ tcApp rn_expr exp_res_ty -- Instantiate ; do_ql <- wantQuickLook rn_fun - ; (delta, inst_args, app_res_rho) <- tcInstFun do_ql True (tc_fun, fun_ctxt) fun_sigma rn_args + ; (delta, inst_args, app_res_rho) + <- tcInstFun do_ql True fun_ctxt tc_fun fun_sigma rn_args -- Quick look at result ; app_res_rho <- if do_ql then quickLookResultType delta app_res_rho exp_res_ty else return app_res_rho + ; finishApp do_ql rn_expr fun tc_fun inst_args app_res_rho exp_res_ty } + +finishApp :: Bool -> HsExpr GhcRn -> (HsExpr GhcRn, AppCtxt) + -> HsExpr GhcTc -> [HsExprArg 'TcpInst] + -> TcRhoType + -> ExpRhoType + -> TcM (HsExpr GhcTc) +finishApp do_ql rn_expr (rn_fun, fun_ctxt) tc_fun inst_args app_res_rho exp_res_ty + = do { do_ds <- xoptM LangExt.DeepSubsumption + -- Unify with expected type from the context -- See Note [Unify with expected type before typechecking arguments] -- - -- perhaps_add_res_ty_ctxt: Inside an expansion, the addFunResCtxt stuff is - -- more confusing than helpful because the function at the head isn't in - -- the source program; it was added by the renamer. See - -- Note [Handling overloaded and rebindable constructs] in GHC.Rename.Expr - ; let perhaps_add_res_ty_ctxt thing_inside - | insideExpansion fun_ctxt - = addHeadCtxt fun_ctxt thing_inside - | otherwise - = addFunResCtxt rn_fun rn_args app_res_rho exp_res_ty $ - thing_inside - -- Match up app_res_rho: the result type of rn_expr -- with exp_res_ty: the expected result type - ; do_ds <- xoptM LangExt.DeepSubsumption ; res_wrap <- perhaps_add_res_ty_ctxt $ if not do_ds then -- No deep subsumption @@ -387,11 +389,8 @@ tcApp rn_expr exp_res_ty ; whenDOptM Opt_D_dump_tc_trace $ do { inst_args <- liftZonkM $ mapM zonkArg inst_args -- Only when tracing ; traceTc "tcApp }" (vcat [ text "rn_fun:" <+> ppr rn_fun - , text "rn_args:" <+> ppr rn_args , text "inst_args" <+> brackets (pprWithCommas pprHsExprArgTc inst_args) , text "do_ql: " <+> ppr do_ql - , text "fun_sigma: " <+> ppr fun_sigma - , text "delta: " <+> ppr delta , text "app_res_rho:" <+> ppr app_res_rho , text "exp_res_ty:" <+> ppr exp_res_ty , text "rn_expr:" <+> ppr rn_expr @@ -401,6 +400,18 @@ tcApp rn_expr exp_res_ty -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } + where + -- perhaps_add_res_ty_ctxt: Inside an expansion, the addFunResCtxt stuff is + -- more confusing than helpful because the function at the head isn't in + -- the source program; it was added by the renamer. See + -- Note [Handling overloaded and rebindable constructs] in GHC.Rename.Expr + perhaps_add_res_ty_ctxt thing_inside + | insideExpansion fun_ctxt + = addHeadCtxt fun_ctxt thing_inside + | otherwise + = addFunResCtxt rn_fun inst_args app_res_rho exp_res_ty $ + thing_inside + -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool @@ -430,9 +441,9 @@ zonkQuickLook do_ql ty -- see what is going on. For that reason, it is not a full zonk: add -- more if you need it. zonkArg :: HsExprArg 'TcpInst -> ZonkM (HsExprArg 'TcpInst) -zonkArg eva@(EValArg { eva_arg_ty = Scaled m ty }) +zonkArg eva@(EValArg { ea_arg_ty = Scaled m ty }) = do { ty' <- zonkTcType ty - ; return (eva { eva_arg_ty = Scaled m ty' }) } + ; return (eva { ea_arg_ty = Scaled m ty' }) } zonkArg arg = return arg @@ -442,60 +453,85 @@ zonkArg arg = return arg tcValArgs :: Bool -- Quick-look on? -> [HsExprArg 'TcpInst] -- Actual argument -> TcM [HsExprArg 'TcpTc] -- Resulting argument -tcValArgs do_ql args - = mapM tc_arg args - where - tc_arg :: HsExprArg 'TcpInst -> TcM (HsExprArg 'TcpTc) - tc_arg (EPrag l p) = return (EPrag l (tcExprPrag p)) - tc_arg (EWrap w) = return (EWrap w) - tc_arg (ETypeArg l hs_ty ty) = return (ETypeArg l hs_ty ty) - - tc_arg eva@(EValArg { eva_arg = arg, eva_arg_ty = Scaled mult arg_ty - , eva_ctxt = ctxt }) - = do { -- Crucial step: expose QL results before checking arg_ty - -- So far as the paper is concerned, this step applies - -- the poly-substitution Theta, learned by QL, so that we - -- "see" the polymorphism in that argument type. E.g. - -- (:) e ids, where ids :: [forall a. a->a] - -- (:) :: forall p. p->[p]->[p] - -- Then Theta = [p :-> forall a. a->a], and we want - -- to check 'e' with expected type (forall a. a->a) - -- See Note [Instantiation variables are short lived] - arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty - - -- Now check the argument - ; arg' <- tcScalingUsage mult $ - do { traceTc "tcEValArg" $ - vcat [ ppr ctxt - , text "arg type:" <+> ppr arg_ty - , text "arg:" <+> ppr arg ] - ; tcEValArg ctxt arg arg_ty } - - ; return (eva { eva_arg = ValArg arg' - , eva_arg_ty = Scaled mult arg_ty }) } - -tcEValArg :: AppCtxt -> EValArg 'TcpInst -> TcSigmaTypeFRR -> TcM (LHsExpr GhcTc) --- Typecheck one value argument of a function call -tcEValArg ctxt (ValArg larg@(L arg_loc arg)) exp_arg_sigma +tcValArgs do_ql args = mapM (tcValArg do_ql) args + +tcValArg :: Bool -- Quick-look on? + -> HsExprArg 'TcpInst -- Actual argument + -> TcM (HsExprArg 'TcpTc) -- Resulting argument +tcValArg _ (EPrag l p) = return (EPrag l (tcExprPrag p)) +tcValArg _ (EWrap w) = return (EWrap w) +tcValArg _ (ETypeArg l hs_ty ty) = return (ETypeArg l hs_ty ty) + +tcValArg do_ql (EValArg { ea_ctxt = ctxt + , ea_arg = larg@(L arg_loc arg) + , ea_arg_ty = Scaled mult arg_ty }) = addArgCtxt ctxt larg $ - do { arg' <- tcPolyExpr arg (mkCheckExpType exp_arg_sigma) - ; return (L arg_loc arg') } - -tcEValArg ctxt (ValArgQL { va_expr = larg@(L arg_loc _) - , va_fun = (inner_fun, fun_ctxt) - , va_args = inner_args - , va_ty = app_res_rho }) exp_arg_sigma + do { traceTc "tcValArg" $ + vcat [ ppr ctxt + , text "arg type:" <+> ppr arg_ty + , text "arg:" <+> ppr arg ] + + -- Crucial step: expose QL results before checking arg_ty + -- So far as the paper is concerned, this step applies + -- the poly-ubstitution Theta, learned by QL, so that we + -- "see" the polymorphism in that argument type. E.g. + -- (:) e ids, where ids :: [forall a. a->a] + -- (:) :: forall p. p->[p]->[p] + -- Then Theta = [p :-> forall a. a->a], and we want + -- to check 'e' with expected type (forall a. a->a) + -- See Note [Instantiation variables are short lived] + ; arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty + + -- Now check the argument + ; arg' <- tcScalingUsage mult $ + tcPolyExpr arg (mkCheckExpType arg_ty) + + ; return (EValArg { ea_ctxt = ctxt + , ea_arg = L arg_loc arg' + , ea_arg_ty = Scaled mult arg_ty }) } + +tcValArg do_ql (EValArgQL { eaql_ctxt = ctxt + , eaql_arg_ty = Scaled mult arg_ty + , eaql_larg = larg@(L arg_loc rn_expr) + , eaql_head = rn_head + , eaql_delta = mb_delta + , eaql_tc_fun = tc_fun + , eaql_args = inst_args + , eaql_res_rho = res_rho }) = addArgCtxt ctxt larg $ - do { traceTc "tcEValArgQL {" (vcat [ ppr inner_fun <+> ppr inner_args ]) - ; tc_args <- tcValArgs True inner_args - - ; co <- unifyType Nothing app_res_rho exp_arg_sigma - ; arg' <- mkHsWrapCo co <$> rebuildHsApps inner_fun fun_ctxt tc_args app_res_rho + do { arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty + ; traceTc "tcEValArgQL {" (vcat [ ppr rn_head + , text "mb_delta:" <+> ppr mb_delta + , text "app_res_rho:" <+> ppr res_rho + , text "arg_ty:" <+> ppr arg_ty + , text "args:" <+> ppr inst_args ]) + + ; arg' <- tcScalingUsage mult $ + do_skolemise arg_ty $ \arg_rho -> + finishApp do_ql rn_expr rn_head tc_fun inst_args res_rho + (Check arg_rho) ; traceTc "tcEValArgQL }" $ - vcat [ text "inner_fun:" <+> ppr inner_fun - , text "app_res_rho:" <+> ppr app_res_rho - , text "exp_arg_sigma:" <+> ppr exp_arg_sigma ] - ; return (L arg_loc arg') } + vcat [ text "rn_head:" <+> ppr rn_head + , text "res_rho:" <+> ppr res_rho ] + ; return (EValArg { ea_ctxt = ctxt + , ea_arg = L arg_loc arg' + , ea_arg_ty = Scaled mult arg_ty }) } + + where + do_skolemise arg_ty thing_inside = case mb_delta of + Nothing -> thing_inside arg_ty + Just (delta, wanted) + -> do { ds_flag <- getDeepSubsumptionFlag + ; lvl1 <- getTcLevel + ; (wrap, arg') <- tcSkolemise ds_flag GenSigCtxt arg_ty $ \ arg_rho -> + do { demoteQLDelta delta + ; emitConstraints wanted + ; lvl2 <- getTcLevel + ; traceTc "EVQL 2" (vcat [ ppr lvl1 <+> ppr lvl2 + , ppr arg_ty, ppr arg_rho ]) + ; thing_inside arg_rho } + ; return (mkHsWrap wrap arg') } + {- ********************************************************************* * * @@ -503,11 +539,6 @@ tcEValArg ctxt (ValArgQL { va_expr = larg@(L arg_loc _) * * ********************************************************************* -} -type Delta = TcTyVarSet -- Set of instantiation variables, - -- written \kappa in the QL paper - -- Just a set of ordinary unification variables, - -- but ones that QL may fill in with polytypes - tcInstFun :: Bool -- True <=> Do quick-look -> Bool -- False <=> Instantiate only /inferred/ variables at the end -- so may return a sigma-type @@ -517,7 +548,8 @@ tcInstFun :: Bool -- True <=> Do quick-look -- in tcInferSigma, which is used only to implement :type -- Otherwise we do eager instantiation; in Fig 5 of the paper -- |-inst returns a rho-type - -> (HsExpr GhcTc, AppCtxt) + -> AppCtxt + -> HsExpr GhcTc -- ^ For error messages and to retrieve concreteness information -- of the function -> TcSigmaType -> [HsExprArg 'TcpRn] @@ -527,7 +559,7 @@ tcInstFun :: Bool -- True <=> Do quick-look -- This function implements the |-inst judgement in Fig 4, plus the -- modification in Fig 5, of the QL paper: -- "A quick look at impredicativity" (ICFP'20). -tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args +tcInstFun do_ql inst_final fun_ctxt tc_fun fun_sigma rn_args = do { traceTc "tcInstFun" (vcat [ text "tc_fun" <+> ppr tc_fun , text "fun_sigma" <+> ppr fun_sigma , text "fun_ctxt" <+> ppr fun_ctxt @@ -535,15 +567,11 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args , text "do_ql" <+> ppr do_ql ]) ; go emptyVarSet [] [] fun_sigma rn_args } where - fun_orig - | VAExpansion (OrigStmt{}) _ _ <- fun_ctxt - = DoOrigin - | VAExpansion (OrigPat pat) _ _ <- fun_ctxt - = DoPatOrigin pat - | VAExpansion (OrigExpr e) _ _ <- fun_ctxt - = exprCtOrigin e - | VACall e _ _ <- fun_ctxt - = exprCtOrigin e + fun_orig = case fun_ctxt of + VAExpansion (OrigStmt{}) _ _ -> DoOrigin + VAExpansion (OrigPat pat) _ _ -> DoPatOrigin pat + VAExpansion (OrigExpr e) _ _ -> exprCtOrigin e + VACall e _ _ -> exprCtOrigin e -- These are the type variables which must be instantiated to concrete -- types. See Note [Representation-polymorphic Ids with no binding] @@ -640,7 +668,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- nested forall a. Eq a => forall b. Show b => blah -- Rule ITVDQ from the GHC Proposal #281 - go1 delta acc so_far fun_ty ((EValArg { eva_arg = ValArg arg }) : rest_args) + go1 delta acc so_far fun_ty ((EValArg { ea_arg = arg }) : rest_args) | Just (tvb, body) <- tcSplitForAllTyVarBinder_maybe fun_ty = assertPpr (binderFlag tvb == Required) (ppr fun_ty $$ ppr arg) $ -- Any invisible binders have been instantiated by IALL above, @@ -661,10 +689,10 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args = go1 delta (EPrag sp prag : acc) so_far fun_ty args -- Rule ITYARG from Fig 4 of the QL paper - go1 delta acc so_far fun_ty ( ETypeArg { eva_ctxt = ctxt, eva_hs_ty = hs_ty } + go1 delta acc so_far fun_ty ( ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty } : rest_args ) = do { (ty_arg, inst_ty) <- tcVTA fun_conc_tvs fun_ty hs_ty - ; let arg' = ETypeArg { eva_ctxt = ctxt, eva_hs_ty = hs_ty, eva_ty = ty_arg } + ; let arg' = ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg } ; go delta (arg' : acc) so_far inst_ty rest_args } -- Rule IVAR from Fig 4 of the QL paper: @@ -695,7 +723,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- When we come to unify the nus (in qlUnify), we will call -- unifyKind on the kinds. This will do the right thing, even though -- we are manually filling in the nu metavariables. - new_arg_tv (ValArg (L _ arg)) i = + new_arg_tv (L _ arg) i = newOpenFlexiFRRTyVar $ FRRExpectedFunTy (ExpectedFunTyArg (HsExprTcThing tc_fun) arg) i ; arg_nus <- zipWithM new_arg_tv @@ -721,7 +749,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- Rule IARG from Fig 4 of the QL paper: go1 delta acc so_far fun_ty - (eva@(EValArg { eva_arg = ValArg arg, eva_ctxt = ctxt }) : rest_args) + (eva@(EValArg { ea_arg = arg, ea_ctxt = ctxt }) : rest_args) = do { let herald = case fun_ctxt of VAExpansion (OrigStmt{}) _ _ -> ExpectedFunTySyntaxOp DoOrigin tc_fun _ -> ExpectedFunTyArg (HsExprTcThing tc_fun) (unLoc arg) @@ -739,10 +767,9 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args then addArgCtxt ctxt arg $ -- Context needed for constraints -- generated by calls in arg - quickLookArg delta arg arg_ty - else return (delta, ValArg arg) - ; let acc' = eva { eva_arg = arg', eva_arg_ty = arg_ty } - : addArgWrap wrap acc + quickLookArg delta ctxt arg arg_ty + else return (delta, eva { ea_arg_ty = arg_ty }) + ; let acc' = arg' : addArgWrap wrap acc ; go delta' acc' (arg_ty:so_far) res_ty rest_args } -- Is the argument supposed to instantiate a forall? @@ -759,7 +786,7 @@ looks_like_type_arg ETypeArg{} = -- The argument is clearly supposed to instantiate an invisible forall, -- i.e. when we see `f @a`, we expect `f :: forall x. t`. True -looks_like_type_arg EValArg{ eva_arg = ValArg (L _ e) } = +looks_like_type_arg EValArg{ ea_arg = L _ e } = -- Check if the argument is supposed to instantiate a visible forall, -- i.e. when we see `f (type Int)`, we expect `f :: forall x -> t`, -- but not if we see `f True`. @@ -1457,51 +1484,54 @@ Wrinkles: ---------------- quickLookArg :: Delta + -> AppCtxt -> LHsExpr GhcRn -- ^ Argument -> Scaled TcSigmaTypeFRR -- ^ Type expected by the function - -> TcM (Delta, EValArg 'TcpInst) + -> TcM (Delta, HsExprArg 'TcpInst) -- See Note [Quick Look at value arguments] -- -- The returned Delta is a superset of the one passed in -- with added instantiation variables from -- (a) the call itself -- (b) the arguments of the call -quickLookArg delta larg (Scaled _ arg_ty) - | isEmptyVarSet delta = skipQuickLook delta larg - | otherwise = go arg_ty +quickLookArg delta ctxt larg orig_arg_ty + | isEmptyVarSet delta = skipQuickLook delta ctxt larg orig_arg_ty + | otherwise = go orig_arg_ty where - guarded = isGuardedTy arg_ty + guarded = isGuardedTy orig_arg_ty -- NB: guardedness is computed based on the original, -- unzonked arg_ty (before calling `go`), so that we deliberately do -- not exploit guardedness that emerges a result of QL on earlier args - go arg_ty | not (isRhoTy arg_ty) - = skipQuickLook delta larg + go sc_arg_ty@(Scaled mult arg_ty) + | not (isRhoTy arg_ty) + = skipQuickLook delta ctxt larg sc_arg_ty - -- This top-level zonk step, which is the reason - -- we need a local 'go' loop, is subtle - -- See Section 9 of the QL paper - | Just kappa <- getTyVar_maybe arg_ty - , kappa `elemVarSet` delta - = do { info <- readMetaTyVar kappa - ; case info of - Indirect arg_ty' -> go arg_ty' - Flexi -> quickLookArg1 guarded delta larg arg_ty } + -- This top-level zonk step, which is the reason + -- we need a local 'go' loop, is subtle + -- See Section 9 of the QL paper + | Just kappa <- getTyVar_maybe arg_ty + , kappa `elemVarSet` delta + = do { info <- readMetaTyVar kappa + ; case info of + Indirect arg_ty'' -> go (Scaled mult arg_ty'') + Flexi -> quickLookArg1 guarded delta ctxt larg sc_arg_ty } - | otherwise - = quickLookArg1 guarded delta larg arg_ty + | otherwise + = quickLookArg1 guarded delta ctxt larg sc_arg_ty -isGuardedTy :: TcType -> Bool -isGuardedTy ty +isGuardedTy :: Scaled TcType -> Bool +isGuardedTy (Scaled _ ty) | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal | Just {} <- tcSplitAppTy_maybe ty = True | otherwise = False -quickLookArg1 :: Bool -> Delta -> LHsExpr GhcRn -> TcSigmaTypeFRR - -> TcM (Delta, EValArg 'TcpInst) +quickLookArg1 :: Bool -> Delta -> AppCtxt -> LHsExpr GhcRn + -> Scaled TcRhoType + -> TcM (Delta, HsExprArg 'TcpInst) -- quickLookArg1 implements the "QL Argument" judgement in Fig 5 of the paper -quickLookArg1 guarded delta larg@(L _ arg) arg_ty - = do { ((rn_fun, fun_ctxt), rn_args) <- splitHsApps arg +quickLookArg1 guarded delta ctxt larg@(L _ arg) sc_arg_ty@(Scaled _ arg_ty) + = do { (rn_head@(rn_fun, fun_ctxt), rn_args) <- splitHsApps arg -- Step 1: get the type of the head of the argument ; mb_fun_ty <- tcInferAppHead_maybe rn_fun @@ -1512,12 +1542,22 @@ quickLookArg1 guarded delta larg@(L _ arg) arg_ty , text "args:" <+> ppr rn_args ] ; case mb_fun_ty of { - Nothing -> skipQuickLook delta larg ; -- fun is too complicated + Nothing -> skipQuickLook delta ctxt larg sc_arg_ty ; -- fun is too complicated Just (tc_fun, fun_sigma) -> -- Step 2: use |-inst to instantiate the head applied to the arguments do { do_ql <- wantQuickLook rn_fun - ; (delta_app, inst_args, app_res_rho) <- tcInstFun do_ql True (tc_fun, fun_ctxt) fun_sigma rn_args + ; ((delta_app, inst_args, app_res_rho), wanted) + <- captureConstraints $ + tcInstFun do_ql True fun_ctxt tc_fun fun_sigma rn_args + ; let ql_arg = EValArgQL { eaql_ctxt = ctxt + , eaql_arg_ty = sc_arg_ty + , eaql_larg = larg + , eaql_head = rn_head + , eaql_delta = Nothing + , eaql_tc_fun = tc_fun + , eaql_args = inst_args + , eaql_res_rho = app_res_rho } ; traceTc "quickLookArg 2" $ vcat [ text "arg:" <+> ppr arg @@ -1535,19 +1575,18 @@ quickLookArg1 guarded delta larg@(L _ arg) arg_ty -- Step 4: do quick-look unification if either (A) or (B) hold -- NB: arg_ty may not be zonked, but that's ok - ; let delta' = delta `unionVarSet` delta_app - ; when can_do_ql $ - qlUnify delta' arg_ty app_res_rho - - ; traceTc "quickLookArg 3" $ - vcat [ text "tc_fun:" <+> ppr tc_fun - , text "fun_sigma:" <+> ppr fun_sigma ] - - ; let ql_arg = ValArgQL { va_expr = larg - , va_fun = (tc_fun, fun_ctxt) - , va_args = inst_args - , va_ty = app_res_rho } - ; return (delta', ql_arg) } } } + ; if can_do_ql + then do { let delta' = delta `unionVarSet` delta_app + ; qlUnify delta' arg_ty app_res_rho + ; emitConstraints wanted + ; traceTc "quickLookArg unify" (ppr rn_fun <+> ppr delta') + ; return (delta', ql_arg) } + + else -- Treat this argument independently + do { let ql_arg' = ql_arg { eaql_delta = Just (delta_app, wanted) } + ; traceTc "quickLookArg indep" (ppr rn_fun <+> ppr delta_app) + ; return (delta, ql_arg') } + }}} anyFreeKappa :: Delta -> TcType -> TcM Bool -- True if there is a free instantiation variable (member of Delta) @@ -1565,8 +1604,10 @@ anyFreeKappa delta ty | otherwise = return False -skipQuickLook :: Delta -> LHsExpr GhcRn -> TcM (Delta, EValArg 'TcpInst) -skipQuickLook delta larg = return (delta, ValArg larg) +skipQuickLook :: Delta -> AppCtxt -> LHsExpr GhcRn -> Scaled TcRhoType + -> TcM (Delta, HsExprArg 'TcpInst) +skipQuickLook delta ctxt larg arg_ty + = return (delta, EValArg { ea_ctxt = ctxt, ea_arg = larg, ea_arg_ty = arg_ty }) ---------------- quickLookResultType :: Delta -> TcRhoType -> ExpRhoType -> TcM TcRhoType ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -268,7 +268,10 @@ tcMonoExprNC (L loc expr) res_ty ; return (L loc expr') } --------------- -tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) +tcExpr :: HsExpr GhcRn + -> ExpRhoType -- DeepSubsumption <=> when checking, this type + -- is deeply skolemised + -> TcM (HsExpr GhcTc) -- Use tcApp to typecheck applications, which are treated specially -- by Quick Look. Specifically: ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -16,7 +16,7 @@ -} module GHC.Tc.Gen.Head - ( HsExprArg(..), EValArg(..), TcPass(..) + ( HsExprArg(..), TcPass(..), Delta , AppCtxt(..), appCtxtLoc, insideExpansion , splitHsApps, rebuildHsApps , addArgWrap, isHsValArg @@ -47,18 +47,19 @@ import GHC.Tc.Utils.Unify import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep_syntactic ) import GHC.Tc.Utils.Instantiate import GHC.Tc.Instance.Family ( tcLookupDataFamInst ) -import GHC.Core.FamInstEnv ( FamInstEnvs ) -import GHC.Core.UsageEnv ( singleUsageUE ) import GHC.Tc.Errors.Types import GHC.Tc.Solver ( InferMode(..), simplifyInfer ) import GHC.Tc.Utils.Env import GHC.Tc.Utils.TcMType import GHC.Tc.Types.Origin +import GHC.Tc.Types.Constraint( WantedConstraints ) import GHC.Tc.Utils.TcType as TcType import GHC.Tc.Types.Evidence import GHC.Tc.Zonk.TcType +import GHC.Core.FamInstEnv ( FamInstEnvs ) +import GHC.Core.UsageEnv ( singleUsageUE ) import GHC.Core.PatSyn( PatSyn ) import GHC.Core.ConLike( ConLike(..) ) import GHC.Core.DataCon @@ -168,37 +169,53 @@ data TcPass = TcpRn -- Arguments decomposed | TcpInst -- Function instantiated | TcpTc -- Typechecked -data HsExprArg (p :: TcPass) - = -- See Note [HsExprArg] - EValArg { eva_ctxt :: AppCtxt - , eva_arg :: EValArg p - , eva_arg_ty :: !(XEVAType p) } +type Delta = TcTyVarSet -- Set of instantiation variables, + -- written \kappa in the QL paper + -- Just a set of ordinary unification variables, + -- but ones that QL may fill in with polytypes + +data HsExprArg (p :: TcPass) where -- See Note [HsExprArg] + + -- See Note [EValArg] + EValArg :: { ea_ctxt :: AppCtxt + , ea_arg_ty :: !(XEVAType p) + , ea_arg :: LHsExpr (GhcPass (XPass p)) } + -> HsExprArg p - | ETypeArg { eva_ctxt :: AppCtxt - , eva_hs_ty :: LHsWcType GhcRn -- The type arg - , eva_ty :: !(XETAType p) } -- Kind-checked type arg + EValArgQL :: { eaql_ctxt :: AppCtxt + , eaql_arg_ty :: !(XEVAType 'TcpInst) -- Type expected by function + , eaql_larg :: LHsExpr GhcRn -- Original application + -- For location and error msgs + , eaql_head :: (HsExpr GhcRn, AppCtxt) -- Function of the application, + -- typechecked, plus its context + , eaql_delta :: Maybe (Delta, WantedConstraints) + -- Nothing <=> unified with caller + -- Just delta <=> independent + , eaql_tc_fun :: HsExpr GhcTc + , eaql_args :: [HsExprArg 'TcpInst] -- Args, instantiated + , eaql_res_rho :: TcRhoType } -- Result type of the application + -> HsExprArg 'TcpInst -- Only exists in TcpInst phase + + ETypeArg :: { ea_ctxt :: AppCtxt + , ea_hs_ty :: LHsWcType GhcRn -- The type arg + , ea_ty_arg :: !(XETAType p) } -- Kind-checked type arg + -> HsExprArg p + + EPrag :: AppCtxt -> (HsPragE (GhcPass (XPass p))) -> HsExprArg p + EWrap :: EWrap -> HsExprArg p - | EPrag AppCtxt - (HsPragE (GhcPass (XPass p))) +type family XETAType p where -- Type arguments + XETAType 'TcpRn = NoExtField + XETAType _ = Type - | EWrap EWrap +type family XEVAType p where -- Value arguments + XEVAType 'TcpRn = NoExtField + XEVAType _ = Scaled TcSigmaType data EWrap = EPar AppCtxt | EExpand HsThingRn | EHsWrap HsWrapper -data EValArg (p :: TcPass) where -- See Note [EValArg] - ValArg :: LHsExpr (GhcPass (XPass p)) - -> EValArg p - - ValArgQL :: { va_expr :: LHsExpr GhcRn -- Original application - -- For location and error msgs - , va_fun :: (HsExpr GhcTc, AppCtxt) -- Function of the application, - -- typechecked, plus its context - , va_args :: [HsExprArg 'TcpInst] -- Args, instantiated - , va_ty :: TcRhoType } -- Result type - -> EValArg 'TcpInst -- Only exists in TcpInst phase - data AppCtxt = VAExpansion HsThingRn @@ -254,23 +271,15 @@ type family XPass p where XPass 'TcpInst = 'Renamed XPass 'TcpTc = 'Typechecked -type family XETAType p where -- Type arguments - XETAType 'TcpRn = NoExtField - XETAType _ = Type - -type family XEVAType p where -- Value arguments - XEVAType 'TcpRn = NoExtField - XEVAType _ = Scaled Type - mkEValArg :: AppCtxt -> LHsExpr GhcRn -> HsExprArg 'TcpRn -mkEValArg ctxt e = EValArg { eva_arg = ValArg e, eva_ctxt = ctxt - , eva_arg_ty = noExtField } +mkEValArg ctxt e = EValArg { ea_arg = e, ea_ctxt = ctxt + , ea_arg_ty = noExtField } mkETypeArg :: AppCtxt -> LHsWcType GhcRn -> HsExprArg 'TcpRn mkETypeArg ctxt hs_ty = - ETypeArg { eva_ctxt = ctxt - , eva_hs_ty = hs_ty - , eva_ty = noExtField } + ETypeArg { ea_ctxt = ctxt + , ea_hs_ty = hs_ty + , ea_ty_arg = noExtField } addArgWrap :: HsWrapper -> [HsExprArg p] -> [HsExprArg p] addArgWrap wrap args @@ -392,9 +401,9 @@ rebuild_hs_apps :: HsExpr GhcTc rebuild_hs_apps fun _ [] = fun rebuild_hs_apps fun ctxt (arg : args) = case arg of - EValArg { eva_arg = ValArg arg, eva_ctxt = ctxt' } + EValArg { ea_arg = arg, ea_ctxt = ctxt' } -> rebuild_hs_apps (HsApp noExtField lfun arg) ctxt' args - ETypeArg { eva_hs_ty = hs_ty, eva_ty = ty, eva_ctxt = ctxt' } + ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_ctxt = ctxt' } -> rebuild_hs_apps (HsAppType ty lfun hs_ty) ctxt' args EPrag ctxt' p -> rebuild_hs_apps (HsPragE noExtField p lfun) ctxt' args @@ -736,12 +745,12 @@ isHsValArg :: HsExprArg id -> Bool isHsValArg (EValArg {}) = True isHsValArg _ = False -leadingValArgs :: [HsExprArg id] -> [EValArg id] -leadingValArgs [] = [] -leadingValArgs (arg@(EValArg {}) : args) = eva_arg arg : leadingValArgs args -leadingValArgs (EWrap {} : args) = leadingValArgs args -leadingValArgs (EPrag {} : args) = leadingValArgs args -leadingValArgs (ETypeArg {} : _) = [] +leadingValArgs :: [HsExprArg 'TcpRn] -> [LHsExpr GhcRn] +leadingValArgs [] = [] +leadingValArgs (EValArg { ea_arg = arg } : args) = arg : leadingValArgs args +leadingValArgs (EWrap {} : args) = leadingValArgs args +leadingValArgs (EPrag {} : args) = leadingValArgs args +leadingValArgs (ETypeArg {} : _) = [] isValArg :: HsExprArg id -> Bool isValArg (EValArg {}) = True @@ -753,24 +762,22 @@ isVisibleArg (ETypeArg {}) = True isVisibleArg _ = False instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where - ppr (EValArg { eva_arg = arg }) = text "EValArg" <+> ppr arg + ppr (EValArg { ea_arg = arg }) = text "EValArg" <+> ppr arg ppr (EPrag _ p) = text "EPrag" <+> ppr p - ppr (ETypeArg { eva_hs_ty = hs_ty }) = char '@' <> ppr hs_ty + ppr (ETypeArg { ea_hs_ty = hs_ty }) = char '@' <> ppr hs_ty ppr (EWrap wrap) = ppr wrap + ppr (EValArgQL { eaql_head = fun, eaql_args = args, eaql_res_rho = ty}) + = hang (text "EValArgQL" <+> ppr fun) + 2 (vcat [ ppr args, text "ea_ql_ty:" <+> ppr ty ]) + instance Outputable EWrap where ppr (EPar _) = text "EPar" ppr (EHsWrap w) = text "EHsWrap" <+> ppr w ppr (EExpand orig) = text "EExpand" <+> ppr orig -instance OutputableBndrId (XPass p) => Outputable (EValArg p) where - ppr (ValArg e) = ppr e - ppr (ValArgQL { va_fun = fun, va_args = args, va_ty = ty}) - = hang (text "ValArgQL" <+> ppr fun) - 2 (vcat [ ppr args, text "va_ty:" <+> ppr ty ]) - pprHsExprArgTc :: HsExprArg 'TcpInst -> SDoc -pprHsExprArgTc (EValArg { eva_arg = tm, eva_arg_ty = ty }) +pprHsExprArgTc (EValArg { ea_arg = tm, ea_arg_ty = ty }) = text "EValArg" <+> hang (ppr tm) 2 (dcolon <+> ppr ty) pprHsExprArgTc arg = ppr arg @@ -1514,7 +1521,7 @@ naughtiness in both branches. c.f. GHC.Tc.TyCl.Utils.mkRecSelBinds. * * ********************************************************************* -} -addFunResCtxt :: HsExpr GhcRn -> [HsExprArg 'TcpRn] +addFunResCtxt :: HsExpr GhcRn -> [HsExprArg p] -> TcType -> ExpRhoType -> TcM a -> TcM a -- When we have a mis-match in the return type of a function ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -361,12 +361,14 @@ tcDoStmts doExpr@(DoExpr _) ss@(L l stmts) res_ty ; return (HsDo res_ty doExpr (L l stmts')) } else do { expanded_expr <- expandDoStmts doExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty } + ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> + tcExpr (unLoc expanded_expr) res_ty } } tcDoStmts mDoExpr@(MDoExpr _) ss@(L _ stmts) res_ty = do { expanded_expr <- expandDoStmts mDoExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty } + ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> + tcExpr (unLoc expanded_expr) res_ty } tcDoStmts MonadComp (L l stmts) res_ty = do { stmts' <- tcStmts (HsDoStmt MonadComp) tcMcStmt stmts res_ty ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -80,7 +80,7 @@ module GHC.Tc.Utils.TcMType ( defaultTyVar, promoteMetaTyVarTo, promoteTyVarSet, quantifyTyVars, isQuantifiableTv, zonkAndSkolemise, skolemiseQuantifiedTyVar, - doNotQuantifyTyVars, + doNotQuantifyTyVars, demoteQLDelta, candidateQTyVarsOfType, candidateQTyVarsOfKind, candidateQTyVarsOfTypes, candidateQTyVarsOfKinds, @@ -2443,6 +2443,37 @@ promoteTyVarSet tvs -- Non-determinism is OK because order of promotion doesn't matter ; return (or bools) } +demoteDeltaTyVarTo :: TcLevel -> TcTyVar -> TcM () +demoteDeltaTyVarTo tclvl tv + | MetaTv { mtv_ref = ref, mtv_tclvl = tv_lvl } <- tcTyVarDetails tv + = assertPpr (tclvl `strictlyDeeperThan` tcTyVarLevel tv) (ppr tclvl <+> ppr tv) $ + do { info <- readTcRef ref + ; case info of { + Indirect {} -> return () ; + Flexi -> + do { cloned_tv <- cloneMetaTyVar tv + ; let rhs_tv = setMetaTyVarTcLevel cloned_tv tclvl + ; liftZonkM $ writeTcRef ref (Indirect (TyVarTy rhs_tv)) + -- Do not go via writeMetaTyVar! + ; traceTc "demoteTyVar" (ppr tv <+> text "-->" <+> ppr rhs_tv) + ; return () } } } + | otherwise + = pprPanic "demoteDeltaTyVarTo" (ppr tv) + +demoteQLDelta :: TcTyVarSet -> TcM () +demoteQLDelta delta + | null tvs + = return () + | otherwise + = do { tclvl <- getTcLevel + ; assertPpr (isMetaTyVar tv1) (ppr delta) $ + when (tclvl `strictlyDeeperThan` tcTyVarLevel tv1) $ + mapM_ (demoteDeltaTyVarTo tclvl) tvs } + where + tv1 = head tvs + tvs = nonDetEltsUniqSet delta + -- Non-determinism is OK because order of promotion doesn't matter + {- %************************************************************************ %* * ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1332,15 +1332,17 @@ tcSubType orig ctxt ty_actual ty_expected --------------- tcSubTypeDS :: HsExpr GhcRn - -> TcRhoType -- Actual -- a rho-type not a sigma-type - -> ExpRhoType -- Expected + -> TcRhoType -- Actual type -- a rho-type not a sigma-type + -> ExpRhoType -- Expected type + -- DeepSubsumption <=> when checking, this type + -- is deeply skolemised -> TcM HsWrapper -- Similar signature to unifyExpectedType; does deep subsumption -- Only one call site, in GHC.Tc.Gen.App.tcApp tcSubTypeDS rn_expr act_rho res_ty = case res_ty of - Check exp_rho -> tc_sub_type_ds Deep (unifyType m_thing) orig - GenSigCtxt act_rho exp_rho + Check exp_rho -> tc_sub_type_deep (unifyType m_thing) orig + GenSigCtxt act_rho exp_rho Infer inf_res -> do { co <- fillInferResult act_rho inf_res ; return (mkWpCastN co) } @@ -1485,18 +1487,24 @@ tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected , text "ty_expected =" <+> ppr ty_expected ] ; (sk_wrap, inner_wrap) - <- case ds_flag of - Shallow -> -- Shallow: skolemise, instantiate and unify - tcSkolemise Shallow ctxt ty_expected $ \sk_rho -> - do { (wrap, rho_a) <- topInstantiate inst_orig ty_actual - ; cow <- unify rho_a sk_rho - ; return (mkWpCastN cow <.> wrap) } - Deep -> -- Deep: we have co/contra work to do - tcSkolemise Deep ctxt ty_expected $ \sk_rho -> - tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho + <- tcSkolemise ds_flag ctxt ty_expected $ \sk_rho -> + case ds_flag of + Deep -> tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho + Shallow -> tc_sub_type_shallow unify inst_orig ty_actual sk_rho ; return (sk_wrap <.> inner_wrap) } +---------------------- +tc_sub_type_shallow :: (TcType -> TcType -> TcM TcCoercionN) + -> CtOrigin + -> TcSigmaType + -> TcRhoType -- Skolemised (shallow-ly) + -> TcM HsWrapper +tc_sub_type_shallow unify inst_orig ty_actual sk_rho + = do { (wrap, rho_a) <- topInstantiate inst_orig ty_actual + ; cow <- unify rho_a sk_rho + ; return (mkWpCastN cow <.> wrap) } + ---------------------- definitely_mono :: DeepSubsumptionFlag -> TcType -> Bool definitely_mono ds_flag ty @@ -1734,7 +1742,8 @@ tc_sub_type_deep :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify -- Precondition: ty_expected is deeply skolemised tc_sub_type_deep unify inst_orig ctxt ty_actual ty_expected - = do { traceTc "tc_sub_type_deep" $ + = assertPpr (isDeepRhoTy ty_expected) (ppr ty_expected) $ + do { traceTc "tc_sub_type_deep" $ vcat [ text "ty_actual =" <+> ppr ty_actual , text "ty_expected =" <+> ppr ty_expected ] ; go ty_actual ty_expected } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18712afb58bb9eb6da2f429253c1c0fa99181ea2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18712afb58bb9eb6da2f429253c1c0fa99181ea2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 13:08:56 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Wed, 24 Apr 2024 09:08:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sand-witch/fix-tuple-renaminb Message-ID: <662904687e00f_2d9bf1d550e81879b@gitlab.mail> Andrei Borzenkov pushed new branch wip/sand-witch/fix-tuple-renaminb at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sand-witch/fix-tuple-renaminb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 13:11:49 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Wed, 24 Apr 2024 09:11:49 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/fix-tuple-renaminb] Fix tuple puns renaming (24702) Message-ID: <662905152e2dc_2d9bf1da02c8189bf@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/fix-tuple-renaminb at Glasgow Haskell Compiler / GHC Commits: cc31faba by Andrei Borzenkov at 2024-04-24T17:11:27+04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 7 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (64 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc31fabafd674ee83699be214175ae066718786b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc31fabafd674ee83699be214175ae066718786b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 13:45:37 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 24 Apr 2024 09:45:37 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] STM: Be more optimistic when validating in-flight transactions. Message-ID: <66290d0115da5_2d9bf11337bf03291f@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: 6ec9b439 by Andreas Klebinger at 2024-04-24T15:30:44+02:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 8 changed files: - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T Changes: ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/STM.c ===================================== @@ -359,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -681,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -751,7 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } - // TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -941,17 +981,185 @@ void stmCondemnTransaction(Capability *cap, TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -// Check if a transaction is known to be invalid by this point. -// Currently we use this to: -// * Eagerly abort invalid transactions from the scheduler. -// * If an exception occured inside a transaction, decide weither or not to -// abort by checking if the transaction was valid. -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +To "validate" a transaction means to check that the transaction's log (Trec) is +consistent with the current state of memory; specifically, that any variable +observed (through reads AND writes) by the transaction has the same value in +memory as it did when the transaction read it. + +In some situations we can give ourself some leeway by allowing: +* False positives - The validation check claims the memory state is consistent when it isn't. +* False negatives - The validation check claims memory state is inconsistent when it + is in fact consistent. + +We validate a STM transaction for two purposes: + +(A) Post-run validation runs /after/ the transaction has completed, either during + commit or after an exception has occurred. + + This is done by validate_and_acquire_ownership. The commit process + /absolutely must/ be transactional: that is, it must read a consistent + snapshot of memory, compare with the log, and then atomically commit all the + writes in the log. We do this by locking the TVars. + + For post-run validation we must *never* allow false-positives for correctness + reasons. But we allow for false-negatives, trading occasional spurious retries + for performance in the average case. + + The implementation of performing this update atomically is mostly based on + the 2002 paper "A Practical Multi-Word Compare-and-Swap Operation" + +(B) In-flight validation runs /during/ the execution of the transaction. Suppose a transaction + is long-running, and memory has /already/ changed so that it is inconsistent with the + transaction's log. It is just conceivable that memory might change back again to be + consistent, but very unlikely. It is better to terminate and retry the transaction, + rather than let it run potentially forever as a zombie, and only retry when it attempts to commit. + + This is done by validate_trec_optimistic. Since in-flight validation at most results in early + termination of a transaction we may accept both + * a "false negative" (causing the transaction to retry unnecessarily), and + * a "false positive" (allowing the transaction to continue as a zombie). + + We want to run in-flight validation somewhat frequently to detect invalid + transactions early. We perform in-flight validation whenever a thread returns to + the scheduler, a convenient and regular opportunity. + +Note that in-flight validation is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +As noted above, post-run validation and commit /must/ be transactional, involving expensive locking. +But in-flight validation can accept false positives and false negatives. While we could lock TVars +during in-flight validation to rule out false positives, we don't have to: +it is much cheaper and very nearly as good simply to read them without locking allowing for +false-postive results. + +Moreover, locking during in-flight validation can cause lack of progress, or livelock (#24446) +through false-negative results. Suppose we have two long-running transactions, each doing successive +in-flight validation using locking. If the validation discovers a locked TVar it aborts and retries. +Now they can each abort the other, forever. +This *can* also happen with post-run validation. But since post-run validation occurs less +frequently it's incredibly unlikely to happen repeatedly compared to in-flight validation. + +Hence: locking during in-flight validation is + * Expensive + * Can lead to livelock-like conditions. + +Conclusion: + * don't use locking during in-flight validation. + * Use locking during post-run validation, where the risk of livelock is comparatively small + compared to the cost of ruling out live-lock completely. + +See below for other design alternatives. + +Design considerations about locking during in flight validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All else being equal we would always want to get a precise result for validation. +And indeed for the non-threaded runtime this is reasonably easy to achieve +(see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult, and ruling out false negatives/positives +would come at significant cost in the average case. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we use for post-run validation. +The trade off being that it can lead to false negatives during validation when multiple +threads perform validation in parallel. As long as the false-negative rate is +is reasonably low this is not problematic. + +However in-flight validation can happen multiple times per transaction. +So even a fairly low rate of spurious validation failures will result in a large +performance hit. In the worst case preventing progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve in-flight validation perf by allowing false positives. +This removes the need for tacking locks which means: + +Benefits +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. +The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. So we accept this behaviour. + +Design alternatives to improve in-flight false-postive rate: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + +A1: +Take locks for in-flight validation but don't fail if in-flight validation +encounters already locked tvars. +This would solve lock contention/false positives caused by concurrent in-flight validations. + +But it would still result in in-flight validation causing some false-negatives +during post-run validation by holding locks post-run validation is trying to take. + +It also doesn't *guaranteed* that we recognize looping transaction as invalid. +As the relevant tvars might be locked by other validations when we try to lock +them. So while this would improve over using regular lock tacking for in-flight +transactions it seems straight up worse than not taking locks to me in most +situations. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +locked tvars we encountered, as these are the only sources of false-positives. +This would give a hard upper bound on the number of false-positives while keeping +the impact on post-run validations lower. + +If the looping transaction issue turns out to be a real problem this might be worth +doing. + +A3: +When locking a tvar for a potential update keep the old value accessible. Then +in-flight validations should never return false-positives. However compared to A2 +this seems like it would come with a non-trivial overhead relative to the likelyhood +of these false-positives causing actual issues. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || @@ -960,8 +1168,13 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { t = trec; StgBool result = true; while (t != NO_TREC) { - // TODO: I don't think there is a need to lock any tvars here, all even less so. - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -972,7 +1185,6 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { ===================================== rts/STM.h ===================================== @@ -20,7 +20,7 @@ non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -84,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -110,7 +117,7 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in ===================================== rts/Schedule.c ===================================== @@ -1106,7 +1106,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,6 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [when(unregisterised(), skip), req_ghc_with_threaded_rts], compile_and_run, ['-threaded -with-rtsopts "-N2"']) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ec9b439b8e34c798a06541c877bba9772907131 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ec9b439b8e34c798a06541c877bba9772907131 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 13:55:14 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 24 Apr 2024 09:55:14 -0400 Subject: [Git][ghc/ghc][wip/T24676] Wibble Message-ID: <66290f42ab402_2d9bf1152438c351b9@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: b63ef509 by Simon Peyton Jones at 2024-04-24T15:54:51+02:00 Wibble - - - - - 1 changed file: - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -2444,15 +2444,15 @@ promoteTyVarSet tvs ; return (or bools) } demoteDeltaTyVarTo :: TcLevel -> TcTyVar -> TcM () -demoteDeltaTyVarTo tclvl tv +demoteDeltaTyVarTo new_lvl tv | MetaTv { mtv_ref = ref, mtv_tclvl = tv_lvl } <- tcTyVarDetails tv - = assertPpr (tclvl `strictlyDeeperThan` tcTyVarLevel tv) (ppr tclvl <+> ppr tv) $ + = assertPpr (new_lvl `strictlyDeeperThan` tv_lvl) (ppr new_lvl <+> ppr tv) $ do { info <- readTcRef ref ; case info of { Indirect {} -> return () ; Flexi -> do { cloned_tv <- cloneMetaTyVar tv - ; let rhs_tv = setMetaTyVarTcLevel cloned_tv tclvl + ; let rhs_tv = setMetaTyVarTcLevel cloned_tv new_lvl ; liftZonkM $ writeTcRef ref (Indirect (TyVarTy rhs_tv)) -- Do not go via writeMetaTyVar! ; traceTc "demoteTyVar" (ppr tv <+> text "-->" <+> ppr rhs_tv) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b63ef5098ca341bff9484193f18085d7dd731540 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b63ef5098ca341bff9484193f18085d7dd731540 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 14:50:48 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 10:50:48 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/clyring/9.10.1-release-notes-cleanup Message-ID: <66291c48acea6_2d9bf11e501185283c@gitlab.mail> Ben Gamari deleted branch wip/clyring/9.10.1-release-notes-cleanup at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 14:50:52 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 10:50:52 -0400 Subject: [Git][ghc/ghc][ghc-9.10] 2 commits: Add release notes entry for GHC proposal 575 Message-ID: <66291c4cc81f5_2d9bf11e8778053032@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: b9b3b007 by Matthew Craven at 2024-04-15T10:57:59-04:00 Add release notes entry for GHC proposal 575 - - - - - 26b6c7fd by Matthew Craven at 2024-04-15T10:59:17-04:00 Users' guide: Fix base-ref links containing symbols - - - - - 2 changed files: - docs/users_guide/9.10.1-notes.rst - docs/users_guide/conf.py Changes: ===================================== docs/users_guide/9.10.1-notes.rst ===================================== @@ -28,6 +28,12 @@ Language compatible, and future releases of GHC may change the default, it is highly recommended to specify the language edition explicitly. +- GHC Proposal `#575 `_ + has been implemented, allowing ``DEPRECATED`` and ``WARNING`` + pragmas to be applied to class ``instance`` declarations. + Doing so will cause warnings to be emitted whenever such instances are used + to solve a constraint. For details, see :ref:`warning-deprecated-pragma`. + - GHC Proposal `#281 `_ "Visible forall in types of terms" has been partially implemented. The following code is now accepted by GHC:: ===================================== docs/users_guide/conf.py ===================================== @@ -237,6 +237,15 @@ def haddock_role(lib): parts = text.split('.') module_parts = parts[:-1] thing = parts[-1] + + # Escape any symbols in the identifier; + # see also Haddock.Utils.makeAnchorId + def escapeChar(c): + if (c in ':_.') or (c.isascii() and c.isalnum()): + return c + return '-%d-' % ord(c) + thing = ''.join(escapeChar(c) for c in thing) + if thing != '': # reference to type or identifier tag = 't' if thing[0].isupper() else 'v' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b63186da9de818963c40ecb27848d3eb4722513...26b6c7fdaf0ac6c5c68d76922c2339d0cfec6c6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b63186da9de818963c40ecb27848d3eb4722513...26b6c7fdaf0ac6c5c68d76922c2339d0cfec6c6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 15:00:46 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 11:00:46 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.10-backports-1] 8 commits: Add release notes entry for GHC proposal 575 Message-ID: <66291e9e85369_2d9bf120215646296b@gitlab.mail> Ben Gamari pushed to branch wip/az/ghc-9.10-backports-1 at Glasgow Haskell Compiler / GHC Commits: b9b3b007 by Matthew Craven at 2024-04-15T10:57:59-04:00 Add release notes entry for GHC proposal 575 - - - - - 26b6c7fd by Matthew Craven at 2024-04-15T10:59:17-04:00 Users' guide: Fix base-ref links containing symbols - - - - - dfd0e1c6 by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - 31174204 by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 (cherry picked from commit f07015858fd79dca41983dbf3a249dfecd8d2eea) - - - - - c06ebd5f by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 (cherry picked from commit c90c60390aa3949b400f26ee0534273c56e19005) - - - - - b07bbb46 by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 (cherry picked from commit 26036f96919b1a8b99715dd99724163012c719fc) - - - - - 51d5ff25 by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 (cherry picked from commit 2f8e3a254a20f4573aec26fc85ab74b51d661472) - - - - - 8a99d663 by Alan Zimmerman at 2024-04-24T15:00:11+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. (cherry picked from commit 00d3ecf0775c1a3f1ab8495e5e125f21d450394e) - - - - - 30 changed files: - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - docs/users_guide/9.10.1-notes.rst - docs/users_guide/conf.py - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/parser/should_compile/T23315/T23315.stderr - testsuite/tests/printer/AnnotationNoListTuplePuns.hs - + testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/printer/T18791.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9f509a09f60707024cac6557f2b07c2e06bd9b23...8a99d6635cc1035f5dd21b086a6ba6234d4d3e49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9f509a09f60707024cac6557f2b07c2e06bd9b23...8a99d6635cc1035f5dd21b086a6ba6234d4d3e49 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 15:02:20 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 11:02:20 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 14 commits: Add release notes entry for GHC proposal 575 Message-ID: <66291efc404cd_2d9bf12154008633b9@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: b9b3b007 by Matthew Craven at 2024-04-15T10:57:59-04:00 Add release notes entry for GHC proposal 575 - - - - - 26b6c7fd by Matthew Craven at 2024-04-15T10:59:17-04:00 Users' guide: Fix base-ref links containing symbols - - - - - f15a854e by Alan Zimmerman at 2024-04-21T09:59:45+01:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - c8d25501 by Alan Zimmerman at 2024-04-21T10:41:35+01:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 (cherry picked from commit f07015858fd79dca41983dbf3a249dfecd8d2eea) - - - - - 7d6ae7aa by Alan Zimmerman at 2024-04-21T11:39:48+01:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 (cherry picked from commit c90c60390aa3949b400f26ee0534273c56e19005) - - - - - 64013156 by Alan Zimmerman at 2024-04-21T12:43:22+01:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 (cherry picked from commit 26036f96919b1a8b99715dd99724163012c719fc) - - - - - 898fcbd2 by Alan Zimmerman at 2024-04-21T13:49:41+01:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 (cherry picked from commit 2f8e3a254a20f4573aec26fc85ab74b51d661472) - - - - - 9f509a09 by Alan Zimmerman at 2024-04-21T15:32:17+01:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. (cherry picked from commit 00d3ecf0775c1a3f1ab8495e5e125f21d450394e) - - - - - 45cc3064 by Ben Gamari at 2024-04-24T11:00:59-04:00 Merge remote-tracking branch 'origin/wip/az/ghc-9.10-backports-1' into HEAD - - - - - d9cd4bde by Ben Gamari at 2024-04-24T11:01:34-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. (cherry picked from commit 55eb8c98895308d2dd025f7bd64c0b80fce6ace3) - - - - - b8f9880c by Zubin Duggal at 2024-04-24T11:01:34-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. (cherry picked from commit a933aff37992ea311a60be878379e7abf650e9fb) - - - - - 6d6c2640 by Ben Gamari at 2024-04-24T11:01:37-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. (cherry picked from commit d7a3d6b5ee5e0c16af295579da3c54d8f0c37a05) - - - - - 88e31848 by Teo Camarasu at 2024-04-24T11:01:37-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 (cherry picked from commit f30e4984fb048818051465698ef8e4e20dacb577) - - - - - 1261ec2f by Simon Peyton Jones at 2024-04-24T11:01:37-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] (cherry picked from commit 9d38bfa0c0f910208822579acaa999f87c2f8c65) - - - - - 30 changed files: - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - docs/index.html.in - docs/users_guide/9.10.1-notes.rst - docs/users_guide/conf.py - hadrian/src/Rules/Generate.hs - libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs - libraries/ghc-internal/src/GHC/Internal/List.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/667cb76bf9faf9974ee1ac0b544f588506bf9289...1261ec2fc0db926357c9d5dbbc0a69a621902694 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/667cb76bf9faf9974ee1ac0b544f588506bf9289...1261ec2fc0db926357c9d5dbbc0a69a621902694 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 15:13:07 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 24 Apr 2024 11:13:07 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: driver: force merge objects when building dynamic objects Message-ID: <6629218384dfa_2e63201865b4102175@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - 70967189 by Cheng Shao at 2024-04-24T11:11:33-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 42959129 by Cheng Shao at 2024-04-24T11:11:33-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 07de0186 by Cheng Shao at 2024-04-24T11:11:33-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 40f4d343 by Cheng Shao at 2024-04-24T11:11:33-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - 03c13f34 by Sylvain Henry at 2024-04-24T11:11:45-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 10 changed files: - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/StgToJS/Literal.hs - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln Changes: ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -1040,13 +1040,22 @@ this is accomplished with the `ld -r` command. We rely on this for two ends: The command used for object linking is set using the -pgmlm and -optlm command-line options. -Sadly, the LLD linker that we use on Windows does not support the `-r` flag -needed to support object merging (see #21068). For this reason on Windows we do -not support GHCi objects. To deal with foreign stubs we build a static archive -of all of a module's object files instead merging them. Consequently, we can -end up producing `.o` files which are in fact static archives. However, -toolchains generally don't have a problem with this as they use file headers, -not the filename, to determine the nature of inputs. +However, `ld -r` is broken in some cases: + + * The LLD linker that we use on Windows does not support the `-r` + flag needed to support object merging (see #21068). For this reason + on Windows we do not support GHCi objects. + * `wasm-ld -r` is prohibitively slow, especially when handling large + input objects (e.g. profiled objects). + +In these cases, we bundle a module's own object file with its foreign +stub's object file, instead of merging them. Consequently, we can end +up producing `.o` files which are in fact static archives. This can +only work if `ar -L` is supported, so the archive `.o` files can be +properly added to the final static library. We must also take care not +to produce archive `.dyn_o` when building dynamic objects, otherwise +we end up with broken `.so` files when GHC is built with `llvm-ar` +(#22210). Note that this has somewhat non-obvious consequences when producing initializers and finalizers. See Note [Initializers and finalizers in Cmm] @@ -1072,7 +1081,7 @@ via gcc. -- | See Note [Object merging]. joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO () joinObjectFiles hsc_env o_files output_fn - | can_merge_objs && not dashLSupported = do + | can_merge_objs && (not dashLSupported || is_dyn) = do let toolSettings' = toolSettings dflags ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings' ld_r args = GHC.SysTools.runMergeObjects (hsc_logger hsc_env) (hsc_tmpfs hsc_env) (hsc_dflags hsc_env) ( @@ -1100,6 +1109,7 @@ joinObjectFiles hsc_env o_files output_fn withAtomicRename output_fn $ \tmp_ar -> liftIO $ runAr logger dflags Nothing $ map Option $ ["qc" ++ dashL, tmp_ar] ++ o_files where + is_dyn = ways dflags `hasWay` WayDyn dashLSupported = sArSupportsDashL (settings dflags) dashL = if dashLSupported then "L" else "" can_merge_objs = isJust (pgm_lm (hsc_dflags hsc_env)) ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] ===================================== configure.ac ===================================== @@ -97,11 +97,11 @@ dnl use either is considered a Feature. dnl ** What command to use to compile compiler sources ? dnl -------------------------------------------------------------- -AC_ARG_VAR(GHC,[Use as the full path to GHC. [default=autodetect]]) -AC_PATH_PROG([GHC], [ghc]) +AC_ARG_VAR(GHC,[Use as the bootstrap GHC. [default=autodetect]]) +AC_CHECK_PROG([GHC], [ghc], [ghc]) AC_ARG_WITH([ghc], - AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the full path to ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), - AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' or 'GHC=$withval ./configure' instead)])) + AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the bootstrap ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), + AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' instead)])) AC_SUBST(WithGhc,$GHC) AC_ARG_ENABLE(bootstrap-with-devel-snapshot, @@ -740,10 +740,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -184,7 +181,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -443,7 +439,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -511,15 +506,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -31,6 +31,7 @@ import qualified Distribution.PackageDescription.Parsec as C import qualified Distribution.Simple.Compiler as C import qualified Distribution.Simple.Program.Db as C import qualified Distribution.Simple as C +import qualified Distribution.Simple.GHC as GHC import qualified Distribution.Simple.Program.Builtin as C import qualified Distribution.Simple.Utils as C import qualified Distribution.Simple.Program.Types as C @@ -363,12 +364,11 @@ registerPackage rs context = do need [setupConfig] -- This triggers 'configurePackage' pd <- packageDescription <$> readContextData context db_path <- packageDbPath (PackageDbLoc (stage context) (iplace context)) - dist_dir <- Context.buildPath context pid <- pkgUnitId (stage context) (package context) -- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path -- from the local build info @lbi at . lbi <- liftIO $ C.getPersistBuildConfig cPath - liftIO $ register db_path pid dist_dir pd lbi + liftIO $ register db_path pid pd lbi -- Then after the register, which just writes the .conf file, do the recache step. buildWithResources rs $ target context (GhcPkg Recache (stage context)) [] [] @@ -377,25 +377,23 @@ registerPackage rs context = do -- into a different package database to the one it was configured against. register :: FilePath -> String -- ^ Package Identifier - -> FilePath -> C.PackageDescription -> LocalBuildInfo -> IO () -register pkg_db pid build_dir pd lbi +register pkg_db pid pd lbi = withLibLBI pd lbi $ \lib clbi -> do - absPackageDBs <- C.absolutePackageDBPaths packageDbs - installedPkgInfo <- C.generateRegistrationInfo - C.silent pd lib lbi clbi False reloc build_dir - (C.registrationPackageDB absPackageDBs) - + when reloc $ error "register does not support reloc" + installedPkgInfo <- generateRegistrationInfo pd lbi lib clbi writeRegistrationFile installedPkgInfo where regFile = pkg_db pid <.> "conf" reloc = relocatable lbi - -- Using a specific package db here is why we have to copy the function from Cabal. - packageDbs = [C.SpecificPackageDB pkg_db] + + generateRegistrationInfo pkg lbi lib clbi = do + abi_hash <- C.mkAbiHash <$> GHC.libAbiHash C.silent pkg lbi lib clbi + return (C.absoluteInstalledPackageInfo pkg abi_hash lib lbi clbi) writeRegistrationFile installedPkgInfo = do writeUTF8File regFile (CP.showInstalledPackageInfo installedPkgInfo) ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d1b92a396fd4201d34d0d7dbe74c3d5dd86ff1fa...03c13f343554e7c51d80cb8e6ee7519a4bcc7ef8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d1b92a396fd4201d34d0d7dbe74c3d5dd86ff1fa...03c13f343554e7c51d80cb8e6ee7519a4bcc7ef8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 21:27:03 2024 From: gitlab at gitlab.haskell.org (Bodigrim (@Bodigrim)) Date: Wed, 24 Apr 2024 17:27:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/setenv-is-not-thread-safe Message-ID: <66297927b6f12_3cf69b1514798601d2@gitlab.mail> Bodigrim pushed new branch wip/setenv-is-not-thread-safe at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/setenv-is-not-thread-safe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 24 22:39:42 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 24 Apr 2024 18:39:42 -0400 Subject: [Git][ghc/ghc][wip/T24676] Wibbles Message-ID: <66298a2e53b9c_3cf69b1caa3186351c@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: 0a4233b3 by Simon Peyton Jones at 2024-04-25T00:39:22+02:00 Wibbles - - - - - 2 changed files: - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -320,8 +320,7 @@ before tcValArgs. -} tcApp :: HsExpr GhcRn - -> ExpRhoType -- DeepSubsumption <=> when checking, this type - -- is deeply skolemised + -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised -> TcM (HsExpr GhcTc) -- See Note [tcApp: typechecking applications] tcApp rn_expr exp_res_ty @@ -348,11 +347,11 @@ tcApp rn_expr exp_res_ty finishApp :: Bool -> HsExpr GhcRn -> (HsExpr GhcRn, AppCtxt) -> HsExpr GhcTc -> [HsExprArg 'TcpInst] - -> TcRhoType - -> ExpRhoType + -> TcSigmaType + -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised -> TcM (HsExpr GhcTc) finishApp do_ql rn_expr (rn_fun, fun_ctxt) tc_fun inst_args app_res_rho exp_res_ty - = do { do_ds <- xoptM LangExt.DeepSubsumption + = do { ds_flag <- getDeepSubsumptionFlag -- Unify with expected type from the context -- See Note [Unify with expected type before typechecking arguments] @@ -360,15 +359,15 @@ finishApp do_ql rn_expr (rn_fun, fun_ctxt) tc_fun inst_args app_res_rho exp_res_ -- Match up app_res_rho: the result type of rn_expr -- with exp_res_ty: the expected result type ; res_wrap <- perhaps_add_res_ty_ctxt $ - if not do_ds - then -- No deep subsumption + case ds_flag of + Shallow -> -- No deep subsumption -- app_res_rho and exp_res_ty are both rho-types, -- so with simple subsumption we can just unify them -- No need to zonk; the unifier does that do { co <- unifyExpectedType rn_expr app_res_rho exp_res_ty ; return (mkWpCastN co) } - else -- Deep subsumption + Deep -> -- Deep subsumption -- Even though both app_res_rho and exp_res_ty are rho-types, -- they may have nested polymorphism, so if deep subsumption -- is on we must call tcSubType. @@ -502,36 +501,36 @@ tcValArg do_ql (EValArgQL { eaql_ctxt = ctxt do { arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty ; traceTc "tcEValArgQL {" (vcat [ ppr rn_head , text "mb_delta:" <+> ppr mb_delta - , text "app_res_rho:" <+> ppr res_rho + , text "res_rho:" <+> ppr res_rho , text "arg_ty:" <+> ppr arg_ty , text "args:" <+> ppr inst_args ]) - ; arg' <- tcScalingUsage mult $ - do_skolemise arg_ty $ \arg_rho -> - finishApp do_ql rn_expr rn_head tc_fun inst_args res_rho - (Check arg_rho) + ; ds_flag <- getDeepSubsumptionFlag + ; (wrap, arg') + <- tcScalingUsage mult $ + tcSkolemise ds_flag GenSigCtxt arg_ty $ \ arg_rho -> + -- Tricky point: with deep subsumption, even if mb_delta is Nothing + -- arg_ty will be a rho-type (no top-level foralls), but it may have + -- /nested/ foralls; so we should deeply skolemise it, in order to + -- pass a deeply-skolemised type to finishApp + -- Example from haskeline:System.Console.Haskeline.Backend.Terminfo + -- output $ blah + -- output :: TermAction -> ActionM () + -- type ActionM a = forall m . (..) => ActionT (Draw m) a + do { case mb_delta of + Nothing -> return () + Just (delta, wanted) -> do { demoteQLDelta delta + ; emitConstraints wanted } + ; finishApp do_ql rn_expr rn_head tc_fun inst_args res_rho + (Check arg_rho) } + ; traceTc "tcEValArgQL }" $ vcat [ text "rn_head:" <+> ppr rn_head , text "res_rho:" <+> ppr res_rho ] ; return (EValArg { ea_ctxt = ctxt - , ea_arg = L arg_loc arg' + , ea_arg = L arg_loc (mkHsWrap wrap arg') , ea_arg_ty = Scaled mult arg_ty }) } - where - do_skolemise arg_ty thing_inside = case mb_delta of - Nothing -> thing_inside arg_ty - Just (delta, wanted) - -> do { ds_flag <- getDeepSubsumptionFlag - ; lvl1 <- getTcLevel - ; (wrap, arg') <- tcSkolemise ds_flag GenSigCtxt arg_ty $ \ arg_rho -> - do { demoteQLDelta delta - ; emitConstraints wanted - ; lvl2 <- getTcLevel - ; traceTc "EVQL 2" (vcat [ ppr lvl1 <+> ppr lvl2 - , ppr arg_ty, ppr arg_rho ]) - ; thing_inside arg_rho } - ; return (mkHsWrap wrap arg') } - {- ********************************************************************* * * @@ -1527,7 +1526,7 @@ isGuardedTy (Scaled _ ty) | otherwise = False quickLookArg1 :: Bool -> Delta -> AppCtxt -> LHsExpr GhcRn - -> Scaled TcRhoType + -> Scaled TcRhoType -- Not deeply skolemised, even with -XDeepSubsumption -> TcM (Delta, HsExprArg 'TcpInst) -- quickLookArg1 implements the "QL Argument" judgement in Fig 5 of the paper quickLookArg1 guarded delta ctxt larg@(L _ arg) sc_arg_ty@(Scaled _ arg_ty) ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -19,7 +19,7 @@ module GHC.Tc.Utils.Unify ( buildImplicationFor, buildTvImplication, emitResidualTvConstraint, -- Skolemisation - DeepSubsumptionFlag(..), getDeepSubsumptionFlag, + DeepSubsumptionFlag(..), getDeepSubsumptionFlag, isRhoTyDS, tcSkolemise, tcSkolemiseCompleteSig, tcSkolemiseExpectedType, -- Various unifications @@ -402,7 +402,7 @@ tcSkolemiseGeneral -> ([(Name, TcInvisTVBinder)] -> TcType -> TcM result) -> TcM (HsWrapper, result) tcSkolemiseGeneral ds_flag ctxt top_ty expected_ty thing_inside - | definitely_mono ds_flag expected_ty + | isRhoTyDS ds_flag expected_ty -- Fast path for a very very common case: no skolemisation to do -- But still call checkConstraints in case we need an implication regardless = do { let sig_skol = SigSkol ctxt top_ty [] @@ -1474,7 +1474,7 @@ tc_sub_type_ds :: DeepSubsumptionFlag -- It takes an explicit DeepSubsumptionFlag tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected | definitely_poly ty_expected -- See Note [Don't skolemise unnecessarily] - , definitely_mono ds_flag ty_actual + , isRhoTyDS ds_flag ty_actual = do { traceTc "tc_sub_type (drop to equality)" $ vcat [ text "ty_actual =" <+> ppr ty_actual , text "ty_expected =" <+> ppr ty_expected ] @@ -1506,12 +1506,6 @@ tc_sub_type_shallow unify inst_orig ty_actual sk_rho ; return (mkWpCastN cow <.> wrap) } ---------------------- -definitely_mono :: DeepSubsumptionFlag -> TcType -> Bool -definitely_mono ds_flag ty - = case ds_flag of - Shallow -> isRhoTy ty -- isRhoTy: no top level forall or (=>) - Deep -> isDeepRhoTy ty -- "deep" version: no nested forall or (=>) - definitely_poly :: TcType -> Bool -- A very conservative test: -- see Note [Don't skolemise unnecessarily] @@ -1729,7 +1723,8 @@ getDeepSubsumptionFlag :: TcM DeepSubsumptionFlag getDeepSubsumptionFlag = do { ds <- xoptM LangExt.DeepSubsumption ; if ds then return Deep else return Shallow } -tc_sub_type_deep :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify +tc_sub_type_deep :: HasDebugCallStack + => (TcType -> TcType -> TcM TcCoercionN) -- How to unify -> CtOrigin -- Used when instantiating -> UserTypeCtxt -- Used when skolemising -> TcSigmaType -- Actual; a sigma-type @@ -1886,6 +1881,12 @@ isDeepRhoTy ty | Just (_, res) <- tcSplitFunTy_maybe ty = isDeepRhoTy res | otherwise = True -- No forall, (=>), or (->) at top +isRhoTyDS :: DeepSubsumptionFlag -> TcType -> Bool +isRhoTyDS ds_flag ty + = case ds_flag of + Shallow -> isRhoTy ty -- isRhoTy: no top level forall or (=>) + Deep -> isDeepRhoTy ty -- "deep" version: no nested forall or (=>) + {- ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a4233b32de3cc054dda0d28accaffa216cd4085 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a4233b32de3cc054dda0d28accaffa216cd4085 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 01:21:49 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 21:21:49 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.10 Message-ID: <6629b02dde43f_da43f9b7f0820298@gitlab.mail> Ben Gamari deleted branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 01:21:53 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 24 Apr 2024 21:21:53 -0400 Subject: [Git][ghc/ghc][ghc-9.10] 12 commits: EPA: Add additional comments field to AnnsModule Message-ID: <6629b03190557_da43f9e2f002045f@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: f15a854e by Alan Zimmerman at 2024-04-21T09:59:45+01:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - c8d25501 by Alan Zimmerman at 2024-04-21T10:41:35+01:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 (cherry picked from commit f07015858fd79dca41983dbf3a249dfecd8d2eea) - - - - - 7d6ae7aa by Alan Zimmerman at 2024-04-21T11:39:48+01:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 (cherry picked from commit c90c60390aa3949b400f26ee0534273c56e19005) - - - - - 64013156 by Alan Zimmerman at 2024-04-21T12:43:22+01:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 (cherry picked from commit 26036f96919b1a8b99715dd99724163012c719fc) - - - - - 898fcbd2 by Alan Zimmerman at 2024-04-21T13:49:41+01:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 (cherry picked from commit 2f8e3a254a20f4573aec26fc85ab74b51d661472) - - - - - 9f509a09 by Alan Zimmerman at 2024-04-21T15:32:17+01:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. (cherry picked from commit 00d3ecf0775c1a3f1ab8495e5e125f21d450394e) - - - - - 45cc3064 by Ben Gamari at 2024-04-24T11:00:59-04:00 Merge remote-tracking branch 'origin/wip/az/ghc-9.10-backports-1' into HEAD - - - - - d9cd4bde by Ben Gamari at 2024-04-24T11:01:34-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. (cherry picked from commit 55eb8c98895308d2dd025f7bd64c0b80fce6ace3) - - - - - b8f9880c by Zubin Duggal at 2024-04-24T11:01:34-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. (cherry picked from commit a933aff37992ea311a60be878379e7abf650e9fb) - - - - - 6d6c2640 by Ben Gamari at 2024-04-24T11:01:37-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. (cherry picked from commit d7a3d6b5ee5e0c16af295579da3c54d8f0c37a05) - - - - - 88e31848 by Teo Camarasu at 2024-04-24T11:01:37-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 (cherry picked from commit f30e4984fb048818051465698ef8e4e20dacb577) - - - - - 1261ec2f by Simon Peyton Jones at 2024-04-24T11:01:37-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] (cherry picked from commit 9d38bfa0c0f910208822579acaa999f87c2f8c65) - - - - - 30 changed files: - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/ThToHs.hs - docs/index.html.in - hadrian/src/Rules/Generate.hs - libraries/ghc-internal/src/GHC/Internal/Foreign/Marshal/Error.hs - libraries/ghc-internal/src/GHC/Internal/List.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - + testsuite/tests/core-to-stg/T24463.hs - testsuite/tests/core-to-stg/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Makefile - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/Setup.hs - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/all.T - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/genLargeHMU - + testsuite/tests/driver/multipleHomeUnits/mhu-perf/mhu-perf.stderr - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/linear/should_fail/LinearLet6.stderr - testsuite/tests/linear/should_fail/LinearLet7.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/26b6c7fdaf0ac6c5c68d76922c2339d0cfec6c6e...1261ec2fc0db926357c9d5dbbc0a69a621902694 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/26b6c7fdaf0ac6c5c68d76922c2339d0cfec6c6e...1261ec2fc0db926357c9d5dbbc0a69a621902694 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 05:32:44 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 01:32:44 -0400 Subject: [Git][ghc/ghc][master] 4 commits: ghc-bignum: remove obsolete ln script Message-ID: <6629eafc35a7f_da43f25c73ec299a3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - 7 changed files: - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln Changes: ===================================== configure.ac ===================================== @@ -740,10 +740,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -184,7 +181,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -443,7 +439,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -511,15 +506,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3fff09779d5830549ae455a15907b7bb9fe7859a...71f28958454872db9c21c7d974dd0f0a7c7e8f3d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3fff09779d5830549ae455a15907b7bb9fe7859a...71f28958454872db9c21c7d974dd0f0a7c7e8f3d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 05:33:20 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 01:33:20 -0400 Subject: [Git][ghc/ghc][master] JS: correctly handle RUBBISH literals (#24664) Message-ID: <6629eb205565a_da43f276a83433010@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 1 changed file: - compiler/GHC/StgToJS/Literal.hs Changes: ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/daeda83478d5b800d29661408dd67cc4b23df374 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/daeda83478d5b800d29661408dd67cc4b23df374 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 07:32:12 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 25 Apr 2024 03:32:12 -0400 Subject: [Git][ghc/ghc][wip/or-pats] 31 commits: EPA: Fix span for PatBuilderAppType Message-ID: <662a06fc4b4de_da43f3539c804122b@gitlab.mail> Sebastian Graf pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC Commits: 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 4ae18d8f by Sebastian Graf at 2024-04-25T09:31:12+02:00 Parser: Remove unused `apats` rule - - - - - ab4e6c52 by David Knothe at 2024-04-25T09:31:57+02:00 Implement Or Patterns (#22596) This commit introduces a new language extension, `-XOrPatterns`, as described in GHC Proposal 522. An or-pattern `pat1; ...; patk` succeeds iff one of the patterns `pat1`, ..., `patk` succeed, in this order. See also the summary `Note [Implmentation of OrPatterns]`. Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> - - - - - 30 changed files: - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Check.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3abaf0223ef561d62f1bf42465cf76a6f4b3557f...ab4e6c5273bdb3d8b990351edfca030e124b762c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3abaf0223ef561d62f1bf42465cf76a6f4b3557f...ab4e6c5273bdb3d8b990351edfca030e124b762c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 08:06:42 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 25 Apr 2024 04:06:42 -0400 Subject: [Git][ghc/ghc][wip/T24676] Do a qlUnify when resuming Message-ID: <662a0f12abc73_da43f3a0c4ec442aa@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: bb5e111d by Simon Peyton Jones at 2024-04-25T10:05:58+02:00 Do a qlUnify when resuming ...tricky! - - - - - 1 changed file: - compiler/GHC/Tc/Gen/App.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -519,7 +519,9 @@ tcValArg do_ql (EValArgQL { eaql_ctxt = ctxt -- type ActionM a = forall m . (..) => ActionT (Draw m) a do { case mb_delta of Nothing -> return () - Just (delta, wanted) -> do { demoteQLDelta delta + Just (delta, wanted) -> do { qlUnify delta arg_rho res_rho + -- ToDo: tricky point, needs documentation + ; demoteQLDelta delta ; emitConstraints wanted } ; finishApp do_ql rn_expr rn_head tc_fun inst_args res_rho (Check arg_rho) } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb5e111d2980c930201a3df83158d1323e089b60 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb5e111d2980c930201a3df83158d1323e089b60 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 09:01:58 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Thu, 25 Apr 2024 05:01:58 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/fix-tuple-renaminb] Fix tuple puns renaming (24702) Message-ID: <662a1c0689ca2_14932163a02450152@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/fix-tuple-renaminb at Glasgow Haskell Compiler / GHC Commits: 937af61e by Andrei Borzenkov at 2024-04-25T13:01:43+04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 7 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (63 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/937af61ee87b50a9b204cc479b1c67232174c68e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/937af61ee87b50a9b204cc479b1c67232174c68e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 11:09:54 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 25 Apr 2024 07:09:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/late_workfree Message-ID: <662a3a029ecca_149321151970c644f1@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/late_workfree at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/late_workfree You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 12:06:24 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 08:06:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: ghc-bignum: remove obsolete ln script Message-ID: <662a4740c8739_1493211b9d344713bf@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - f1a58906 by Matthew Pickering at 2024-04-25T08:06:09-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 02536948 by Andrei Borzenkov at 2024-04-25T08:06:10-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 16 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/StgToJS/Literal.hs - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] ===================================== configure.ac ===================================== @@ -740,10 +740,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -184,7 +181,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -443,7 +439,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -511,15 +506,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -71,6 +71,7 @@ import System.Directory (getCurrentDirectory) import qualified Distribution.InstalledPackageInfo as CP import Distribution.Simple.Utils (writeUTF8File) import Utilities +import Packages -- | Parse the Cabal file of a given 'Package'. This operation is cached by the @@ -150,8 +151,20 @@ configurePackage context at Context {..} = do -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage + + + -- Normally we will depend on Inplace package databases which enables + -- cross-package parallelism, but see #24436 for why we lineariese the build + -- of base and ghc-internal. + let forceBaseAfterGhcInternal dep = + if dep == ghcInternal && package == base + then Final + else iplace + + + -- We'll need those packages in our package database. - deps <- sequence [ pkgConfFile (context { package = pkg }) + deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg }) | pkg <- depPkgs, pkg `elem` stagePkgs ] need $ extraPreConfigureDeps ++ deps ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (63 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03c13f343554e7c51d80cb8e6ee7519a4bcc7ef8...02536948764b4e33169623b4230a3abccfcb430e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03c13f343554e7c51d80cb8e6ee7519a4bcc7ef8...02536948764b4e33169623b4230a3abccfcb430e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 13:16:42 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 25 Apr 2024 09:16:42 -0400 Subject: [Git][ghc/ghc][wip/andreask/arm_mem_model] NCG: AArch64 - Add -fhuge-code-sections. Message-ID: <662a57ba5e95d_14932126049cc948ac@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/arm_mem_model at Glasgow Haskell Compiler / GHC Commits: 32c94235 by Andreas Klebinger at 2024-04-25T15:13:07+02:00 NCG: AArch64 - Add -fhuge-code-sections. When enabled the arm backend will assume jumps to targets outside of the current module are further than 128MB away. This will allow for code to work if: * The current module results in less than 128MB of code. * The whole program is loaded within a 4GB memory region. We enable this by default on mac where the lack of split sections can sometimes cause us to go over this limit - see #24648. This works around #24648 for now. - - - - - 7 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -23,7 +23,7 @@ import GHC.Cmm.DebugBlock import GHC.CmmToAsm.Monad ( NatM, getNewRegNat , getPicBaseMaybeNat, getPlatform, getConfig - , getDebugBlock, getFileId + , getDebugBlock, getFileId, getThisModuleNat ) -- import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC @@ -1353,8 +1353,16 @@ assignReg_FltCode = assignReg_IntCode -- Jumps genJump :: CmmExpr{-the branch target-} -> NatM InstrBlock -genJump expr@(CmmLit (CmmLabel lbl)) - = return $ unitOL (annExpr expr (J (TLabel lbl))) +genJump expr@(CmmLit (CmmLabel lbl)) = do + cur_mod <- getThisModuleNat + !huge_sections <- ncgEnableHugeTextSections <$> getConfig + let is_local = isLocalCLabel cur_mod lbl + + if not huge_sections || is_local + then return $ unitOL (annExpr expr (J (TLabel lbl))) + else do + (target, _format, code) <- getSomeReg expr + return (code `appOL` unitOL (annExpr expr (J (TReg target)))) genJump expr = do (target, _format, code) <- getSomeReg expr ===================================== compiler/GHC/CmmToAsm/Config.hs ===================================== @@ -44,6 +44,7 @@ data NCGConfig = NCGConfig , ncgDwarfSourceNotes :: !Bool -- ^ Enable GHC-specific source note DIEs , ncgCmmStaticPred :: !Bool -- ^ Enable static control-flow prediction , ncgEnableShortcutting :: !Bool -- ^ Enable shortcutting (don't jump to blocks only containing a jump) + , ncgEnableHugeTextSections:: !Bool -- ^ Enable use of far-jumps by default. , ncgComputeUnwinding :: !Bool -- ^ Compute block unwinding tables , ncgEnableDeadCodeElimination :: !Bool -- ^ Whether to enable the dead-code elimination } ===================================== compiler/GHC/Driver/Config/CmmToAsm.hs ===================================== @@ -68,6 +68,7 @@ initNCGConfig dflags this_mod = NCGConfig , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags + , ncgEnableHugeTextSections = gopt Opt_HugeCodeSections dflags , ncgComputeUnwinding = debugLevel dflags > 0 , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) -- Disable when -finfo-table-map is on (#20428) ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1204,6 +1204,16 @@ defaultFlags settings ++ validHoleFitDefaults + -- Platform/OS specific stuff + ++ case platformOS platform of + -- On mac in edge cases we end up with very large text sections + -- so enable HugeTextSections by default to generate jumps compatible + -- with those. + OSDarwin + | platformArch platform == ArchAArch64 + -> [Opt_HugeCodeSections] + _ -> [] + where platform = sTargetPlatform settings ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -299,6 +299,7 @@ data GeneralFlag | Opt_CmmElimCommonBlocks | Opt_CmmControlFlow | Opt_AsmShortcutting + | Opt_HugeCodeSections | Opt_OmitYields | Opt_FunToThunk -- deprecated | Opt_DictsStrict -- be strict in argument dictionaries @@ -541,6 +542,7 @@ optimisationFlags = EnumSet.fromList , Opt_CmmSink , Opt_CmmElimCommonBlocks , Opt_AsmShortcutting + , Opt_HugeCodeSections , Opt_FunToThunk , Opt_DmdTxDictSel , Opt_Loopification ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2412,6 +2412,7 @@ fFlagsDeps = [ flagSpec "gen-manifest" Opt_GenManifest, flagSpec "ghci-history" Opt_GhciHistory, flagSpec "ghci-leak-check" Opt_GhciLeakCheck, + flagSpec "huge-code-sections" Opt_HugeCodeSections, flagSpec "validate-ide-info" Opt_ValidateHie, flagGhciSpec "local-ghci-history" Opt_LocalGhciHistory, flagGhciSpec "no-it" Opt_NoIt, ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -596,6 +596,24 @@ as such you shouldn't need to set any of them explicitly. A flag ``-fno-full-laziness``. If that is inconvenient for you, please leave a comment `on the issue tracker (#21204) `__. +.. ghc-flag:: -fhuge-text-sections + :shortdesc: Assume code sections can be unreasonably large. + :type: dynamic + :reverse: -fno-huge-code-sections + :category: + + :default: Enabled by default on aarch64 macOS. Otherwise defaults to no. + + In some niche scenarious one can end up with code sections large enough to prevent the + linker from properly relocating jumps. (:ghc-ticket:`24648`) + + In such cases this flag causes all jumps to targets outside of the currently + compiled module to be generated in a way that allows for larger jump offsets + at the cost of performance. + + Note that this flag currently only affects the NCG AArch64 backend. + + .. ghc-flag:: -fignore-asserts :shortdesc: Ignore assertions in the source. Implied by :ghc-flag:`-O`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32c94235fff1438c9b4d11015c7df4a7c85e6c62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32c94235fff1438c9b4d11015c7df4a7c85e6c62 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 15:16:50 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 11:16:50 -0400 Subject: [Git][ghc/ghc][master] Linearise ghc-internal and base build Message-ID: <662a73e257c1_14932137d9f6c111270@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 1 changed file: - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs Changes: ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -71,6 +71,7 @@ import System.Directory (getCurrentDirectory) import qualified Distribution.InstalledPackageInfo as CP import Distribution.Simple.Utils (writeUTF8File) import Utilities +import Packages -- | Parse the Cabal file of a given 'Package'. This operation is cached by the @@ -150,8 +151,20 @@ configurePackage context at Context {..} = do -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage + + + -- Normally we will depend on Inplace package databases which enables + -- cross-package parallelism, but see #24436 for why we lineariese the build + -- of base and ghc-internal. + let forceBaseAfterGhcInternal dep = + if dep == ghcInternal && package == base + then Final + else iplace + + + -- We'll need those packages in our package database. - deps <- sequence [ pkgConfFile (context { package = pkg }) + deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg }) | pkg <- depPkgs, pkg `elem` stagePkgs ] need $ extraPreConfigureDeps ++ deps View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a06ddf68bb5a9985e3a7b8464dd04b928c36b90 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a06ddf68bb5a9985e3a7b8464dd04b928c36b90 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 15:17:30 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 11:17:30 -0400 Subject: [Git][ghc/ghc][master] Fix tuple puns renaming (24702) Message-ID: <662a740a963b6_1493213971c3011439d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 7 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (63 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94da936507c685aa8101a714e7619b4d428d0187 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94da936507c685aa8101a714e7619b4d428d0187 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 15:27:17 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 25 Apr 2024 11:27:17 -0400 Subject: [Git][ghc/ghc][wip/andreask/expose-overloaded-unfoldings] 62 commits: users-guide: Clarify language extension documentation Message-ID: <662a7655139cf_1493213b7b7381182b6@gitlab.mail> Sebastian Graf pushed to branch wip/andreask/expose-overloaded-unfoldings at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 26b7ddae by Andreas Klebinger at 2024-04-25T15:27:09+00:00 Tidy: Add flag to expose unfoldings if they take dictionary arguments. Add the flag `-fexpose-overloaded-unfoldings` to be able to control this behaviour. For ghc's boot libraries file size grew by less than 1% when it was enabled. However I refrained from enabling it by default for now. I've also added a section on specialization more broadly to the users guide. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: T12425 T13386 hard_hole_fits ------------------------- - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af52c6e1ce063bcd438052964c032ec46a82ca4e...26b7ddaeea1aae5950bd8979e2cfe6a5c69b9d06 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af52c6e1ce063bcd438052964c032ec46a82ca4e...26b7ddaeea1aae5950bd8979e2cfe6a5c69b9d06 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 16:32:15 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Thu, 25 Apr 2024 12:32:15 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] 2 commits: Implement -falignment-sanitisation Message-ID: <662a858f6e818_14932143cd238120775@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: ef6ed137 by Sven Tennie at 2024-04-25T18:29:37+02:00 Implement -falignment-sanitisation - - - - - 88a8a0be by Sven Tennie at 2024-04-25T18:30:09+02:00 Ensure there's always a well defined skip label (far branches) Just th be sure, we don't accidentally land somewhere unexpected. - - - - - 2 changed files: - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -26,6 +26,7 @@ import GHC.CmmToAsm.Config import GHC.CmmToAsm.Format import GHC.CmmToAsm.Monad ( NatM, + getBlockIdNat, getConfig, getDebugBlock, getFileId, @@ -54,6 +55,7 @@ import GHC.Utils.Constants (debugIsOn) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain (assert) -- For an overview of an NCG's structure, see Note [General layout of an NCG] @@ -476,6 +478,10 @@ getRegister' config plat (CmmMachOp (MO_Add w0) [x, CmmLit (CmmInt i w1)]) | i < getRegister' config plat (CmmMachOp (MO_Sub w0) [x, CmmLit (CmmInt i w1)]) | i < 0 = getRegister' config plat (CmmMachOp (MO_Add w0) [x, CmmLit (CmmInt (-i) w1)]) +getRegister' config platform (CmmMachOp (MO_AlignmentCheck align wordWidth) [e]) + = do + reg <- getRegister' config platform e + addAlignmentCheck align wordWidth reg -- Generic case. getRegister' config plat expr = @@ -1080,6 +1086,34 @@ truncateReg w w' r = where shift = 64 - widthInBits w' +-- | Given a 'Register', produce a new 'Register' with an instruction block +-- which will check the value for alignment. Used for @-falignment-sanitisation at . +addAlignmentCheck :: Int -> Width -> Register -> NatM Register +addAlignmentCheck align wordWidth reg = do + jumpReg <- getNewRegNat II64 + cmpReg <- getNewRegNat II64 + okayLblId <- getBlockIdNat + + pure $ case reg of + Fixed fmt reg code -> Fixed fmt reg (code `appOL` check fmt jumpReg cmpReg okayLblId reg) + Any fmt f -> Any fmt (\reg -> f reg `appOL` check fmt jumpReg cmpReg okayLblId reg) + where + -- TODO: Reduce amount of parameters by making this a let binding + check :: Format -> Reg -> Reg -> BlockId -> Reg -> InstrBlock + check fmt jumpReg cmpReg okayLblId reg = + let width = formatToWidth fmt + in assert (not $ isFloatFormat fmt) + $ toOL + [ ann + (text "Alignment check - alignment: " <> int align <> text ", word width: " <> text (show wordWidth)) + (AND (OpReg width cmpReg) (OpReg width reg) (OpImm $ ImmInt $ align - 1)) + , BCOND EQ (OpReg width cmpReg) zero (TBlock okayLblId) + , COMMENT (text "Alignment check failed") + , LDR II64 (OpReg W64 jumpReg) (OpImm $ ImmCLbl mkBadAlignmentLabel) + , J (TReg jumpReg) + , NEWBLOCK okayLblId + ] + -- ----------------------------------------------------------------------------- -- The 'Amode' type: Memory addressing modes passed up the tree. data Amode = Amode AddrMode InstrBlock ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -468,7 +468,8 @@ pprInstr platform instr = case instr of -- 2. Bit Manipulation Instructions ------------------------------------------ -- 3. Logical and Move Instructions ------------------------------------------ - AND o1 o2 o3 -> op3 (text "\tand") o1 o2 o3 + AND o1 o2 o3 | isImmOp o3 -> op3 (text "\tandi") o1 o2 o3 + | otherwise -> op3 (text "\tand") o1 o2 o3 OR o1 o2 o3 -> op3 (text "\tor") o1 o2 o3 ASR o1 o2 o3 | isImmOp o3 -> op3 (text "\tsrai") o1 o2 o3 ASR o1 o2 o3 -> op3 (text "\tsra") o1 o2 o3 @@ -527,9 +528,10 @@ pprInstr platform instr = case instr of -- register based jump (ignoring the link result in register zero) or just -- branch to the end of the block, jumping over the far jump instructions. BCOND_FAR c l r b t | isLabel t -> - lines_ [ text "\t" <> pprBcond (negateCond c) <+> pprOp platform l <> comma <+> pprOp platform r <> comma <+> getLabel platform b <> text "_end" + lines_ [ text "\t" <> pprBcond (negateCond c) <+> pprOp platform l <> comma <+> pprOp platform r <> comma <+> getLabel platform b <> text "far_branch_end" , text "\tla" <+> pprOp platform ip <> comma <+> getLabel platform t , text "\tjalr" <+> text "x0" <> comma <+> pprOp platform ip <> comma <+> text "0" + , text "\t" <> getLabel platform b <> text "far_branch_end" <> colon ] BCOND_FAR _ _ _ _ (TReg _) -> panic "RV64.ppr: No conditional branching to registers!" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b268fc4c044af12fd3cd028751129cf59bb6a359...88a8a0beafd100280d7e17d13bb3170b90bac49a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b268fc4c044af12fd3cd028751129cf59bb6a359...88a8a0beafd100280d7e17d13bb3170b90bac49a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 16:52:18 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 25 Apr 2024 12:52:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.10 Message-ID: <662a8a42c479e_149321475caac12134a@gitlab.mail> Ben Gamari pushed new branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.10 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 16:54:52 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 25 Apr 2024 12:54:52 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] 4 commits: ghc-bignum: remove obsolete ln script Message-ID: <662a8adcd719d_14932148fb78c1314f1@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 5f4848c0 by Cheng Shao at 2024-04-25T12:54:20-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. (cherry picked from commit c62dc317c21026396a7a5581b90d17ef4c44f9ac) - - - - - f845a792 by Cheng Shao at 2024-04-25T12:54:22-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. (cherry picked from commit 6399d52ba10d510a94c9db6552a4ea8aae8e003b) - - - - - 92065500 by Cheng Shao at 2024-04-25T12:54:23-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. (cherry picked from commit 65b4b92fa1e1989d055108a6077cc9119ee28acd) - - - - - 1e77ded1 by Cheng Shao at 2024-04-25T12:54:24-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. (cherry picked from commit 71f28958454872db9c21c7d974dd0f0a7c7e8f3d) - - - - - 7 changed files: - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln Changes: ===================================== configure.ac ===================================== @@ -735,10 +735,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -182,7 +179,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -439,7 +435,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -507,15 +502,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be59c02ce0035900fe9223a5a2391d53f6f6f68b...1e77ded14cac81998f211d2990b37b9ecded2fa7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be59c02ce0035900fe9223a5a2391d53f6f6f68b...1e77ded14cac81998f211d2990b37b9ecded2fa7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 16:56:35 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 25 Apr 2024 12:56:35 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] JS: correctly handle RUBBISH literals (#24664) Message-ID: <662a8b435d04e_1493214a572fc131865@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: bb67e8d5 by Sylvain Henry at 2024-04-25T12:56:03-04:00 JS: correctly handle RUBBISH literals (#24664) (cherry picked from commit daeda83478d5b800d29661408dd67cc4b23df374) - - - - - 1 changed file: - compiler/GHC/StgToJS/Literal.hs Changes: ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb67e8d5678a4a6a7d54606b623141bc44ef3b8d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb67e8d5678a4a6a7d54606b623141bc44ef3b8d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 19:48:11 2024 From: gitlab at gitlab.haskell.org (Adam Gundry (@adamgundry)) Date: Thu, 25 Apr 2024 15:48:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/amg/T24710 Message-ID: <662ab37ba2300_1f4d49106f3643116e@gitlab.mail> Adam Gundry pushed new branch wip/amg/T24710 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/amg/T24710 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 19:54:25 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Thu, 25 Apr 2024 15:54:25 -0400 Subject: [Git][ghc/ghc][wip/az/T24670-epa-compare-source] 8 commits: ghc-bignum: remove obsolete ln script Message-ID: <662ab4f1d25df_1f4d4911c2130359b7@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T24670-epa-compare-source at Glasgow Haskell Compiler / GHC Commits: c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 3e65cec9 by Alan Zimmerman at 2024-04-25T20:54:10+01:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 18 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/StgToJS/Literal.hs - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/printer/PprExportWarn.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] ===================================== configure.ac ===================================== @@ -740,10 +740,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -184,7 +181,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -443,7 +439,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -511,15 +506,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -71,6 +71,7 @@ import System.Directory (getCurrentDirectory) import qualified Distribution.InstalledPackageInfo as CP import Distribution.Simple.Utils (writeUTF8File) import Utilities +import Packages -- | Parse the Cabal file of a given 'Package'. This operation is cached by the @@ -150,8 +151,20 @@ configurePackage context at Context {..} = do -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage + + + -- Normally we will depend on Inplace package databases which enables + -- cross-package parallelism, but see #24436 for why we lineariese the build + -- of base and ghc-internal. + let forceBaseAfterGhcInternal dep = + if dep == ghcInternal && package == base + then Final + else iplace + + + -- We'll need those packages in our package database. - deps <- sequence [ pkgConfFile (context { package = pkg }) + deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg }) | pkg <- depPkgs, pkg `elem` stagePkgs ] need $ extraPreConfigureDeps ++ deps ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (63 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e77abdd6af72be43d398826e472a2386d141af13...3e65cec94a0536720fe70dc734db10c6dac9ada3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e77abdd6af72be43d398826e472a2386d141af13...3e65cec94a0536720fe70dc734db10c6dac9ada3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 21:32:39 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 25 Apr 2024 17:32:39 -0400 Subject: [Git][ghc/ghc][wip/T24676] 49 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <662acbf756a5c_1f4d491fef3fc48127@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fc45af3f by Simon Peyton Jones at 2024-04-25T23:32:29+02:00 Fix a QuickLook bug This MR fixes the bug exposed by #24676. The problem was that quickLookArg was trying to avoid calling tcInstFun unnecessarily; but it was in fact necessary. But that in turn forced me into a significant refactoring, putting more fields into EValArgQL. I added a lot of new material to Note [Quick Look at value arguments] It is a bit more subtle than I would like, but the overall plan is rather clearer now than it was. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bb5e111d2980c930201a3df83158d1323e089b60...fc45af3f2bd2c8a7819056c7978341df268f09dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bb5e111d2980c930201a3df83158d1323e089b60...fc45af3f2bd2c8a7819056c7978341df268f09dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 25 22:20:28 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 18:20:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Linearise ghc-internal and base build Message-ID: <662ad72ccb280_1f4d4925e9fb4538a1@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 3e65cec9 by Alan Zimmerman at 2024-04-25T20:54:10+01:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 482f827e by Andrew Lelechenko at 2024-04-25T18:20:20-04:00 Document that setEnv is not thread-safe - - - - - 12 changed files: - compiler/GHC/Builtin/Types.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/printer/PprExportWarn.hs - + testsuite/tests/th/T24702a.hs - + testsuite/tests/th/T24702b.hs - testsuite/tests/th/TH_tuple1.stdout - testsuite/tests/th/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -795,7 +795,7 @@ We make boxed one-tuple names have known keys so that `data Solo a = MkSolo a`, defined in GHC.Tuple, will be used when one-tuples are spliced in through Template Haskell. This program (from #18097) crucially relies on this: - case $( tupE [ [| "ok" |] ] ) of Solo x -> putStrLn x + case $( tupE [ [| "ok" |] ] ) of MkSolo x -> putStrLn x Unless Solo has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an ExplicitTuple of length 1) will not match the type of Solo (an ordinary @@ -838,26 +838,10 @@ isBuiltInOcc_maybe occ = , (commas, rest') <- BS.span (==',') rest , ")" <- rest' -> Just $ tup_name Boxed (1+BS.length commas) - _ | Just rest <- "Tuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - -> if - | BS.null trailing -> Just $ tup_name Boxed num - | "#" == trailing -> Just $ tup_name Unboxed num - | otherwise -> Nothing - - "CUnit" -> Just $ choose_ns (cTupleTyConName 0) (cTupleDataConName 0) - "CSolo" -> Just $ choose_ns (cTupleTyConName 1) (cTupleDataConName 1) - _ | Just rest <- "CTuple" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , BS.null trailing - , num >= 2 && num <= 64 - -> Just $ choose_ns (cTupleTyConName num) (cTupleDataConName num) -- unboxed tuple data/tycon "(##)" -> Just $ tup_name Unboxed 0 - "Unit#" -> Just $ tup_name Unboxed 0 - "Solo#" -> Just $ tup_name Unboxed 1 + "(# #)" -> Just $ tup_name Unboxed 1 _ | Just rest <- "(#" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest , "#)" <- rest' @@ -878,11 +862,6 @@ isBuiltInOcc_maybe occ = -> let arity = nb_pipes1 + nb_pipes2 + 1 alt = nb_pipes1 + 1 in Just $ dataConName $ sumDataCon alt arity - _ | Just rest <- "Sum" `BS.stripPrefix` name - , Just (num, trailing) <- BS.readInt rest - , num >= 2 && num <= 64 - , trailing == "#" - -> Just $ tyConName $ sumTyCon num _ -> Nothing where @@ -920,6 +899,21 @@ isTupleTyOcc_maybe mod occ | otherwise = isTupleNTyOcc_maybe occ isTupleTyOcc_maybe _ _ = Nothing +isCTupleOcc_maybe :: Module -> OccName -> Maybe Name +isCTupleOcc_maybe mod occ + | mod == gHC_CLASSES + = match_occ + where + match_occ + | occ == occName (cTupleTyConName 0) = Just (cTupleTyConName 0) + | occ == occName (cTupleTyConName 1) = Just (cTupleTyConName 1) + | 'C':'T':'u':'p':'l':'e' : rest <- occNameString occ + , Just (BoxedTuple, num) <- arity_and_boxity rest + , num >= 2 && num <= 64 + = Just $ cTupleTyConName num + | otherwise = Nothing + +isCTupleOcc_maybe _ _ = Nothing -- | This is only for Tuple, not for Unit or Solo isTupleNTyOcc_maybe :: OccName -> Maybe Name @@ -985,13 +979,12 @@ isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName = Just listTyConName - | mod == gHC_INTERNAL_TUPLE, occ == occName unitTyConName - = Just unitTyConName - | mod == gHC_TYPES, occ == occName unboxedUnitTyConName - = Just unboxedUnitTyConName - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = isTupleNTyOcc_maybe occ <|> isSumNTyOcc_maybe occ -isPunOcc_maybe _ _ = Nothing + | mod == gHC_TYPES, occ == occName unboxedSoloDataConName + = Just unboxedSoloDataConName + | otherwise + = isTupleTyOcc_maybe mod occ <|> + isCTupleOcc_maybe mod occ <|> + isSumTyOcc_maybe mod occ mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName -- No need to cache these, the caching is done in mk_tuple @@ -1304,6 +1297,8 @@ unboxedSoloTyCon = tupleTyCon Unboxed 1 unboxedSoloTyConName :: Name unboxedSoloTyConName = tyConName unboxedSoloTyCon +unboxedSoloDataConName :: Name +unboxedSoloDataConName = tupleDataConName Unboxed 1 {- ********************************************************************* * * ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -71,6 +71,7 @@ import System.Directory (getCurrentDirectory) import qualified Distribution.InstalledPackageInfo as CP import Distribution.Simple.Utils (writeUTF8File) import Utilities +import Packages -- | Parse the Cabal file of a given 'Package'. This operation is cached by the @@ -150,8 +151,20 @@ configurePackage context at Context {..} = do -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage + + + -- Normally we will depend on Inplace package databases which enables + -- cross-package parallelism, but see #24436 for why we lineariese the build + -- of base and ghc-internal. + let forceBaseAfterGhcInternal dep = + if dep == ghcInternal && package == base + then Final + else iplace + + + -- We'll need those packages in our package database. - deps <- sequence [ pkgConfFile (context { package = pkg }) + deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg }) | pkg <- depPkgs, pkg `elem` stagePkgs ] need $ extraPreConfigureDeps ++ deps ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -236,7 +236,6 @@ maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing maybe_tuple "()" = Just("Z0T") -maybe_tuple "MkSolo" = Just("Z1T") maybe_tuple ('(' : cs) = case count_commas (0::Int) cs of (n, ')' : _) -> Just ('Z' : shows (n+1) "T") _ -> Nothing ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1930,15 +1930,19 @@ mk_tup_name n space boxed | boxed = "(" ++ thing ++ ")" | otherwise = "(#" ++ thing ++ "#)" tup_occ | n == 0, space == TcClsName = if boxed then "Unit" else "Unit#" - | n == 1 = if boxed then solo else "Solo#" + | n == 1 = if boxed then solo else unboxed_solo | space == TcClsName = "Tuple" ++ show n ++ if boxed then "" else "#" | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 - tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Prim") + tup_mod = mkModName (if boxed then "GHC.Tuple" else "GHC.Types") solo | space == DataName = "MkSolo" | otherwise = "Solo" + unboxed_solo + | space == DataName = "(# #)" + | otherwise = "Solo#" + -- Unboxed sum data and type constructors -- | Unboxed sum data constructor unboxedSumDataName :: SumAlt -> SumArity -> Name ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/th/T24702a.hs ===================================== @@ -0,0 +1,55 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnboxedTuples #-} +module T24702a where + +import Language.Haskell.TH.Lib +import Language.Haskell.TH.Syntax + +$(do + let + step = \acc n -> acc `appT` n + args n = replicate n (conT ''Int) + + mkTupleTest mkTupTy mkTupCon boxity n = do + let + nil = conT (mkTupTy n) + tup = foldl step nil (args n) + f <- newName (boxity <> show n) + + -- f :: (,,..n..,,) t1 t2 .. tn -> () + -- f = \ (_, _, ...n..., _) -> () + sequence $ + sigD f [t|$(tup) -> ()|] : + valD (varP f) (normalB [e| \ $(conP (mkTupCon n) (replicate n wildP)) -> ()|]) [] : + [] + + mkSumTest n = do + let + nil = conT (unboxedSumTypeName n) + sumTy = foldl step nil (args n) + mkSumAlt altN = + let sumDataCon = unboxedSumDataName altN n + varName = mkName "x" in + clause [conP sumDataCon [varP varName]] + (normalB (conE sumDataCon `appE` varE varName)) [] + f <- newName ("sum" <> show n) + + -- f :: (#||...n...||#) -> (#||...n...||#) + -- f (x||...n...||) = (x||...n...||) + -- f (|x||...n...||) = (|x||...n...||) + -- ...n... + -- f (||...n...||x) = (||...n...||x) + sequence $ + sigD f [t|$(sumTy) -> $(sumTy)|] : + funD f (map mkSumAlt [1 .. n]) : + [] + + newDeclarationGroup <> + mkTupleTest + unboxedTupleTypeName unboxedTupleDataName "unboxed" + `foldMap` (64 : [0 .. 8]) <> + mkTupleTest + tupleTypeName tupleDataName "boxed" + `foldMap` (64 : [0 .. 8]) <> + mkSumTest + `foldMap` (63 : [2 .. 8]) ) ===================================== testsuite/tests/th/T24702b.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE TemplateHaskell, MagicHash #-} +module T24702b where + +import Language.Haskell.TH + +data Unit = MkUnit +tup0 :: $(conT (mkName "Unit")) +tup0 = MkUnit + +data Solo = MkSolo +tup1 :: $(conT (mkName "Solo")) +tup1 = MkSolo + +data Tuple2 = MkTuple2 +tup2 :: $(conT (mkName "Tuple2")) +tup2 = MkTuple2 + +data CUnit = MkCUnit +ctup0 :: $(conT (mkName "CUnit")) +ctup0 = MkCUnit + +data CSolo = MkCSolo +ctup1 :: $(conT (mkName "CSolo")) +ctup1 = MkCSolo + +data CTuple2 = MkCTuple2 +ctup2 :: $(conT (mkName "CTuple2")) +ctup2 = MkCTuple2 + +data Unit# = MkUnit# +utup0 :: $(conT (mkName "Unit#")) +utup0 = MkUnit# + +data Solo# = MkSolo# +utup1 :: $(conT (mkName "Solo#")) +utup1 = MkSolo# + +data Tuple2# = MkTuple2# +utup2 :: $(conT (mkName "Tuple2#")) +utup2 = MkTuple2# + +data Sum2# = MkSum2# +sum2 :: $(conT (mkName "Sum2#")) +sum2 = MkSum2# ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -3,8 +3,8 @@ GHC.Tuple.(,) 1 2 :: GHC.Tuple.Tuple2 GHC.Num.Integer.Integer GHC.Num.Integer.Integer SigE (AppE (ConE GHC.Tuple.MkSolo) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Solo) (ConT GHC.Num.Integer.Integer)) GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer -SigE (AppE (AppE (ConE GHC.Prim.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Prim.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.(#,#) 1 2 :: GHC.Prim.Tuple2# GHC.Num.Integer.Integer - GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Prim.Solo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Prim.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Prim.Solo# 1 :: GHC.Prim.Solo# GHC.Num.Integer.Integer +SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer + GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer ===================================== testsuite/tests/th/all.T ===================================== @@ -612,3 +612,5 @@ test('T24557b', normal, compile_fail, ['']) test('T24557c', normal, compile_fail, ['']) test('T24557d', normal, compile_fail, ['']) test('T24557e', normal, compile, ['']) +test('T24702a', normal, compile, ['']) +test('T24702b', normal, compile, ['']) ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02536948764b4e33169623b4230a3abccfcb430e...482f827e98fe693d882dc908eaceeabab0fa7ee5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02536948764b4e33169623b4230a3abccfcb430e...482f827e98fe693d882dc908eaceeabab0fa7ee5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 01:01:10 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 25 Apr 2024 21:01:10 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Fix missing escaping-kind check in tcPatSynSig Message-ID: <662afcd6dc634_1f4d4939495286889f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c9c940fd by Simon Peyton Jones at 2024-04-25T21:01:01-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - af05f00c by Alan Zimmerman at 2024-04-25T21:01:01-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 7c8f6317 by Andrew Lelechenko at 2024-04-25T21:01:01-04:00 Document that setEnv is not thread-safe - - - - - 12 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/PprExportWarn.hs - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/482f827e98fe693d882dc908eaceeabab0fa7ee5...7c8f631781cdbb2aee71e1d3571c3d704739f937 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/482f827e98fe693d882dc908eaceeabab0fa7ee5...7c8f631781cdbb2aee71e1d3571c3d704739f937 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 03:35:49 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 25 Apr 2024 23:35:49 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.10 Message-ID: <662b211577e0c_3801e21a3b6432059@gitlab.mail> Ben Gamari deleted branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 03:35:55 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 25 Apr 2024 23:35:55 -0400 Subject: [Git][ghc/ghc][ghc-9.10] 7 commits: Put the newline after errors instead of before them Message-ID: <662b211b3e0b9_3801e21758403226f@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: bcb5a91d by Jade at 2024-04-24T11:06:13-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 (cherry picked from commit 275e41a902f4aec8552707ec9924f2d0a20346d0) - - - - - be59c02c by Ben Gamari at 2024-04-25T12:51:45-04:00 Bump Cabal submodule to 3.12 - - - - - 5f4848c0 by Cheng Shao at 2024-04-25T12:54:20-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. (cherry picked from commit c62dc317c21026396a7a5581b90d17ef4c44f9ac) - - - - - f845a792 by Cheng Shao at 2024-04-25T12:54:22-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. (cherry picked from commit 6399d52ba10d510a94c9db6552a4ea8aae8e003b) - - - - - 92065500 by Cheng Shao at 2024-04-25T12:54:23-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. (cherry picked from commit 65b4b92fa1e1989d055108a6077cc9119ee28acd) - - - - - 1e77ded1 by Cheng Shao at 2024-04-25T12:54:24-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. (cherry picked from commit 71f28958454872db9c21c7d974dd0f0a7c7e8f3d) - - - - - bb67e8d5 by Sylvain Henry at 2024-04-25T12:56:03-04:00 JS: correctly handle RUBBISH literals (#24664) (cherry picked from commit daeda83478d5b800d29661408dd67cc4b23df374) - - - - - 22 changed files: - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/Utils/Logger.hs - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Rules/Gmp.hs - libraries/Cabal - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T9140.stdout - testsuite/tests/layout/layout001.stdout - testsuite/tests/layout/layout003.stdout - testsuite/tests/layout/layout004.stdout - testsuite/tests/layout/layout006.stdout - testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout - testsuite/tests/overloadedrecflds/ghci/T19314.stdout - testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout - testsuite/tests/rename/should_compile/T13839.stdout - testsuite/tests/th/T7276a.stdout - testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr Changes: ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -22,6 +22,7 @@ import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal import GHC.Types.Basic +import GHC.Types.RepType import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable @@ -68,7 +69,27 @@ genLit = \case | otherwise -> return [ toJExpr (global (mkRawSymbol True name)) , ValExpr (JInt 0) ] - LitRubbish {} -> return [ null_ ] + LitRubbish _ rr_ty -> + -- Generate appropriate rubbish literals, otherwise it might trip up the + -- code generator when a primop is applied to a rubbish literal (see #24664) + let reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genLit") rr_ty + rub = \case + BoxedRep _ -> [ null_ ] + AddrRep -> [ null_, ValExpr (JInt 0) ] + WordRep -> [ ValExpr (JInt 0) ] + Word8Rep -> [ ValExpr (JInt 0) ] + Word16Rep -> [ ValExpr (JInt 0) ] + Word32Rep -> [ ValExpr (JInt 0) ] + Word64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + IntRep -> [ ValExpr (JInt 0) ] + Int8Rep -> [ ValExpr (JInt 0) ] + Int16Rep -> [ ValExpr (JInt 0) ] + Int32Rep -> [ ValExpr (JInt 0) ] + Int64Rep -> [ ValExpr (JInt 0), ValExpr (JInt 0) ] + DoubleRep -> [ ValExpr (JInt 0) ] + FloatRep -> [ ValExpr (JInt 0) ] + VecRep _ _ -> panic "GHC.StgToJS.Literal.genLit: VecRep unsupported" + in return (concatMap rub reps) -- | generate a literal for the static init tables genStaticLit :: Literal -> G [StaticLit] ===================================== compiler/GHC/Utils/Logger.hs ===================================== @@ -417,14 +417,13 @@ defaultLogAction logflags msg_class srcSpan msg message = mkLocMessageWarningGroups (log_show_warn_groups logflags) msg_class srcSpan msg printDiagnostics = do - hPutChar stderr '\n' caretDiagnostic <- if log_show_caret logflags then getCaretDiagnostic msg_class srcSpan else pure empty printErrs $ getPprStyle $ \style -> withPprStyle (setStyleColoured True style) - (message $+$ caretDiagnostic) + (message $+$ caretDiagnostic $+$ blankLine) -- careful (#2302): printErrs prints in UTF-8, -- whereas converting to string first and using -- hPutStr would just emit the low 8 bits of ===================================== configure.ac ===================================== @@ -735,10 +735,6 @@ dnl ** check for tar dnl if GNU tar is named gtar, look for it first. AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) -dnl ** check for patch -dnl if GNU patch is named gpatch, look for it first -AC_PATH_PROGS(PatchCmd,gpatch patch, patch) - dnl ** check for autoreconf AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) ===================================== hadrian/cfg/system.config.in ===================================== @@ -17,7 +17,6 @@ sphinx-build = @SPHINXBUILD@ system-ghc = @WithGhc@ system-ghc-pkg = @GhcPkgCmd@ tar = @TarCmd@ -patch = @PatchCmd@ xelatex = @XELATEX@ makeindex = @MAKEINDEX@ makeinfo = @MAKEINFO@ ===================================== hadrian/src/Builder.hs ===================================== @@ -8,10 +8,7 @@ module Builder ( -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilders, runBuilder, runBuilderWith, runBuilderWithCmdOptions, getBuilderPath, - builderEnvironment, - - -- * Ad hoc builder invocation - applyPatch + builderEnvironment ) where import Control.Exception.Extra (Partial) @@ -182,7 +179,6 @@ data Builder = Alex | MergeObjects Stage -- ^ linker to be used to merge object files. | Nm | Objdump - | Patch | Python | Ranlib | Testsuite TestMode @@ -439,7 +435,6 @@ systemBuilderPath builder = case builder of Makeinfo -> fromKey "makeinfo" Nm -> fromTargetTC "nm" (Toolchain.nmProgram . tgtNm) Objdump -> fromKey "objdump" - Patch -> fromKey "patch" Python -> fromKey "python" Ranlib -> fromTargetTC "ranlib" (maybeProg Toolchain.ranlibProgram . tgtRanlib) Testsuite _ -> fromKey "python" @@ -507,15 +502,6 @@ systemBuilderPath builder = case builder of isSpecified :: Builder -> Action Bool isSpecified = fmap (not . null) . systemBuilderPath --- | Apply a patch by executing the 'Patch' builder in a given directory. -applyPatch :: FilePath -> FilePath -> Action () -applyPatch dir patch = do - let file = dir -/- patch - needBuilders [Patch] - path <- builderPath Patch - putBuild $ "| Apply patch " ++ file - quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] - -- Note [cmd wrapper] -- ~~~~~~~~~~~~~~~~~~ -- `cmd'` is a wrapper for Shake's `cmd` that allows us to customize what is ===================================== hadrian/src/Rules/Gmp.hs ===================================== @@ -143,23 +143,18 @@ gmpRules = do gmpP = takeDirectory gmpBuildP ctx <- makeGmpPathContext gmpP removeDirectory gmpBuildP - -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is - -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents. + -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.xz, which is + -- gmp-4.2.4.tar.xz repacked without the doc/ directory contents. -- That's because the doc/ directory contents are under the GFDL, -- which causes problems for Debian. tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected" - <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"] + <$> getDirectoryFiles top [gmpBase -/- "gmp-tarballs/gmp*.tar.xz"] withTempDir $ \dir -> do let tmp = unifyPath dir need [top -/- tarball] build $ target ctx (Tar Extract) [top -/- tarball] [tmp] - let patch = gmpBase -/- "gmpsrc.patch" - patchName = takeFileName patch - copyFile patch $ tmp -/- patchName - applyPatch tmp patchName - let name = dropExtension . dropExtension $ takeFileName tarball unpack = fromMaybe . error $ "gmpRules: expected suffix " ++ "-nodoc (found: " ++ name ++ ")." ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 7d140c56d277c49fb8452729de3bb62c937017a0 +Subproject commit 59fd01457fa662bca17110bc7505ea52bf162135 ===================================== libraries/ghc-bignum/gmp/gmp-tarballs ===================================== @@ -1 +1 @@ -Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919 +Subproject commit 01149ce3471128e9fe0feca607579981f4b64395 ===================================== libraries/ghc-bignum/gmp/gmpsrc.patch deleted ===================================== @@ -1,44 +0,0 @@ -diff -Naur gmp-6.2.1/Makefile.am gmpbuild/Makefile.am ---- gmp-6.2.1/Makefile.am 2020-11-15 02:45:09.000000000 +0800 -+++ gmpbuild/Makefile.am 2021-01-09 22:56:14.571708858 +0800 -@@ -112,7 +112,7 @@ - LIBGMPXX_LT_AGE = 6 - - --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \ - COPYING.LESSERv3 COPYINGv2 COPYINGv3 -diff -Naur gmp-6.2.1/Makefile.in gmpbuild/Makefile.in ---- gmp-6.2.1/Makefile.in 2020-11-15 02:45:16.000000000 +0800 -+++ gmpbuild/Makefile.in 2021-01-10 16:15:37.387670402 +0800 -@@ -572,7 +572,7 @@ - LIBGMPXX_LT_CURRENT = 10 - LIBGMPXX_LT_REVISION = 1 - LIBGMPXX_LT_AGE = 6 --SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc -+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune - - # Put asl.h here for now. - -diff -Naur gmp-6.2.1/configure gmpbuild/configure ---- gmp-6.2.1/configure 2020-11-15 02:45:15.000000000 +0800 -+++ gmpbuild/configure 2021-01-10 16:13:59.196004951 +0800 -@@ -27985,7 +27985,7 @@ - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" -+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in gmp.pc:gmp.pc.in gmpxx.pc:gmpxx.pc.in" - - cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure -@@ -29129,7 +29129,6 @@ - "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;; - "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;; - "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;; -- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;; - "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;; ===================================== libraries/ghc-bignum/gmp/ln deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -exit 1 - ===================================== testsuite/tests/ghci/prog018/prog018.stdout ===================================== @@ -1,7 +1,6 @@ [1 of 3] Compiling A ( A.hs, interpreted ) [2 of 3] Compiling B ( B.hs, interpreted ) [3 of 3] Compiling C ( C.hs, interpreted ) - A.hs:5:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)] Pattern match(es) are non-exhaustive In an equation for ‘incompletePattern’: @@ -17,9 +16,10 @@ B.hs:7:1: warning: [GHC-66111] [-Wunused-imports (in -Wextra)] C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules loaded. [3 of 3] Compiling C ( C.hs, interpreted ) - C.hs:6:7: error: [GHC-88464] Variable not in scope: variableNotInScope :: () + Failed, two modules reloaded. ===================================== testsuite/tests/ghci/scripts/T9140.stdout ===================================== @@ -1,4 +1,3 @@ - :2:5: error: [GHC-20036] You can't mix polymorphic and unlifted bindings: a = (# 1 #) Suggested fix: Add a type signature. @@ -10,3 +9,4 @@ :1:1: error: [GHC-17999] GHCi can't bind a variable of unlifted type: a :: (# Integer, Integer #) + ===================================== testsuite/tests/layout/layout001.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout001.hs:6:3: error: [GHC-58481] parse error on input ‘where’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout001.hs:6:3: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `where' clause at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout003.stdout ===================================== @@ -1,9 +1,9 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout003.hs:11:4: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout003.hs:11:4: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block + ===================================== testsuite/tests/layout/layout004.stdout ===================================== @@ -1,7 +1,7 @@ Running with -XNoAlternativeLayoutRule Running with -XAlternativeLayoutRule - layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout004.hs:7:14: error: [GHC-58481] parse error on input ‘,’ + ===================================== testsuite/tests/layout/layout006.stdout ===================================== @@ -1,13 +1,12 @@ Running with -XNoAlternativeLayoutRule - layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... -Running with -XAlternativeLayoutRule +Running with -XAlternativeLayoutRule layout006.hs:12:2: error: [GHC-58481] parse error on input ‘|’ -Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional +Running with -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional (in -Wdefault)] transitional layout will not be accepted in the future: `|' at the same depth as implicit layout block @@ -15,3 +14,4 @@ layout006.hs:12:2: warning: [GHC-93617] [-Walternative-layout-rule-transitional layout006.hs:12:4: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] Pattern match is redundant In an equation for ‘f’: f | True = ... + ===================================== testsuite/tests/overloadedrecflds/ghci/GHCiDRF.stdout ===================================== @@ -1,10 +1,10 @@ GHCiDRF.foo :: T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to either the field ‘bar’ of record ‘T’, defined at GHCiDRF.hs:3:28, or the field ‘bar’ of record ‘U’, defined at GHCiDRF.hs:4:16. + type T :: * data T = MkT {foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -16,7 +16,6 @@ type U :: * data U = MkU {bar :: Bool} -- Defined at GHCiDRF.hs:4:16 GHCiDRF.foo :: GHCiDRF.T -> Int - :1:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -26,6 +25,7 @@ GHCiDRF.foo :: GHCiDRF.T -> Int or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + type GHCiDRF.T :: * data GHCiDRF.T = GHCiDRF.MkT {GHCiDRF.foo :: Int, ...} -- Defined at GHCiDRF.hs:3:16 @@ -36,7 +36,6 @@ data GHCiDRF.T = GHCiDRF.MkT {..., GHCiDRF.bar :: Int} type GHCiDRF.U :: * data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} -- Defined at GHCiDRF.hs:4:16 - :11:1: error: [GHC-87543] Ambiguous occurrence ‘GHCiDRF.bar’. It could refer to @@ -46,3 +45,4 @@ data GHCiDRF.U = GHCiDRF.MkU {GHCiDRF.bar :: Bool} or the field ‘bar’ belonging to data constructor ‘MkU’, imported qualified from ‘GHCiDRF’ (and originally defined at GHCiDRF.hs:4:16-18). + ===================================== testsuite/tests/overloadedrecflds/ghci/T19314.stdout ===================================== @@ -1,6 +1,5 @@ w :: [a] -> a x :: [a] -> a - :1:1: error: [GHC-88464] Variable not in scope: y Suggested fix: @@ -12,3 +11,4 @@ x :: [a] -> a Suggested fix: Notice that ‘z’ is a field selector that has been suppressed by NoFieldSelectors. + ===================================== testsuite/tests/overloadedrecflds/ghci/duplicaterecfldsghci01.stdout ===================================== @@ -7,7 +7,6 @@ type T :: * -> * data T a = MkT {foo :: Bool, ...} -- Defined at :4:18 True - :1:1: error: [GHC-87543] Ambiguous occurrence ‘foo’. It could refer to @@ -15,6 +14,7 @@ True defined at :3:16, or the field ‘foo’ of record ‘T’, defined at :4:18. + type U :: * data U = MkU {foo :: Int} -- Defined at :12:16 ===================================== testsuite/tests/rename/should_compile/T13839.stdout ===================================== @@ -1,5 +1,5 @@ - T13839a.hs:10:1: warning: [GHC-40910] [-Wunused-top-binds (in -Wextra, -Wunused-binds)] Defined but not used: ‘nonUsed’ + nonUsed :: () nonUsed :: () ===================================== testsuite/tests/th/T7276a.stdout ===================================== @@ -1,4 +1,3 @@ - :3:9: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] • Couldn't match type ‘[Dec]’ with ‘Exp’ Expected: Q Exp @@ -17,3 +16,4 @@ (deferred type error) Code: x • In the untyped splice: $x + ===================================== testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr ===================================== @@ -1,4 +1,3 @@ - CaretDiagnostics1.hs:7:8-15: error: [GHC-83865] • Couldn't match expected type ‘IO a0’ with actual type ‘Int’ • In the second argument of ‘(+)’, namely ‘(3 :: Int)’ @@ -68,3 +67,4 @@ CaretDiagnostics1.hs:23:25-26: error: [GHC-83865] | 23 | tabby2 = () | ^^ + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1261ec2fc0db926357c9d5dbbc0a69a621902694...bb67e8d5678a4a6a7d54606b623141bc44ef3b8d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1261ec2fc0db926357c9d5dbbc0a69a621902694...bb67e8d5678a4a6a7d54606b623141bc44ef3b8d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 05:41:57 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 01:41:57 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Fix missing escaping-kind check in tcPatSynSig Message-ID: <662b3ea58482c_3801e2101da5041346@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ee2319aa by Simon Peyton Jones at 2024-04-26T01:41:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 3828ccbd by Alan Zimmerman at 2024-04-26T01:41:49-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 4ceb6077 by Andrew Lelechenko at 2024-04-26T01:41:50-04:00 Document that setEnv is not thread-safe - - - - - 12 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/PprExportWarn.hs - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7c8f631781cdbb2aee71e1d3571c3d704739f937...4ceb6077ff4f599a6ae2a757470db546caa7cb41 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7c8f631781cdbb2aee71e1d3571c3d704739f937...4ceb6077ff4f599a6ae2a757470db546caa7cb41 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 06:10:12 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 26 Apr 2024 02:10:12 -0400 Subject: [Git][ghc/ghc][wip/T24676] Fix a QuickLook bug Message-ID: <662b454416c95_3801e21450c08482b1@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: 3b28a6c9 by Simon Peyton Jones at 2024-04-26T08:15:43+02:00 Fix a QuickLook bug This MR fixes the bug exposed by #24676. The problem was that quickLookArg was trying to avoid calling tcInstFun unnecessarily; but it was in fact necessary. But that in turn forced me into a significant refactoring, putting more fields into EValArgQL. I added a lot of new material to Note [Quick Look at value arguments] It is a bit more subtle than I would like, but the overall plan is rather clearer now than it was. - - - - - 10 changed files: - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Unify.hs - + testsuite/tests/impredicative/T24676.hs - testsuite/tests/impredicative/all.T - testsuite/tests/typecheck/should_fail/T2846b.stderr Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -29,6 +29,7 @@ module GHC.Core.TyCo.FVs -- Any and No Free vars anyFreeVarsOfType, anyFreeVarsOfTypes, anyFreeVarsOfCo, noFreeVarsOfType, noFreeVarsOfTypes, noFreeVarsOfCo, + anyFreeVarsOfTypeM, -- * Free type constructors tyConsOfType, tyConsOfTypes, @@ -58,7 +59,7 @@ import {-# SOURCE #-} GHC.Core.Coercion( coercionLKind ) import GHC.Builtin.Types.Prim( funTyFlagTyCon ) -import Data.Monoid as DM ( Endo(..), Any(..) ) +import Data.Monoid as DM ( Any(..) ) import GHC.Core.TyCo.Rep import GHC.Core.TyCon import GHC.Core.Coercion.Axiom( coAxiomTyCon ) @@ -74,6 +75,8 @@ import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Data.Pair +import Data.Semigroup + {- %************************************************************************ %* * @@ -974,6 +977,36 @@ noFreeVarsOfCo co = not $ DM.getAny (f co) where (_, _, f, _) = foldTyCo (afvFolder (const True)) emptyVarSet +{- ********************************************************************* +* * + Folding over free vars +* * +********************************************************************* -} + +newtype AnyM m = AM { unAnyM :: m Bool } + +instance Monad m => Semigroup (AnyM m) where + AM ml <> AM mr = AM (do { l <- ml; if l then return True else mr }) + +instance Monad m => Monoid (AnyM m) where + mempty = AM (return False) + +{-# INLINE afvFolderM #-} -- so that specialization to (const True) works +afvFolderM :: Monad m => (TyCoVar -> m Bool) -> TyCoFolder TyCoVarSet (AnyM m) +afvFolderM check_fv = TyCoFolder { tcf_view = noView + , tcf_tyvar = do_tv, tcf_covar = mempty + , tcf_hole = mempty, tcf_tycobinder = do_bndr } + where + do_bndr is tcv _ = extendVarSet is tcv + do_tv is tv | tv `elemVarSet` is = AM (return False) + | otherwise = AM (check_fv tv) + +anyFreeVarsOfTypeM :: Monad m => (TyCoVar -> m Bool) -> Type -> m Bool +-- Returns True if check_fv returns True of any free var of the type +anyFreeVarsOfTypeM check_fv ty = unAnyM (f ty) + where (f, _, _, _) = foldTyCo (afvFolderM check_fv) emptyVarSet + + {- ********************************************************************* * * scopedSort ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -151,7 +151,7 @@ tcInferSigma inst (L loc rn_expr) do { (fun@(rn_fun,fun_ctxt), rn_args) <- splitHsApps rn_expr ; do_ql <- wantQuickLook rn_fun ; (tc_fun, fun_sigma) <- tcInferAppHead fun - ; (_delta, inst_args, app_res_sigma) <- tcInstFun do_ql inst (tc_fun, fun_ctxt) fun_sigma rn_args + ; (_delta, inst_args, app_res_sigma) <- tcInstFun do_ql inst fun_ctxt tc_fun fun_sigma rn_args ; _tc_args <- tcValArgs do_ql inst_args ; return app_res_sigma } @@ -319,7 +319,9 @@ The latter is much better. That is why we call unifyExpectedType before tcValArgs. -} -tcApp :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) +tcApp :: HsExpr GhcRn + -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised + -> TcM (HsExpr GhcTc) -- See Note [tcApp: typechecking applications] tcApp rn_expr exp_res_ty = do { (fun@(rn_fun, fun_ctxt), rn_args) <- splitHsApps rn_expr @@ -333,40 +335,39 @@ tcApp rn_expr exp_res_ty -- Instantiate ; do_ql <- wantQuickLook rn_fun - ; (delta, inst_args, app_res_rho) <- tcInstFun do_ql True (tc_fun, fun_ctxt) fun_sigma rn_args + ; (delta, inst_args, app_res_rho) + <- tcInstFun do_ql True fun_ctxt tc_fun fun_sigma rn_args -- Quick look at result ; app_res_rho <- if do_ql then quickLookResultType delta app_res_rho exp_res_ty else return app_res_rho + ; finishApp do_ql rn_expr fun tc_fun inst_args app_res_rho exp_res_ty } + +finishApp :: Bool -> HsExpr GhcRn -> (HsExpr GhcRn, AppCtxt) + -> HsExpr GhcTc -> [HsExprArg 'TcpInst] + -> TcSigmaType + -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised + -> TcM (HsExpr GhcTc) +finishApp do_ql rn_expr (rn_fun, fun_ctxt) tc_fun inst_args app_res_rho exp_res_ty + = do { ds_flag <- getDeepSubsumptionFlag + -- Unify with expected type from the context -- See Note [Unify with expected type before typechecking arguments] -- - -- perhaps_add_res_ty_ctxt: Inside an expansion, the addFunResCtxt stuff is - -- more confusing than helpful because the function at the head isn't in - -- the source program; it was added by the renamer. See - -- Note [Handling overloaded and rebindable constructs] in GHC.Rename.Expr - ; let perhaps_add_res_ty_ctxt thing_inside - | insideExpansion fun_ctxt - = addHeadCtxt fun_ctxt thing_inside - | otherwise - = addFunResCtxt rn_fun rn_args app_res_rho exp_res_ty $ - thing_inside - -- Match up app_res_rho: the result type of rn_expr -- with exp_res_ty: the expected result type - ; do_ds <- xoptM LangExt.DeepSubsumption ; res_wrap <- perhaps_add_res_ty_ctxt $ - if not do_ds - then -- No deep subsumption + case ds_flag of + Shallow -> -- No deep subsumption -- app_res_rho and exp_res_ty are both rho-types, -- so with simple subsumption we can just unify them -- No need to zonk; the unifier does that do { co <- unifyExpectedType rn_expr app_res_rho exp_res_ty ; return (mkWpCastN co) } - else -- Deep subsumption + Deep -> -- Deep subsumption -- Even though both app_res_rho and exp_res_ty are rho-types, -- they may have nested polymorphism, so if deep subsumption -- is on we must call tcSubType. @@ -387,11 +388,8 @@ tcApp rn_expr exp_res_ty ; whenDOptM Opt_D_dump_tc_trace $ do { inst_args <- liftZonkM $ mapM zonkArg inst_args -- Only when tracing ; traceTc "tcApp }" (vcat [ text "rn_fun:" <+> ppr rn_fun - , text "rn_args:" <+> ppr rn_args , text "inst_args" <+> brackets (pprWithCommas pprHsExprArgTc inst_args) , text "do_ql: " <+> ppr do_ql - , text "fun_sigma: " <+> ppr fun_sigma - , text "delta: " <+> ppr delta , text "app_res_rho:" <+> ppr app_res_rho , text "exp_res_ty:" <+> ppr exp_res_ty , text "rn_expr:" <+> ppr rn_expr @@ -401,6 +399,18 @@ tcApp rn_expr exp_res_ty -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } + where + -- perhaps_add_res_ty_ctxt: Inside an expansion, the addFunResCtxt stuff is + -- more confusing than helpful because the function at the head isn't in + -- the source program; it was added by the renamer. See + -- Note [Handling overloaded and rebindable constructs] in GHC.Rename.Expr + perhaps_add_res_ty_ctxt thing_inside + | insideExpansion fun_ctxt + = addHeadCtxt fun_ctxt thing_inside + | otherwise + = addFunResCtxt rn_fun inst_args app_res_rho exp_res_ty $ + thing_inside + -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool @@ -430,9 +440,9 @@ zonkQuickLook do_ql ty -- see what is going on. For that reason, it is not a full zonk: add -- more if you need it. zonkArg :: HsExprArg 'TcpInst -> ZonkM (HsExprArg 'TcpInst) -zonkArg eva@(EValArg { eva_arg_ty = Scaled m ty }) +zonkArg eva@(EValArg { ea_arg_ty = Scaled m ty }) = do { ty' <- zonkTcType ty - ; return (eva { eva_arg_ty = Scaled m ty' }) } + ; return (eva { ea_arg_ty = Scaled m ty' }) } zonkArg arg = return arg @@ -442,60 +452,93 @@ zonkArg arg = return arg tcValArgs :: Bool -- Quick-look on? -> [HsExprArg 'TcpInst] -- Actual argument -> TcM [HsExprArg 'TcpTc] -- Resulting argument -tcValArgs do_ql args - = mapM tc_arg args - where - tc_arg :: HsExprArg 'TcpInst -> TcM (HsExprArg 'TcpTc) - tc_arg (EPrag l p) = return (EPrag l (tcExprPrag p)) - tc_arg (EWrap w) = return (EWrap w) - tc_arg (ETypeArg l hs_ty ty) = return (ETypeArg l hs_ty ty) - - tc_arg eva@(EValArg { eva_arg = arg, eva_arg_ty = Scaled mult arg_ty - , eva_ctxt = ctxt }) - = do { -- Crucial step: expose QL results before checking arg_ty - -- So far as the paper is concerned, this step applies - -- the poly-substitution Theta, learned by QL, so that we - -- "see" the polymorphism in that argument type. E.g. - -- (:) e ids, where ids :: [forall a. a->a] - -- (:) :: forall p. p->[p]->[p] - -- Then Theta = [p :-> forall a. a->a], and we want - -- to check 'e' with expected type (forall a. a->a) - -- See Note [Instantiation variables are short lived] - arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty - - -- Now check the argument - ; arg' <- tcScalingUsage mult $ - do { traceTc "tcEValArg" $ - vcat [ ppr ctxt - , text "arg type:" <+> ppr arg_ty - , text "arg:" <+> ppr arg ] - ; tcEValArg ctxt arg arg_ty } - - ; return (eva { eva_arg = ValArg arg' - , eva_arg_ty = Scaled mult arg_ty }) } - -tcEValArg :: AppCtxt -> EValArg 'TcpInst -> TcSigmaTypeFRR -> TcM (LHsExpr GhcTc) --- Typecheck one value argument of a function call -tcEValArg ctxt (ValArg larg@(L arg_loc arg)) exp_arg_sigma +tcValArgs do_ql args = mapM (tcValArg do_ql) args + +tcValArg :: Bool -- Quick-look on? + -> HsExprArg 'TcpInst -- Actual argument + -> TcM (HsExprArg 'TcpTc) -- Resulting argument +tcValArg _ (EPrag l p) = return (EPrag l (tcExprPrag p)) +tcValArg _ (EWrap w) = return (EWrap w) +tcValArg _ (ETypeArg l hs_ty ty) = return (ETypeArg l hs_ty ty) + +tcValArg do_ql (EValArg { ea_ctxt = ctxt + , ea_arg = larg@(L arg_loc arg) + , ea_arg_ty = Scaled mult arg_ty }) = addArgCtxt ctxt larg $ - do { arg' <- tcPolyExpr arg (mkCheckExpType exp_arg_sigma) - ; return (L arg_loc arg') } - -tcEValArg ctxt (ValArgQL { va_expr = larg@(L arg_loc _) - , va_fun = (inner_fun, fun_ctxt) - , va_args = inner_args - , va_ty = app_res_rho }) exp_arg_sigma + do { traceTc "tcValArg" $ + vcat [ ppr ctxt + , text "arg type:" <+> ppr arg_ty + , text "arg:" <+> ppr arg ] + + -- Crucial step: expose QL results before checking arg_ty + -- So far as the paper is concerned, this step applies + -- the poly-ubstitution Theta, learned by QL, so that we + -- "see" the polymorphism in that argument type. E.g. + -- (:) e ids, where ids :: [forall a. a->a] + -- (:) :: forall p. p->[p]->[p] + -- Then Theta = [p :-> forall a. a->a], and we want + -- to check 'e' with expected type (forall a. a->a) + -- See Note [Instantiation variables are short lived] + ; arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty + + -- Now check the argument + ; arg' <- tcScalingUsage mult $ + tcPolyExpr arg (mkCheckExpType arg_ty) + + ; return (EValArg { ea_ctxt = ctxt + , ea_arg = L arg_loc arg' + , ea_arg_ty = Scaled mult arg_ty }) } + +tcValArg do_ql (EValArgQL { eaql_status = ql_status + , eaql_ctxt = ctxt + , eaql_arg_ty = Scaled mult arg_ty + , eaql_larg = larg@(L arg_loc rn_expr) + , eaql_head = rn_head + , eaql_tc_fun = tc_fun + , eaql_args = inst_args + , eaql_res_rho = res_rho }) = addArgCtxt ctxt larg $ - do { traceTc "tcEValArgQL {" (vcat [ ppr inner_fun <+> ppr inner_args ]) - ; tc_args <- tcValArgs True inner_args + do { -- Expose QL results + arg_ty <- liftZonkM $ zonkQuickLook do_ql arg_ty + + ; traceTc "tcEValArgQL {" (vcat [ ppr rn_head + , text "status:" <+> ppr ql_status + , text "res_rho:" <+> ppr res_rho + , text "arg_ty:" <+> ppr arg_ty + , text "args:" <+> ppr inst_args ]) + + ; ds_flag <- getDeepSubsumptionFlag + ; (wrap, arg') + <- tcScalingUsage mult $ + tcSkolemise ds_flag GenSigCtxt arg_ty $ \ arg_rho -> + -- Tricky point: with deep subsumption, even if ql_status=QLUnified + -- arg_ty will be a rho-type (no top-level foralls), but it may have + -- /nested/ foralls; so if -XDeepSubsumption is on we should deeply + -- skolemise it, in order to pass a deeply-skolemised type to finishApp. + -- Example from haskeline:System.Console.Haskeline.Backend.Terminfo + -- output $ blah + -- output :: TermAction -> ActionM () + -- type ActionM a = forall m . (..) => ActionT (Draw m) a + do { resume_ql_arg ql_status arg_rho + ; finishApp do_ql rn_expr rn_head tc_fun inst_args res_rho + (Check arg_rho) } - ; co <- unifyType Nothing app_res_rho exp_arg_sigma - ; arg' <- mkHsWrapCo co <$> rebuildHsApps inner_fun fun_ctxt tc_args app_res_rho ; traceTc "tcEValArgQL }" $ - vcat [ text "inner_fun:" <+> ppr inner_fun - , text "app_res_rho:" <+> ppr app_res_rho - , text "exp_arg_sigma:" <+> ppr exp_arg_sigma ] - ; return (L arg_loc arg') } + vcat [ text "rn_head:" <+> ppr rn_head + , text "res_rho:" <+> ppr res_rho ] + ; return (EValArg { ea_ctxt = ctxt + , ea_arg = L arg_loc (mkHsWrap wrap arg') + , ea_arg_ty = Scaled mult arg_ty }) } + where + resume_ql_arg QLUnified _ + = return () + resume_ql_arg (QLIndependent delta wc) arg_rho + = -- A tricky function! + -- See Note [Quick Look at value arguments] wrinkle (QLA4) + do { unless (isEmptyVarSet delta) $ -- Optimisation only + do { demoteQLDelta delta + ; qlUnify delta arg_rho res_rho } + ; emitConstraints wc } {- ********************************************************************* * * @@ -503,11 +546,6 @@ tcEValArg ctxt (ValArgQL { va_expr = larg@(L arg_loc _) * * ********************************************************************* -} -type Delta = TcTyVarSet -- Set of instantiation variables, - -- written \kappa in the QL paper - -- Just a set of ordinary unification variables, - -- but ones that QL may fill in with polytypes - tcInstFun :: Bool -- True <=> Do quick-look -> Bool -- False <=> Instantiate only /inferred/ variables at the end -- so may return a sigma-type @@ -517,17 +555,18 @@ tcInstFun :: Bool -- True <=> Do quick-look -- in tcInferSigma, which is used only to implement :type -- Otherwise we do eager instantiation; in Fig 5 of the paper -- |-inst returns a rho-type - -> (HsExpr GhcTc, AppCtxt) + -> AppCtxt + -> HsExpr GhcTc -- ^ For error messages and to retrieve concreteness information -- of the function -> TcSigmaType -> [HsExprArg 'TcpRn] -> TcM ( Delta , [HsExprArg 'TcpInst] , TcSigmaType ) --- This function implements the |-inst judgement in Fig 4, plus the +-- This crucial function implements the |-inst judgement in Fig 4, plus the -- modification in Fig 5, of the QL paper: -- "A quick look at impredicativity" (ICFP'20). -tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args +tcInstFun do_ql inst_final fun_ctxt tc_fun fun_sigma rn_args = do { traceTc "tcInstFun" (vcat [ text "tc_fun" <+> ppr tc_fun , text "fun_sigma" <+> ppr fun_sigma , text "fun_ctxt" <+> ppr fun_ctxt @@ -535,15 +574,11 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args , text "do_ql" <+> ppr do_ql ]) ; go emptyVarSet [] [] fun_sigma rn_args } where - fun_orig - | VAExpansion (OrigStmt{}) _ _ <- fun_ctxt - = DoOrigin - | VAExpansion (OrigPat pat) _ _ <- fun_ctxt - = DoPatOrigin pat - | VAExpansion (OrigExpr e) _ _ <- fun_ctxt - = exprCtOrigin e - | VACall e _ _ <- fun_ctxt - = exprCtOrigin e + fun_orig = case fun_ctxt of + VAExpansion (OrigStmt{}) _ _ -> DoOrigin + VAExpansion (OrigPat pat) _ _ -> DoPatOrigin pat + VAExpansion (OrigExpr e) _ _ -> exprCtOrigin e + VACall e _ _ -> exprCtOrigin e -- These are the type variables which must be instantiated to concrete -- types. See Note [Representation-polymorphic Ids with no binding] @@ -640,7 +675,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- nested forall a. Eq a => forall b. Show b => blah -- Rule ITVDQ from the GHC Proposal #281 - go1 delta acc so_far fun_ty ((EValArg { eva_arg = ValArg arg }) : rest_args) + go1 delta acc so_far fun_ty ((EValArg { ea_arg = arg }) : rest_args) | Just (tvb, body) <- tcSplitForAllTyVarBinder_maybe fun_ty = assertPpr (binderFlag tvb == Required) (ppr fun_ty $$ ppr arg) $ -- Any invisible binders have been instantiated by IALL above, @@ -661,10 +696,10 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args = go1 delta (EPrag sp prag : acc) so_far fun_ty args -- Rule ITYARG from Fig 4 of the QL paper - go1 delta acc so_far fun_ty ( ETypeArg { eva_ctxt = ctxt, eva_hs_ty = hs_ty } + go1 delta acc so_far fun_ty ( ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty } : rest_args ) = do { (ty_arg, inst_ty) <- tcVTA fun_conc_tvs fun_ty hs_ty - ; let arg' = ETypeArg { eva_ctxt = ctxt, eva_hs_ty = hs_ty, eva_ty = ty_arg } + ; let arg' = ETypeArg { ea_ctxt = ctxt, ea_hs_ty = hs_ty, ea_ty_arg = ty_arg } ; go delta (arg' : acc) so_far inst_ty rest_args } -- Rule IVAR from Fig 4 of the QL paper: @@ -695,7 +730,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- When we come to unify the nus (in qlUnify), we will call -- unifyKind on the kinds. This will do the right thing, even though -- we are manually filling in the nu metavariables. - new_arg_tv (ValArg (L _ arg)) i = + new_arg_tv (L _ arg) i = newOpenFlexiFRRTyVar $ FRRExpectedFunTy (ExpectedFunTyArg (HsExprTcThing tc_fun) arg) i ; arg_nus <- zipWithM new_arg_tv @@ -721,7 +756,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args -- Rule IARG from Fig 4 of the QL paper: go1 delta acc so_far fun_ty - (eva@(EValArg { eva_arg = ValArg arg, eva_ctxt = ctxt }) : rest_args) + (eva@(EValArg { ea_arg = arg, ea_ctxt = ctxt }) : rest_args) = do { let herald = case fun_ctxt of VAExpansion (OrigStmt{}) _ _ -> ExpectedFunTySyntaxOp DoOrigin tc_fun _ -> ExpectedFunTyArg (HsExprTcThing tc_fun) (unLoc arg) @@ -739,10 +774,9 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args then addArgCtxt ctxt arg $ -- Context needed for constraints -- generated by calls in arg - quickLookArg delta arg arg_ty - else return (delta, ValArg arg) - ; let acc' = eva { eva_arg = arg', eva_arg_ty = arg_ty } - : addArgWrap wrap acc + quickLookArg delta ctxt arg arg_ty + else return (delta, eva { ea_arg_ty = arg_ty }) + ; let acc' = arg' : addArgWrap wrap acc ; go delta' acc' (arg_ty:so_far) res_ty rest_args } -- Is the argument supposed to instantiate a forall? @@ -759,7 +793,7 @@ looks_like_type_arg ETypeArg{} = -- The argument is clearly supposed to instantiate an invisible forall, -- i.e. when we see `f @a`, we expect `f :: forall x. t`. True -looks_like_type_arg EValArg{ eva_arg = ValArg (L _ e) } = +looks_like_type_arg EValArg{ ea_arg = L _ e } = -- Check if the argument is supposed to instantiate a visible forall, -- i.e. when we see `f (type Int)`, we expect `f :: forall x -> t`, -- but not if we see `f True`. @@ -1440,109 +1474,233 @@ need to zonk `body` before performing the substitution above. See test case ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The function quickLookArg implements the "QL argument" judgement of the QL paper, in Fig 5 of "A quick look at impredicativity" (ICFP 2020), -rather directly. +rather directly. The key rule, implemented by `quickLookArg` is -Wrinkles: + G |-h h:sg -- Find the type of the head + G |-inst sg;pis ~> phis;rho_r -- tcInstFun on the args + (A) rho = T sgs OR (B) fiv(phis) = emptyset -- can_do_ql + -------------------------------------- APP-QL + G |-ql h pis : rho ~> qlUnify( rho, rho_r ) -* We avoid zonking, so quickLookArg thereby sees the argument type /before/ - the QL substitution Theta is applied to it. So we achieve argument-order - independence for free (see 5.7 in the paper). +(The paper uses a lightning-bolt where we use "ql".) The most straightforward +way to implement this rule for a call (f e1 ... en) would be: + + 1. Take a quick look at the argumets e1..en to guide instantiation + of the function f. + 2. Then typecheck e1..en from scratch. + +That's wasteful, because in Step 1, the quick look at each argument, say (g +h1..hm), involves instantiating `h` and taking a quick look at /its/ +arguments. Then in Step 2 we typecheck (g h1..hm) and again take a quick look +at its arguments. This is quadratic in the nesting depth of the arguments. + +Instead, after the quick look, we /save/ the work we have done in an EValArgQL +record, and /resume/ it later. The way to think of it is this: + + * `tcApp` typechecks an application. It is strutured into two: + - the "initial" part, especially `tcInstFun` + - the "finish" part, `finishApp`, which completes the job -* When we quick-look at an argument, we save the work done, by returning - an EValArg with a ValArgQL inside it. (It started life with a ValArg - inside.) The ValArgQL remembers all the work that QL did (notably, - decomposing the argument and instantiating) so that tcValArgs does - not need to repeat it. Rather neat, and remarkably easy. + * quickLookArg (which takes a quick look at the argument) + + - Does the "initial" part of `tcApp`, especially `tcInstFun` + + - Captures the result in an EValArgQL record + + - Later, `tcValArg` starts from the EValArgQL record, and + completes the job of tpyechecking the appication by calling + `finishApp` + +This turned out to be more subtle than I expected. Wrinkles: + +(QLA1) We avoid zonking, so quickLookArg thereby sees the argument type /before/ + the QL substitution Theta is applied to it. So we achieve argument-order + independence for free (see 5.7 in the paper). See the `guarded` predictate + in `quickLookArg`. + +(QLA2) `quickLookArg` decides whether or not premises (A) and (B) of the + quick-look-arg jugement APP-QL are satisfied; this is captured in `can_do_ql`: + + - can_do_ql=True: + get info from argument by unifying the argument result type with + the type expected by the caller, using `qlUnify` in `quickLookResultType` + Capture the work done in EValArgQL with eaql_status = QLUnified. + + - can_do_ql=False: + do not get info from argument; no `qlUnify`. Instead just save the + work done in EValArgQL, with eaql_status = QLIndependent. + +(QLA3) Deciding whether the premises are satisfied involves calling `tcInstFun` + (which takes quite some work becuase it calls quickLookArg on nested calls). + That's why we want to capture the work done, in EValArgQL. + + Do we really have to call `tcInstFun` before deciding `can_do_ql`? Yes. + Suppose ids :: [forall a. a->a], and consider + (:) (reverse ids) blah + `tcApp` on the outer call will instantiate (:) with `kappa`, and take a + quick look at (reverse ids). Only after instantiating `reverse` with kappa2, + quick-looking at `ids` can we discover that (kappa2:=forall a. a->a), which + satisfies premise (B) of can_do_ql. + +(QLA4) When we resume typechecking an argument, in `tcValArg`, it's fairly + easy if eaql_status=QLUnified (see (QLA2)). But for QLIndependent things + are a bit tricky; see function `resume_ql-arg`: + + - quickLookArg has not yet done `qlUnify` with the calling context. We + must do so now. Example: choose [] ids, + where ids :: [forall a. a->a] + choose :: a -> a -> a + We instantiate choose with `kappa` and discover from `ids` that + (kappa = [forall a. a->a]). Now we resume typechecking argument [], and + we must take advantage of what we have now discovered about `kappa`, + to typecheck [] :: [forall a. a->a] + + - Calling `tcInstFun` on the argument may have emitted some constraints, which + we carefully captured in `quickLookArg` and stored in the EValArgQL. We must + now emit them with `emitConstraints` + + - When we quick-looked at the argument we instantiated with say kappa2. But + the /level-number/ on kappa2 will be from the original `tcApp`, whereas + we may now be more deeply nested; see the `tcSkolemise` in `tcValArg` for + EValArgQL. We carefully kept those kappas, and we now /demote/ them to the + ambient level with `demoteQLDelta`. + + The demotion seems right butis not very beautiful; e.g. `demoteDeltaTyVarTo` + deliberately disobeys a sanity check otherwise enforced by writeMetaTyVar. -} ----------------- quickLookArg :: Delta + -> AppCtxt -> LHsExpr GhcRn -- ^ Argument -> Scaled TcSigmaTypeFRR -- ^ Type expected by the function - -> TcM (Delta, EValArg 'TcpInst) + -> TcM (Delta, HsExprArg 'TcpInst) -- See Note [Quick Look at value arguments] -- -- The returned Delta is a superset of the one passed in -- with added instantiation variables from -- (a) the call itself -- (b) the arguments of the call -quickLookArg delta larg (Scaled _ arg_ty) - | isEmptyVarSet delta = skipQuickLook delta larg - | otherwise = go arg_ty +quickLookArg delta ctxt larg orig_arg_ty + | isEmptyVarSet delta = skipQuickLook delta ctxt larg orig_arg_ty + | otherwise = go orig_arg_ty where - guarded = isGuardedTy arg_ty + guarded = isGuardedTy orig_arg_ty -- NB: guardedness is computed based on the original, - -- unzonked arg_ty, so we deliberately do not exploit - -- guardedness that emerges a result of QL on earlier args - - go arg_ty | not (isRhoTy arg_ty) - = skipQuickLook delta larg - - -- This top-level zonk step, which is the reason - -- we need a local 'go' loop, is subtle - -- See Section 9 of the QL paper - | Just kappa <- getTyVar_maybe arg_ty - , kappa `elemVarSet` delta - = do { info <- readMetaTyVar kappa - ; case info of - Indirect arg_ty' -> go arg_ty' - Flexi -> quickLookArg1 guarded delta larg arg_ty } - - | otherwise - = quickLookArg1 guarded delta larg arg_ty - -isGuardedTy :: TcType -> Bool -isGuardedTy ty + -- unzonked arg_ty (before calling `go`), so that we deliberately do + -- not exploit guardedness that emerges a result of QL on earlier args + + go sc_arg_ty@(Scaled mult arg_ty) + | not (isRhoTy arg_ty) + = skipQuickLook delta ctxt larg sc_arg_ty + + -- This top-level zonk step, which is the reason we need a local 'go' loop, + -- is subtle. See Section 9 of the QL paper + | Just kappa <- getTyVar_maybe arg_ty + , kappa `elemVarSet` delta + = do { info <- readMetaTyVar kappa + ; case info of + Indirect arg_ty'' -> go (Scaled mult arg_ty'') + Flexi -> quickLookArg1 guarded delta ctxt larg sc_arg_ty } + + | otherwise + = quickLookArg1 guarded delta ctxt larg sc_arg_ty + +isGuardedTy :: Scaled TcType -> Bool +isGuardedTy (Scaled _ ty) | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal | Just {} <- tcSplitAppTy_maybe ty = True | otherwise = False -quickLookArg1 :: Bool -> Delta -> LHsExpr GhcRn -> TcSigmaTypeFRR - -> TcM (Delta, EValArg 'TcpInst) -quickLookArg1 guarded delta larg@(L _ arg) arg_ty - = do { ((rn_fun, fun_ctxt), rn_args) <- splitHsApps arg +quickLookArg1 :: Bool -- Guarded + -> Delta -- Always non-empty + -> AppCtxt -> LHsExpr GhcRn + -> Scaled TcRhoType -- Not deeply skolemised, even with -XDeepSubsumption + -> TcM (Delta, HsExprArg 'TcpInst) +-- quickLookArg1 implements the "QL Argument" judgement in Fig 5 of the paper +quickLookArg1 guarded delta ctxt larg@(L _ arg) sc_arg_ty@(Scaled _ arg_ty) + = do { (rn_head@(rn_fun, fun_ctxt), rn_args) <- splitHsApps arg + + -- Step 1: get the type of the head of the argument ; mb_fun_ty <- tcInferAppHead_maybe rn_fun ; traceTc "quickLookArg 1" $ vcat [ text "arg:" <+> ppr arg + , text "arg_ty:" <+> ppr arg_ty , text "head:" <+> ppr rn_fun <+> dcolon <+> ppr mb_fun_ty , text "args:" <+> ppr rn_args ] ; case mb_fun_ty of { - Nothing -> -- fun is too complicated - skipQuickLook delta larg ; + Nothing -> skipQuickLook delta ctxt larg sc_arg_ty ; -- fun is too complicated Just (tc_fun, fun_sigma) -> - do { let no_free_kappas = findNoQuantVars fun_sigma rn_args - ; traceTc "quickLookArg 2" $ - vcat [ text "no_free_kappas:" <+> ppr no_free_kappas - , text "guarded:" <+> ppr guarded - , text "tc_fun:" <+> ppr tc_fun - , text "fun_sigma:" <+> ppr fun_sigma ] - ; if not (guarded || no_free_kappas) - then skipQuickLook delta larg - else + -- Step 2: use |-inst to instantiate the head applied to the arguments do { do_ql <- wantQuickLook rn_fun - ; (delta_app, inst_args, app_res_rho) <- tcInstFun do_ql True (tc_fun, fun_ctxt) fun_sigma rn_args - ; traceTc "quickLookArg 3" $ + ; ((delta_app, inst_args, app_res_rho), wanted) + <- captureConstraints $ + tcInstFun do_ql True fun_ctxt tc_fun fun_sigma rn_args + + ; let -- mk_ql_arg captures the results so far, for resumption in tcValArg + mk_ql_arg status + = EValArgQL { eaql_status = status + , eaql_ctxt = ctxt + , eaql_arg_ty = sc_arg_ty + , eaql_larg = larg + , eaql_head = rn_head + , eaql_tc_fun = tc_fun + , eaql_args = inst_args + , eaql_res_rho = app_res_rho } + + ; traceTc "quickLookArg 2" $ vcat [ text "arg:" <+> ppr arg , text "delta:" <+> ppr delta , text "delta_app:" <+> ppr delta_app , text "arg_ty:" <+> ppr arg_ty , text "app_res_rho:" <+> ppr app_res_rho ] - -- Do quick-look unification - -- NB: arg_ty may not be zonked, but that's ok - ; let delta' = delta `unionVarSet` delta_app - ; qlUnify delta' arg_ty app_res_rho - - ; let ql_arg = ValArgQL { va_expr = larg - , va_fun = (tc_fun, fun_ctxt) - , va_args = inst_args - , va_ty = app_res_rho } - ; return (delta', ql_arg) } } } } + -- Step 3: check the two other premises of APP-lightning-bolt (Fig 5 in the paper) + -- Namely: (A) is rho guarded, and (B) fiv(rho_r) = emptyset + ; can_do_ql <- if guarded -- (A) + then return True + else not <$> anyFreeKappa delta_app app_res_rho -- (B) + -- For (B) see Note [The fiv test in quickLookArg] -skipQuickLook :: Delta -> LHsExpr GhcRn -> TcM (Delta, EValArg 'TcpInst) -skipQuickLook delta larg = return (delta, ValArg larg) + -- Step 4: do quick-look unification if either (A) or (B) hold + -- NB: arg_ty may not be zonked, but that's ok + ; if can_do_ql + then -- No generalisation will take place for this argument + -- So we can emit the constraints right now, and join its + -- instantiation variables (delta_app) with those of the caller (delta) + do { let delta' = delta `unionVarSet` delta_app + ; qlUnify delta' arg_ty app_res_rho + ; emitConstraints wanted + ; traceTc "quickLookArg unify" (ppr rn_fun <+> ppr delta') + ; return (delta', mk_ql_arg QLUnified) } + + else -- Treat this argument independently + -- Capture delta and wanted in QLIndependent for later resumption + do { traceTc "quickLookArg indep" (ppr rn_fun <+> ppr delta_app) + ; return (delta, mk_ql_arg (QLIndependent delta_app wanted)) } + }}} + +anyFreeKappa :: Delta -> TcType -> TcM Bool +-- True if there is a free instantiation variable (member of Delta) +-- in the argument type, after zonking +-- See Note [The fiv test in quickLookArg] +anyFreeKappa delta ty + = anyFreeVarsOfTypeM is_free_kappa ty + where + is_free_kappa :: TcTyVar -> TcM Bool + is_free_kappa tv | tv `elemVarSet` delta + = do { info <- readMetaTyVar tv + ; case info of + Indirect ty -> anyFreeKappa delta ty + Flexi -> return True } + | otherwise + = return False + +skipQuickLook :: Delta -> AppCtxt -> LHsExpr GhcRn -> Scaled TcRhoType + -> TcM (Delta, HsExprArg 'TcpInst) +skipQuickLook delta ctxt larg arg_ty + = return (delta, EValArg { ea_ctxt = ctxt, ea_arg = larg, ea_arg_ty = arg_ty }) ---------------- quickLookResultType :: Delta -> TcRhoType -> ExpRhoType -> TcM TcRhoType @@ -1553,7 +1711,7 @@ quickLookResultType :: Delta -> TcRhoType -> ExpRhoType -> TcM TcRhoType quickLookResultType delta app_res_rho (Check exp_rho) = -- In checking mode only, do qlUnify with the expected result type - do { unless (isEmptyVarSet delta) $ -- Optimisation only + do { unless (isEmptyVarSet delta) $ -- Optimisation only qlUnify delta app_res_rho exp_rho ; return app_res_rho } @@ -1568,11 +1726,28 @@ quickLookResultType _ app_res_rho (Infer {}) -- generator. The safe thing to do is to zonk any instantiation -- variables away. See Note [Instantiation variables are short lived] +{- Note [The fiv test in quickLookArg] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In rule APP-lightning-bolt in Fig 5 of the paper, we have to test rho_r +for having no free instantiation variables. We do this in Step 3 of quickLookArg1, +using anyFreeKappa. Example: + Suppose ids :: [forall a. a->a] + and consider Just (ids++ids) +We will instantiate Just with kappa, say, and then call + quickLookArg1 False {kappa} (ids ++ ids) kappa +The call to tcInstFun will return with app_res_rho = [forall a. a->a] +which has no free instantiation variables, so we can QL-unify + kappa ~ [Forall a. a->a] +-} + --------------------- qlUnify :: Delta -> TcType -> TcType -> TcM () -- Unify ty1 with ty2, unifying only variables in delta qlUnify delta ty1 ty2 - = do { traceTc "qlUnify" (ppr delta $$ ppr ty1 $$ ppr ty2) + = assertPpr (not (isEmptyVarSet delta)) (ppr delta $$ ppr ty1 $$ ppr ty2) $ + -- Only called with a non-empty delta + -- Empty <=> nothing to do + do { traceTc "qlUnify" (ppr delta $$ ppr ty1 $$ ppr ty2) ; go (emptyVarSet,emptyVarSet) ty1 ty2 } where go :: (TyVarSet, TcTyVarSet) @@ -1709,54 +1884,6 @@ That is the entire point of qlUnify! Wrinkles: TL;DR Calling unifyKind seems like the lesser evil. -} -{- ********************************************************************* -* * - Guardedness -* * -********************************************************************* -} - -findNoQuantVars :: TcSigmaType -> [HsExprArg 'TcpRn] -> Bool --- True <=> there are no free quantified variables --- in the result of the call --- E.g. in the call (f e1 e2), if --- f :: forall a b. a -> b -> Int return True --- f :: forall a b. a -> b -> b return False (b is free) -findNoQuantVars fun_ty args - = go emptyVarSet fun_ty args - where - need_instantiation [] = True - need_instantiation (EValArg {} : _) = True - need_instantiation _ = False - - go :: TyVarSet -> TcSigmaType -> [HsExprArg 'TcpRn] -> Bool - go bvs fun_ty args - | need_instantiation args - , (tvs, theta, rho) <- tcSplitSigmaTy fun_ty - , not (null tvs && null theta) - = go (bvs `extendVarSetList` tvs) rho args - - go bvs fun_ty [] = tyCoVarsOfType fun_ty `disjointVarSet` bvs - - go bvs fun_ty (EWrap {} : args) = go bvs fun_ty args - go bvs fun_ty (EPrag {} : args) = go bvs fun_ty args - - go bvs fun_ty args@(ETypeArg {} : rest_args) - | (tvs, body1) <- tcSplitSomeForAllTyVars (== Inferred) fun_ty - , (theta, body2) <- tcSplitPhiTy body1 - , not (null tvs && null theta) - = go (bvs `extendVarSetList` tvs) body2 args - | Just (_tv, res_ty) <- tcSplitForAllTyVarBinder_maybe fun_ty - = go bvs res_ty rest_args - | otherwise - = False -- E.g. head ids @Int - - go bvs fun_ty (EValArg {} : rest_args) - | Just (_, res_ty) <- tcSplitFunTy_maybe fun_ty - = go bvs res_ty rest_args - | otherwise - = False -- E.g. head id 'x' - - {- ********************************************************************* * * tagToEnum# ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -268,7 +268,10 @@ tcMonoExprNC (L loc expr) res_ty ; return (L loc expr') } --------------- -tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) +tcExpr :: HsExpr GhcRn + -> ExpRhoType -- DeepSubsumption <=> when checking, this type + -- is deeply skolemised + -> TcM (HsExpr GhcTc) -- Use tcApp to typecheck applications, which are treated specially -- by Quick Look. Specifically: ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -16,7 +16,7 @@ -} module GHC.Tc.Gen.Head - ( HsExprArg(..), EValArg(..), TcPass(..) + ( HsExprArg(..), TcPass(..), Delta, QLArgStatus(..) , AppCtxt(..), appCtxtLoc, insideExpansion , splitHsApps, rebuildHsApps , addArgWrap, isHsValArg @@ -47,18 +47,19 @@ import GHC.Tc.Utils.Unify import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep_syntactic ) import GHC.Tc.Utils.Instantiate import GHC.Tc.Instance.Family ( tcLookupDataFamInst ) -import GHC.Core.FamInstEnv ( FamInstEnvs ) -import GHC.Core.UsageEnv ( singleUsageUE ) import GHC.Tc.Errors.Types import GHC.Tc.Solver ( InferMode(..), simplifyInfer ) import GHC.Tc.Utils.Env import GHC.Tc.Utils.TcMType import GHC.Tc.Types.Origin +import GHC.Tc.Types.Constraint( WantedConstraints ) import GHC.Tc.Utils.TcType as TcType import GHC.Tc.Types.Evidence import GHC.Tc.Zonk.TcType +import GHC.Core.FamInstEnv ( FamInstEnvs ) +import GHC.Core.UsageEnv ( singleUsageUE ) import GHC.Core.PatSyn( PatSyn ) import GHC.Core.ConLike( ConLike(..) ) import GHC.Core.DataCon @@ -168,37 +169,55 @@ data TcPass = TcpRn -- Arguments decomposed | TcpInst -- Function instantiated | TcpTc -- Typechecked -data HsExprArg (p :: TcPass) - = -- See Note [HsExprArg] - EValArg { eva_ctxt :: AppCtxt - , eva_arg :: EValArg p - , eva_arg_ty :: !(XEVAType p) } +type Delta = TcTyVarSet -- Set of instantiation variables, + -- written \kappa in the QL paper + -- Just a set of ordinary unification variables, + -- but ones that QL may fill in with polytypes + +data HsExprArg (p :: TcPass) where -- See Note [HsExprArg] + + -- See Note [EValArg] + EValArg :: { ea_ctxt :: AppCtxt + , ea_arg_ty :: !(XEVAType p) + , ea_arg :: LHsExpr (GhcPass (XPass p)) } + -> HsExprArg p + + EValArgQL :: { eaql_status :: QLArgStatus + , eaql_ctxt :: AppCtxt + , eaql_arg_ty :: !(XEVAType 'TcpInst) -- Type expected by function + , eaql_larg :: LHsExpr GhcRn -- Original application + -- For location and error msgs + , eaql_head :: (HsExpr GhcRn, AppCtxt) -- Function of the application, + -- typechecked, plus its context + , eaql_tc_fun :: HsExpr GhcTc + , eaql_args :: [HsExprArg 'TcpInst] -- Args, instantiated + , eaql_res_rho :: TcRhoType } -- Result type of the application + -> HsExprArg 'TcpInst -- Only exists in TcpInst phase - | ETypeArg { eva_ctxt :: AppCtxt - , eva_hs_ty :: LHsWcType GhcRn -- The type arg - , eva_ty :: !(XETAType p) } -- Kind-checked type arg + ETypeArg :: { ea_ctxt :: AppCtxt + , ea_hs_ty :: LHsWcType GhcRn -- The type arg + , ea_ty_arg :: !(XETAType p) } -- Kind-checked type arg + -> HsExprArg p - | EPrag AppCtxt - (HsPragE (GhcPass (XPass p))) + EPrag :: AppCtxt -> (HsPragE (GhcPass (XPass p))) -> HsExprArg p + EWrap :: EWrap -> HsExprArg p - | EWrap EWrap +type family XETAType p where -- Type arguments + XETAType 'TcpRn = NoExtField + XETAType _ = Type + +type family XEVAType p where -- Value arguments + XEVAType 'TcpRn = NoExtField + XEVAType _ = Scaled TcSigmaType + +data QLArgStatus -- See (QLA2) in Note [Quick Look at value arguments] in GHC.Tc.Gen.App + = QLUnified -- Unified with caller + | QLIndependent Delta WantedConstraints -- Independent of caller data EWrap = EPar AppCtxt | EExpand HsThingRn | EHsWrap HsWrapper -data EValArg (p :: TcPass) where -- See Note [EValArg] - ValArg :: LHsExpr (GhcPass (XPass p)) - -> EValArg p - - ValArgQL :: { va_expr :: LHsExpr GhcRn -- Original application - -- For location and error msgs - , va_fun :: (HsExpr GhcTc, AppCtxt) -- Function of the application, - -- typechecked, plus its context - , va_args :: [HsExprArg 'TcpInst] -- Args, instantiated - , va_ty :: TcRhoType } -- Result type - -> EValArg 'TcpInst -- Only exists in TcpInst phase - data AppCtxt = VAExpansion HsThingRn @@ -254,23 +273,15 @@ type family XPass p where XPass 'TcpInst = 'Renamed XPass 'TcpTc = 'Typechecked -type family XETAType p where -- Type arguments - XETAType 'TcpRn = NoExtField - XETAType _ = Type - -type family XEVAType p where -- Value arguments - XEVAType 'TcpRn = NoExtField - XEVAType _ = Scaled Type - mkEValArg :: AppCtxt -> LHsExpr GhcRn -> HsExprArg 'TcpRn -mkEValArg ctxt e = EValArg { eva_arg = ValArg e, eva_ctxt = ctxt - , eva_arg_ty = noExtField } +mkEValArg ctxt e = EValArg { ea_arg = e, ea_ctxt = ctxt + , ea_arg_ty = noExtField } mkETypeArg :: AppCtxt -> LHsWcType GhcRn -> HsExprArg 'TcpRn mkETypeArg ctxt hs_ty = - ETypeArg { eva_ctxt = ctxt - , eva_hs_ty = hs_ty - , eva_ty = noExtField } + ETypeArg { ea_ctxt = ctxt + , ea_hs_ty = hs_ty + , ea_ty_arg = noExtField } addArgWrap :: HsWrapper -> [HsExprArg p] -> [HsExprArg p] addArgWrap wrap args @@ -392,9 +403,9 @@ rebuild_hs_apps :: HsExpr GhcTc rebuild_hs_apps fun _ [] = fun rebuild_hs_apps fun ctxt (arg : args) = case arg of - EValArg { eva_arg = ValArg arg, eva_ctxt = ctxt' } + EValArg { ea_arg = arg, ea_ctxt = ctxt' } -> rebuild_hs_apps (HsApp noExtField lfun arg) ctxt' args - ETypeArg { eva_hs_ty = hs_ty, eva_ty = ty, eva_ctxt = ctxt' } + ETypeArg { ea_hs_ty = hs_ty, ea_ty_arg = ty, ea_ctxt = ctxt' } -> rebuild_hs_apps (HsAppType ty lfun hs_ty) ctxt' args EPrag ctxt' p -> rebuild_hs_apps (HsPragE noExtField p lfun) ctxt' args @@ -736,12 +747,12 @@ isHsValArg :: HsExprArg id -> Bool isHsValArg (EValArg {}) = True isHsValArg _ = False -leadingValArgs :: [HsExprArg id] -> [EValArg id] -leadingValArgs [] = [] -leadingValArgs (arg@(EValArg {}) : args) = eva_arg arg : leadingValArgs args -leadingValArgs (EWrap {} : args) = leadingValArgs args -leadingValArgs (EPrag {} : args) = leadingValArgs args -leadingValArgs (ETypeArg {} : _) = [] +leadingValArgs :: [HsExprArg 'TcpRn] -> [LHsExpr GhcRn] +leadingValArgs [] = [] +leadingValArgs (EValArg { ea_arg = arg } : args) = arg : leadingValArgs args +leadingValArgs (EWrap {} : args) = leadingValArgs args +leadingValArgs (EPrag {} : args) = leadingValArgs args +leadingValArgs (ETypeArg {} : _) = [] isValArg :: HsExprArg id -> Bool isValArg (EValArg {}) = True @@ -753,24 +764,25 @@ isVisibleArg (ETypeArg {}) = True isVisibleArg _ = False instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where - ppr (EValArg { eva_arg = arg }) = text "EValArg" <+> ppr arg + ppr (EValArg { ea_arg = arg }) = text "EValArg" <+> ppr arg ppr (EPrag _ p) = text "EPrag" <+> ppr p - ppr (ETypeArg { eva_hs_ty = hs_ty }) = char '@' <> ppr hs_ty + ppr (ETypeArg { ea_hs_ty = hs_ty }) = char '@' <> ppr hs_ty ppr (EWrap wrap) = ppr wrap + ppr (EValArgQL { eaql_head = fun, eaql_args = args, eaql_res_rho = ty}) + = hang (text "EValArgQL" <+> ppr fun) + 2 (vcat [ ppr args, text "ea_ql_ty:" <+> ppr ty ]) + +instance Outputable QLArgStatus where + ppr QLUnified = text "QLUnified" + ppr (QLIndependent delta wc) = text "QLIndependent" <> braces (sep [ppr delta, ppr wc]) instance Outputable EWrap where ppr (EPar _) = text "EPar" ppr (EHsWrap w) = text "EHsWrap" <+> ppr w ppr (EExpand orig) = text "EExpand" <+> ppr orig -instance OutputableBndrId (XPass p) => Outputable (EValArg p) where - ppr (ValArg e) = ppr e - ppr (ValArgQL { va_fun = fun, va_args = args, va_ty = ty}) - = hang (text "ValArgQL" <+> ppr fun) - 2 (vcat [ ppr args, text "va_ty:" <+> ppr ty ]) - pprHsExprArgTc :: HsExprArg 'TcpInst -> SDoc -pprHsExprArgTc (EValArg { eva_arg = tm, eva_arg_ty = ty }) +pprHsExprArgTc (EValArg { ea_arg = tm, ea_arg_ty = ty }) = text "EValArg" <+> hang (ppr tm) 2 (dcolon <+> ppr ty) pprHsExprArgTc arg = ppr arg @@ -1514,7 +1526,7 @@ naughtiness in both branches. c.f. GHC.Tc.TyCl.Utils.mkRecSelBinds. * * ********************************************************************* -} -addFunResCtxt :: HsExpr GhcRn -> [HsExprArg 'TcpRn] +addFunResCtxt :: HsExpr GhcRn -> [HsExprArg p] -> TcType -> ExpRhoType -> TcM a -> TcM a -- When we have a mis-match in the return type of a function ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -361,12 +361,14 @@ tcDoStmts doExpr@(DoExpr _) ss@(L l stmts) res_ty ; return (HsDo res_ty doExpr (L l stmts')) } else do { expanded_expr <- expandDoStmts doExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty } + ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> + tcExpr (unLoc expanded_expr) res_ty } } tcDoStmts mDoExpr@(MDoExpr _) ss@(L _ stmts) res_ty = do { expanded_expr <- expandDoStmts mDoExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty } + ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> + tcExpr (unLoc expanded_expr) res_ty } tcDoStmts MonadComp (L l stmts) res_ty = do { stmts' <- tcStmts (HsDoStmt MonadComp) tcMcStmt stmts res_ty ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -80,7 +80,7 @@ module GHC.Tc.Utils.TcMType ( defaultTyVar, promoteMetaTyVarTo, promoteTyVarSet, quantifyTyVars, isQuantifiableTv, zonkAndSkolemise, skolemiseQuantifiedTyVar, - doNotQuantifyTyVars, + doNotQuantifyTyVars, demoteQLDelta, candidateQTyVarsOfType, candidateQTyVarsOfKind, candidateQTyVarsOfTypes, candidateQTyVarsOfKinds, @@ -2443,6 +2443,40 @@ promoteTyVarSet tvs -- Non-determinism is OK because order of promotion doesn't matter ; return (or bools) } +demoteDeltaTyVarTo :: TcLevel -> TcTyVar -> TcM () +demoteDeltaTyVarTo new_lvl tv + | MetaTv { mtv_ref = ref, mtv_tclvl = tv_lvl } <- tcTyVarDetails tv + = assertPpr (new_lvl `strictlyDeeperThan` tv_lvl) (ppr new_lvl <+> ppr tv) $ + do { info <- readTcRef ref + ; case info of { + Indirect {} -> return () ; + Flexi -> + do { cloned_tv <- cloneMetaTyVar tv + ; let rhs_tv = setMetaTyVarTcLevel cloned_tv new_lvl + ; liftZonkM $ writeTcRef ref (Indirect (TyVarTy rhs_tv)) + -- Do not go via writeMetaTyVar! In debug-mode it makes sanity check + -- on level numbers which /demoting/ deliberately disobeys + ; traceTc "demoteTyVar" (ppr tv <+> text "-->" <+> ppr rhs_tv) + ; return () } } } + | otherwise + = pprPanic "demoteDeltaTyVarTo" (ppr tv) + +demoteQLDelta :: TcTyVarSet -> TcM () +-- See Note [Quick Look at value arguments] wrinkle (QLA4) +-- in GHC.Tc.Gen.App +demoteQLDelta delta + | null tvs + = return () + | otherwise + = do { tclvl <- getTcLevel + ; assertPpr (isMetaTyVar tv1) (ppr delta) $ + when (tclvl `strictlyDeeperThan` tcTyVarLevel tv1) $ + mapM_ (demoteDeltaTyVarTo tclvl) tvs } + where + tv1 = head tvs + tvs = nonDetEltsUniqSet delta + -- Non-determinism is OK because order of promotion doesn't matter + {- %************************************************************************ %* * ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -19,7 +19,7 @@ module GHC.Tc.Utils.Unify ( buildImplicationFor, buildTvImplication, emitResidualTvConstraint, -- Skolemisation - DeepSubsumptionFlag(..), getDeepSubsumptionFlag, + DeepSubsumptionFlag(..), getDeepSubsumptionFlag, isRhoTyDS, tcSkolemise, tcSkolemiseCompleteSig, tcSkolemiseExpectedType, -- Various unifications @@ -402,7 +402,7 @@ tcSkolemiseGeneral -> ([(Name, TcInvisTVBinder)] -> TcType -> TcM result) -> TcM (HsWrapper, result) tcSkolemiseGeneral ds_flag ctxt top_ty expected_ty thing_inside - | definitely_mono ds_flag expected_ty + | isRhoTyDS ds_flag expected_ty -- Fast path for a very very common case: no skolemisation to do -- But still call checkConstraints in case we need an implication regardless = do { let sig_skol = SigSkol ctxt top_ty [] @@ -1332,15 +1332,17 @@ tcSubType orig ctxt ty_actual ty_expected --------------- tcSubTypeDS :: HsExpr GhcRn - -> TcRhoType -- Actual -- a rho-type not a sigma-type - -> ExpRhoType -- Expected + -> TcRhoType -- Actual type -- a rho-type not a sigma-type + -> ExpRhoType -- Expected type + -- DeepSubsumption <=> when checking, this type + -- is deeply skolemised -> TcM HsWrapper -- Similar signature to unifyExpectedType; does deep subsumption -- Only one call site, in GHC.Tc.Gen.App.tcApp tcSubTypeDS rn_expr act_rho res_ty = case res_ty of - Check exp_rho -> tc_sub_type_ds Deep (unifyType m_thing) orig - GenSigCtxt act_rho exp_rho + Check exp_rho -> tc_sub_type_deep (unifyType m_thing) orig + GenSigCtxt act_rho exp_rho Infer inf_res -> do { co <- fillInferResult act_rho inf_res ; return (mkWpCastN co) } @@ -1472,7 +1474,7 @@ tc_sub_type_ds :: DeepSubsumptionFlag -- It takes an explicit DeepSubsumptionFlag tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected | definitely_poly ty_expected -- See Note [Don't skolemise unnecessarily] - , definitely_mono ds_flag ty_actual + , isRhoTyDS ds_flag ty_actual = do { traceTc "tc_sub_type (drop to equality)" $ vcat [ text "ty_actual =" <+> ppr ty_actual , text "ty_expected =" <+> ppr ty_expected ] @@ -1485,25 +1487,25 @@ tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected , text "ty_expected =" <+> ppr ty_expected ] ; (sk_wrap, inner_wrap) - <- case ds_flag of - Shallow -> -- Shallow: skolemise, instantiate and unify - tcSkolemise Shallow ctxt ty_expected $ \sk_rho -> - do { (wrap, rho_a) <- topInstantiate inst_orig ty_actual - ; cow <- unify rho_a sk_rho - ; return (mkWpCastN cow <.> wrap) } - Deep -> -- Deep: we have co/contra work to do - tcSkolemise Deep ctxt ty_expected $ \sk_rho -> - tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho + <- tcSkolemise ds_flag ctxt ty_expected $ \sk_rho -> + case ds_flag of + Deep -> tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho + Shallow -> tc_sub_type_shallow unify inst_orig ty_actual sk_rho ; return (sk_wrap <.> inner_wrap) } ---------------------- -definitely_mono :: DeepSubsumptionFlag -> TcType -> Bool -definitely_mono ds_flag ty - = case ds_flag of - Shallow -> isRhoTy ty -- isRhoTy: no top level forall or (=>) - Deep -> isDeepRhoTy ty -- "deep" version: no nested forall or (=>) +tc_sub_type_shallow :: (TcType -> TcType -> TcM TcCoercionN) + -> CtOrigin + -> TcSigmaType + -> TcRhoType -- Skolemised (shallow-ly) + -> TcM HsWrapper +tc_sub_type_shallow unify inst_orig ty_actual sk_rho + = do { (wrap, rho_a) <- topInstantiate inst_orig ty_actual + ; cow <- unify rho_a sk_rho + ; return (mkWpCastN cow <.> wrap) } +---------------------- definitely_poly :: TcType -> Bool -- A very conservative test: -- see Note [Don't skolemise unnecessarily] @@ -1721,7 +1723,8 @@ getDeepSubsumptionFlag :: TcM DeepSubsumptionFlag getDeepSubsumptionFlag = do { ds <- xoptM LangExt.DeepSubsumption ; if ds then return Deep else return Shallow } -tc_sub_type_deep :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify +tc_sub_type_deep :: HasDebugCallStack + => (TcType -> TcType -> TcM TcCoercionN) -- How to unify -> CtOrigin -- Used when instantiating -> UserTypeCtxt -- Used when skolemising -> TcSigmaType -- Actual; a sigma-type @@ -1734,7 +1737,8 @@ tc_sub_type_deep :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify -- Precondition: ty_expected is deeply skolemised tc_sub_type_deep unify inst_orig ctxt ty_actual ty_expected - = do { traceTc "tc_sub_type_deep" $ + = assertPpr (isDeepRhoTy ty_expected) (ppr ty_expected) $ + do { traceTc "tc_sub_type_deep" $ vcat [ text "ty_actual =" <+> ppr ty_actual , text "ty_expected =" <+> ppr ty_expected ] ; go ty_actual ty_expected } @@ -1877,6 +1881,12 @@ isDeepRhoTy ty | Just (_, res) <- tcSplitFunTy_maybe ty = isDeepRhoTy res | otherwise = True -- No forall, (=>), or (->) at top +isRhoTyDS :: DeepSubsumptionFlag -> TcType -> Bool +isRhoTyDS ds_flag ty + = case ds_flag of + Shallow -> isRhoTy ty -- isRhoTy: no top level forall or (=>) + Deep -> isDeepRhoTy ty -- "deep" version: no nested forall or (=>) + {- ************************************************************************ * * ===================================== testsuite/tests/impredicative/T24676.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE ImpredicativeTypes #-} + +module T24676 where + +ids :: [forall a. a -> a] +ids = take 5 (repeat id) +-- take :: Int -> [a] -> [a] +-- repeat :: b -> [b] + +test :: [forall a. a->a] +test = ids ++ ids + +-- typechecks with signature, without signature, and inlining "test" +f1a = test + +f1b :: [forall a. a -> a] +f1b = test + +-- typechecks with or without signature +f2a = Just test + +f2b :: Maybe [forall a. a->a] +f2b = Just test + +-- only typechecks with a signature + +f3a = Just (ids ++ ids) + +f3b :: Maybe [forall a. a -> a] +f3b = Just (ids ++ ids) ===================================== testsuite/tests/impredicative/all.T ===================================== @@ -21,3 +21,4 @@ test('T8808', normal, compile, ['']) test('T17332', normal, compile_fail, ['']) test('expr-sig', normal, compile, ['']) test('Dict', normal, compile, ['']) +test('T24676', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/T2846b.stderr ===================================== @@ -1,5 +1,5 @@ -T2846b.hs:5:11: error: [GHC-91028] +T2846b.hs:5:10: error: [GHC-91028] • Couldn't match expected type ‘a1’ with actual type ‘[Num a0 => a0]’ Cannot instantiate unification variable ‘a1’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b28a6c93502a3c8bad8329791a494434bfe8604 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b28a6c93502a3c8bad8329791a494434bfe8604 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 08:19:23 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Fri, 26 Apr 2024 04:19:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sand-witch/mksolo-hash Message-ID: <662b638bddbb9_3801e224ca9085548f@gitlab.mail> Andrei Borzenkov pushed new branch wip/sand-witch/mksolo-hash at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sand-witch/mksolo-hash You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 08:49:49 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Fri, 26 Apr 2024 04:49:49 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/mksolo-hash] 37 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662b6aad2e8f8_3801e228d25f0571f9@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/mksolo-hash at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 97ecc965 by Andrei Borzenkov at 2024-04-26T12:49:32+04:00 Rename Solo# data constructor to MkSolo# (T24673) - data Solo# a = (# a #) + data Solo# a = MkSolo# a And `(# foo #)` syntax now becomes just a syntactic shugar for `MkSolo# a`. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/033f50059b914540cac91c844b8a470e0bdab65d...97ecc965cb9f4c4859404c669cdfc25a4fd50d39 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/033f50059b914540cac91c844b8a470e0bdab65d...97ecc965cb9f4c4859404c669cdfc25a4fd50d39 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 08:50:50 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Fri, 26 Apr 2024 04:50:50 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/mksolo-hash] Rename Solo# data constructor to MkSolo# (T24673) Message-ID: <662b6aea482f3_3801e2290a748573d3@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/mksolo-hash at Glasgow Haskell Compiler / GHC Commits: 01125364 by Andrei Borzenkov at 2024-04-26T12:50:27+04:00 Rename Solo# data constructor to MkSolo# (T24673) - data Solo# a = (# a #) + data Solo# a = MkSolo# a And `(# foo #)` syntax now becomes just a syntactic sugar for `MkSolo# a`. - - - - - 11 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/ghc-experimental/src/Data/Tuple/Experimental.hs - libraries/ghc-prim/GHC/Types.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - + testsuite/tests/rename/should_fail/T24673.hs - + testsuite/tests/rename/should_fail/T24673.stderr - testsuite/tests/rename/should_fail/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/th/TH_tuple1.stdout Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -1015,7 +1015,7 @@ mkUnboxedTupleStr ns 0 | isDataConNameSpace ns = "(##)" | otherwise = "Unit#" mkUnboxedTupleStr ns 1 - | isDataConNameSpace ns = "(# #)" -- See Note [One-tuples] + | isDataConNameSpace ns = "MkSolo#" -- See Note [One-tuples] | otherwise = "Solo#" mkUnboxedTupleStr ns ar | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)" ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -79,7 +79,7 @@ The basic encoding scheme is this. :+ ZCzp () Z0T 0-tuple (,,,,) Z5T 5-tuple - (# #) Z1H unboxed 1-tuple (note the space) + (##) Z0H unboxed 0-tuple (#,,,,#) Z5H unboxed 5-tuple -} @@ -212,7 +212,6 @@ decode_tuple d rest go n (c : rest) | isDigit c = go (10*n + digitToInt c) rest go 0 ('T':rest) = "()" ++ zDecodeString rest go n ('T':rest) = '(' : replicate (n-1) ',' ++ ")" ++ zDecodeString rest - go 1 ('H':rest) = "(# #)" ++ zDecodeString rest go n ('H':rest) = '(' : '#' : replicate (n-1) ',' ++ "#)" ++ zDecodeString rest go n other = error ("decode_tuple: " ++ show n ++ ' ':other) @@ -223,15 +222,13 @@ for 3-tuples or unboxed 3-tuples respectively. No other encoding starts Z * "(##)" is the tycon for an unboxed 0-tuple -* "(# #)" is the tycon for an unboxed 1-tuple -* "()" is the tycon for a boxed 0-tuple. +* "()" is the tycon for a boxed 0-tuple -} maybe_tuple :: UserString -> Maybe EncodedString maybe_tuple "(##)" = Just("Z0H") -maybe_tuple "(# #)" = Just("Z1H") maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing ===================================== libraries/ghc-experimental/src/Data/Tuple/Experimental.hs ===================================== @@ -21,7 +21,7 @@ module Data.Tuple.Experimental ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -65,7 +65,7 @@ module GHC.Types ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, @@ -889,7 +889,7 @@ type Unit# :: TYPE (TupleRep '[]) data Unit# = (# #) type Solo# :: TYPE rep -> TYPE (TupleRep '[rep]) -data Solo# a = (# a #) +data Solo# a = MkSolo# a type Tuple0# = Unit# type Tuple1# = Solo# ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1938,10 +1938,7 @@ mk_tup_name n space boxed solo | space == DataName = "MkSolo" | otherwise = "Solo" - - unboxed_solo - | space == DataName = "(# #)" - | otherwise = "Solo#" + unboxed_solo = solo ++ "#" -- Unboxed sum data and type constructors -- | Unboxed sum data constructor ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -2633,7 +2633,7 @@ module Data.Tuple.Experimental where type Solo :: * -> * data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) - data Solo# a = ... + data Solo# a = MkSolo# a type Tuple0 :: * type Tuple0 = () type Tuple0# :: GHC.Types.ZeroBitType ===================================== testsuite/tests/rename/should_fail/T24673.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE UnboxedTuples, MagicHash, NoListTuplePuns #-} + +module T24673 where + +import Data.Tuple.Experimental + + +f = (# 42 #) + MkSolo# 42 ===================================== testsuite/tests/rename/should_fail/T24673.stderr ===================================== @@ -0,0 +1,20 @@ + +T24673.hs:8:5: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a0 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the first argument of ‘(+)’, namely ‘(# 42 #)’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) + +T24673.hs:8:16: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a1 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the second argument of ‘(+)’, namely ‘MkSolo# 42’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -227,3 +227,4 @@ test('T23570b', [extra_files(['T23570_aux.hs'])], multimod_compile, ['T23570b', test('T17594b', req_th, compile_fail, ['']) test('T14032c', normal, compile_fail, ['']) test('T14032f', normal, compile_fail, ['']) +test('T24673', normal, compile_fail, ['']) ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -20,7 +20,7 @@ T15226b.bar1 sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = T15226b.Str! [sat]; - } in (# #) [sat]; + } in MkSolo# [sat]; }; T15226b.bar ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -6,5 +6,5 @@ GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.MkSolo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.MkSolo# 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01125364a631f5db613f1bfc5e2b23544c79b636 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01125364a631f5db613f1bfc5e2b23544c79b636 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 09:15:58 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 05:15:58 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 3 commits: Add run-time configurability of .hi file compression Message-ID: <662b70ced75e_3801e22e7d130634a9@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: 58c19f2d by Matthew Pickering at 2024-04-26T11:15:09+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: MultiLayerModulesDefsGhciWithCore T21839c T24471 ------------------------- - - - - - ec52327c by Matthew Pickering at 2024-04-26T11:15:36+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 9227f1a8 by Fendor at 2024-04-26T11:15:36+02:00 Implement TrieMap for IfaceType - - - - - 21 changed files: - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs - + testsuite/tests/iface/if_ifacetype.hs - + testsuite/tests/iface/if_name.hs Changes: ===================================== compiler/GHC/Core/Map/Expr.hs ===================================== @@ -129,7 +129,7 @@ instance TrieMap CoreMap where -- inside another 'TrieMap', this is the type you want. type CoreMapG = GenMap CoreMapX -type LiteralMap a = Map.Map Literal a +type LiteralMap a = Map.Map Literal a -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without -- the 'GenMap' optimization. ===================================== compiler/GHC/Data/TrieMap.hs ===================================== @@ -36,6 +36,8 @@ import qualified Data.IntMap as IntMap import GHC.Utils.Outputable import Control.Monad( (>=>) ) import Data.Kind( Type ) +import Data.Functor.Compose +import Data.Functor.Product import qualified Data.Semigroup as S @@ -340,6 +342,95 @@ ftList :: TrieMap m => (a -> Bool) -> ListMap m a -> ListMap m a ftList f (LM { lm_nil = mnil, lm_cons = mcons }) = LM { lm_nil = filterMaybe f mnil, lm_cons = fmap (filterTM f) mcons } + +{- +************************************************************************ +* * + Composition +* * +************************************************************************ +-} + +instance (TrieMap m, TrieMap n) => TrieMap (Compose m n) where + type Key (Compose m n) = (Key m, Key n) + emptyTM = Compose emptyTM + lookupTM = lkCompose lookupTM lookupTM + {-# INLINE lookupTM #-} + alterTM = xtCompose alterTM alterTM + {-# INLINE alterTM #-} + foldTM = fdCompose + {-# INLINE foldTM #-} + filterTM = ftCompose + {-# INLINE filterTM #-} + +lkCompose :: Monad m => (t1 -> f (g a1) -> m a2) -> (t2 -> a2 -> m b) -> (t1, t2) -> Compose f g a1 -> m b +lkCompose f g (a, b) (Compose m) = f a m >>= g b +{-# INLINE lkCompose #-} + +xtCompose :: + (TrieMap m, TrieMap n) + => (forall a . Key m -> XT a -> m a -> m a) + -> (forall a . Key n -> XT a -> n a -> n a) + -> Key (Compose m n) + -> XT a + -> Compose m n a + -> Compose m n a + +xtCompose f g (a, b) xt (Compose m) = Compose ((f a |>> g b xt) m) + +{-# INLINE xtCompose #-} + +fdCompose :: (TrieMap m1, TrieMap m2) => (a -> b -> b) -> Compose m1 m2 a -> b -> b +fdCompose f (Compose m) = foldTM (foldTM f) m + +{-# INLINE fdCompose #-} + + +ftCompose :: (TrieMap n, Functor m) => (a -> Bool) -> Compose m n a -> Compose m n a +ftCompose f (Compose m) = Compose (fmap (filterTM f) m) + +{-# INLINE ftCompose #-} + +{- Product -} +instance (TrieMap m, TrieMap n) => TrieMap (Product m n) where + type Key (Product m n) = Either (Key m) (Key n) + emptyTM = Pair emptyTM emptyTM + lookupTM = lkProduct + {-# INLINE lookupTM #-} + alterTM = xtProduct + {-# INLINE alterTM #-} + foldTM = fdProduct + {-# INLINE foldTM #-} + filterTM = ftProduct + {-# INLINE filterTM #-} + +lkProduct :: (TrieMap m1, TrieMap m2) => Either (Key m1) (Key m2) -> Product m1 m2 b -> Maybe b +lkProduct k (Pair am bm) = + case k of + Left a -> lookupTM a am + Right b -> lookupTM b bm + +{-# INLINE lkProduct #-} + +xtProduct :: (TrieMap f, TrieMap g) => Either (Key f) (Key g) -> XT a -> Product f g a -> Product f g a +xtProduct k xt (Pair am bm) = + case k of + Left a -> Pair (alterTM a xt am) bm + Right b -> Pair am (alterTM b xt bm) + +{-# INLINE xtProduct #-} + +fdProduct :: (TrieMap f, TrieMap g) => (a -> c -> c) -> Product f g a -> c -> c +fdProduct f (Pair am bm) = foldTM f am . foldTM f bm + +{-# INLINE fdProduct #-} + +ftProduct :: (TrieMap f, TrieMap g) => (a -> Bool) -> Product f g a -> Product f g a +ftProduct f (Pair am bm) = Pair (filterTM f am) (filterTM f bm) + +{-# INLINE ftProduct #-} + + {- ************************************************************************ * * ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -207,6 +207,7 @@ data DynFlags = DynFlags { dmdUnboxWidth :: !Int, -- ^ Whether DmdAnal should optimistically put an -- Unboxed demand on returned products with at most -- this number of fields + ifCompression :: Int, specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types @@ -546,6 +547,7 @@ defaultDynFlags mySettings = maxPmCheckModels = 30, simplTickFactor = 100, dmdUnboxWidth = 3, -- Default: Assume an unboxed demand on function bodies returning a triple + ifCompression = 2, -- Default: Apply safe compressions specConstrThreshold = Just 2000, specConstrCount = Just 3, specConstrRecursive = 3, ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -163,7 +163,7 @@ import GHC.JS.Syntax import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings ) -import GHC.Iface.Load ( ifaceStats, writeIface ) +import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression ) import GHC.Iface.Make import GHC.Iface.Recomp import GHC.Iface.Tidy @@ -612,7 +612,7 @@ extract_renamed_stuff mod_summary tc_result = do -- enables the option which keeps the renamed source. hieFile <- mkHieFile mod_summary tc_result (fromJust rn_info) let out_file = ml_hie_file $ ms_location mod_summary - liftIO $ writeHieFile out_file hieFile + liftIO $ writeHieFile (flagsToIfCompression dflags) out_file hieFile liftIO $ putDumpFileMaybe logger Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files @@ -1207,7 +1207,7 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do withTiming logger (text "WriteIface"<+>brackets (text iface_name)) (const ()) - (writeIface logger profile iface_name iface) + (writeIface logger profile (flagsToIfCompression dflags) iface_name iface) if (write_interface || force_write_interface) then do ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1695,6 +1695,9 @@ dynamic_flags_deps = [ , make_ord_flag defFlag "fno-refinement-level-hole-fits" (noArg (\d -> d { refLevelHoleFits = Nothing })) + , make_ord_flag defFlag "fwrite-if-compression" + (intSuffix (\n d -> d { ifCompression = n })) + , make_dep_flag defGhcFlag "fllvm-pass-vectors-in-regs" (noArg id) "vectors registers are now passed in registers by default." ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -14,6 +14,7 @@ module GHC.Iface.Binary ( writeBinIface, readBinIface, readBinIfaceHeader, + CompressionIFace(..), getSymtabName, CheckHiWay(..), TraceBinIFace(..), @@ -48,7 +49,7 @@ import GHC.Types.SrcLoc import GHC.Platform import GHC.Settings.Constants import GHC.Utils.Fingerprint -import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import GHC.Iface.Type (IfaceType(..), getIfaceType, putIfaceType, ifaceTypeSharedByte) import Control.Monad import Data.Array @@ -73,6 +74,21 @@ data TraceBinIFace = TraceBinIFace (SDoc -> IO ()) | QuietBinIFace +data CompressionIFace + = NormalCompression + -- ^ Perform the normal compression operations, + -- such as deduplicating 'Name's and 'FastString's + | SafeExtraCompression + -- ^ Perform some extra compression steps that have minimal impact + -- on the run-time of 'ghc'. + -- + -- This reduces the size of '.hi' files significantly in some cases + -- and reduces overall memory usage in certain scenarios. + | MaximalCompression + -- ^ Try to compress as much as possible. + -- + -- Yields the smallest '.hi' files but at the cost of additional run-time. + -- | Read an interface file header, checking the magic number, version, and -- way. Returns the hash of the source file and a BinHandle which points at the -- start of the rest of the interface file data. @@ -199,8 +215,8 @@ getTables name_cache bh = do -- | Write an interface file. -- -- See Note [Deduplication during iface binary serialisation] for details. -writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () -writeBinIface profile traceBinIface hi_path mod_iface = do +writeBinIface :: Profile -> TraceBinIFace -> CompressionIFace -> FilePath -> ModIface -> IO () +writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do bh <- openBinMem initBinMemSize let platform = profilePlatform profile put_ bh (binaryInterfaceMagic platform) @@ -214,7 +230,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p - putWithUserData traceBinIface bh mod_iface + putWithUserData traceBinIface compressionLevel bh mod_iface extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p @@ -228,9 +244,9 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () -putWithUserData traceBinIface bh payload = do - (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) +putWithUserData :: Binary a => TraceBinIFace -> CompressionIFace -> WriteBinHandle -> a -> IO () +putWithUserData traceBinIface compressionLevel bh payload = do + (name_count, fs_count, _b) <- putWithTables compressionLevel bh (\bh' -> put bh' payload) case traceBinIface of QuietBinIFace -> return () @@ -253,12 +269,12 @@ putWithUserData traceBinIface bh payload = do -- It returns (number of names, number of FastStrings, payload write result) -- -- See Note [Order of deduplication tables during iface binary serialisation] -putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) -putWithTables bh' put_payload = do +putWithTables :: CompressionIFace -> WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables compressionLevel bh' put_payload = do -- Initialise deduplicating tables. (fast_wt, fsWriter) <- initFastStringWriterTable (name_wt, nameWriter) <- initNameWriterTable - (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType + (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel -- Initialise the 'WriterUserData'. let writerUserData = mkWriterUserData @@ -485,15 +501,33 @@ initReadIfaceTypeTable ud = do , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) } -initWriteIfaceType :: IO (WriterTable, BinaryWriter IfaceType) -initWriteIfaceType = do +initWriteIfaceType :: CompressionIFace -> IO (WriterTable, BinaryWriter IfaceType) +initWriteIfaceType compressionLevel = do sym_tab <- initGenericSymbolTable @(Map IfaceType) pure ( WriterTable { putTable = putGenericSymbolTable sym_tab (lazyPut' putIfaceType) } - , mkWriter $ putGenericSymTab sym_tab + , mkWriter $ ifaceWriter sym_tab ) + where + ifaceWriter sym_tab = case compressionLevel of + NormalCompression -> literalIfaceTypeSerialiser + SafeExtraCompression -> ifaceTyConAppSerialiser sym_tab + MaximalCompression -> fullIfaceTypeSerialiser sym_tab + + ifaceTyConAppSerialiser sym_tab bh ty = case ty of + IfaceTyConApp {} -> do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + _ -> putIfaceType bh ty + + + fullIfaceTypeSerialiser sym_tab bh ty = do + put_ bh ifaceTypeSharedByte + putGenericSymTab sym_tab bh ty + + literalIfaceTypeSerialiser = putIfaceType initNameReaderTable :: NameCache -> IO (ReaderTable Name) ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -43,7 +43,7 @@ import System.Directory ( createDirectoryIfMissing ) import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types -import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable) +import GHC.Iface.Binary (initWriteIfaceType, putAllTables, initReadIfaceTypeTable, CompressionIFace) import GHC.Iface.Type (IfaceType) import System.IO.Unsafe (unsafeInterleaveIO) import qualified GHC.Utils.Binary as Binary @@ -73,8 +73,8 @@ putBinLine bh xs = do -- | Write a `HieFile` to the given `FilePath`, with a proper header and -- symbol tables for `Name`s and `FastString`s -writeHieFile :: FilePath -> HieFile -> IO () -writeHieFile hie_file_path hiefile = do +writeHieFile :: CompressionIFace -> FilePath -> HieFile -> IO () +writeHieFile compression hie_file_path hiefile = do bh0 <- openBinMem initBinMemSize -- Write the header: hieHeader followed by the @@ -85,7 +85,7 @@ writeHieFile hie_file_path hiefile = do (fs_tbl, fs_w) <- initFastStringWriterTable (name_tbl, name_w) <- initWriteNameTable - (iface_tbl, iface_w) <- initWriteIfaceType + (iface_tbl, iface_w) <- initWriteIfaceType compression let bh = setWriterUserData bh0 $ mkWriterUserData [ mkSomeBinaryWriter @IfaceType iface_w ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Iface.Load ( loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, findAndReadIface, readIface, writeIface, + flagsToIfCompression, moduleFreeHolesPrecise, needWiredInHomeIface, loadWiredInHomeIface, @@ -965,11 +966,18 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do -- | Write interface file -writeIface :: Logger -> Profile -> FilePath -> ModIface -> IO () -writeIface logger profile hi_file_path new_iface +writeIface :: Logger -> Profile -> CompressionIFace -> FilePath -> ModIface -> IO () +writeIface logger profile compression_level hi_file_path new_iface = do createDirectoryIfMissing True (takeDirectory hi_file_path) let printer = TraceBinIFace (debugTraceMsg logger 3) - writeBinIface profile printer hi_file_path new_iface + writeBinIface profile printer compression_level hi_file_path new_iface + +flagsToIfCompression :: DynFlags -> CompressionIFace +flagsToIfCompression dflags = case ifCompression dflags of + 0 -> NormalCompression + 1 -> NormalCompression + 2 -> SafeExtraCompression + _ -> MaximalCompression -- | @readIface@ tries just the one file. -- ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Iface.Type ( ifTyConBinderVar, ifTyConBinderName, -- Binary utilities - putIfaceType, getIfaceType, + putIfaceType, getIfaceType, ifaceTypeSharedByte, -- Equality testing isIfaceLiftedTypeKind, @@ -92,12 +92,13 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Control.DeepSeq +import Data.Maybe (isJust) import Data.Proxy -import Control.Monad ((<$!>)) -import Control.Arrow (first) import qualified Data.Semigroup as Semi -import Data.Maybe (isJust) +import Data.Word (Word8) +import Control.Arrow (first) +import Control.DeepSeq +import Control.Monad ((<$!>)) {- ************************************************************************ @@ -112,6 +113,10 @@ newtype IfLclName = IfLclName { getIfLclName :: LexicalFastString } deriving (Eq, Ord, Show) +instance Uniquable IfLclName where + getUnique = getUnique . ifLclNameFS + + ifLclNameFS :: IfLclName -> FastString ifLclNameFS = getLexicalFastString . getIfLclName @@ -2194,12 +2199,35 @@ ppr_parend_preds :: [IfacePredType] -> SDoc ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds))) instance Binary IfaceType where - put_ bh tyCon = case findUserDataWriter Proxy bh of - tbl -> putEntry tbl bh tyCon + put_ bh ty = + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh ty - get bh = case findUserDataReader Proxy bh of - tbl -> getEntry tbl bh + get bh = getIfaceTypeShared bh +-- | This is the byte tag we expect to read when the next +-- value is not an 'IfaceType' value, but an offset into a +-- lookup value. +-- +-- Must not overlap with any byte tag in 'getIfaceType'. +ifaceTypeSharedByte :: Word8 +ifaceTypeSharedByte = 99 + +-- | Like 'getIfaceType' but checks for a specific byte tag +-- that indicates that we won't be able to read a 'IfaceType' value +-- but rather an offset into a lookup table. Consequentially, +-- we look up the value for the 'IfaceType' in the look up table. +-- +-- See Note [Deduplication during iface binary serialisation] +-- for details. +getIfaceTypeShared :: ReadBinHandle -> IO IfaceType +getIfaceTypeShared bh = do + start <- tellBinReader bh + tag <- getByte bh + if ifaceTypeSharedByte == tag + then case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh + else seekBinReader bh start >> getIfaceType bh putIfaceType :: WriteBinHandle -> IfaceType -> IO () putIfaceType _ (IfaceFreeTyVar tv) ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -0,0 +1,180 @@ +{-# LANGUAGE TypeFamilies #-} +module GHC.Iface.Type.Map where + +import GHC.Prelude +import GHC.Data.TrieMap +import GHC.Iface.Type +import qualified Data.Map as Map +import Data.Functor.Compose +import GHC.Types.Basic +import Control.Monad ((>=>)) +import GHC.Types.Unique.DFM +import Data.Functor.Product +import GHC.Types.Var (VarBndr(..)) + + +newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) + +instance Functor IfaceTypeMap where + fmap f (IfaceTypeMap m) = IfaceTypeMap (fmap f m) + +instance TrieMap IfaceTypeMap where + type Key IfaceTypeMap = IfaceType + + emptyTM = IfaceTypeMap emptyTM + + lookupTM k (IfaceTypeMap m) = lookupTM k m + + alterTM k f (IfaceTypeMap m) = IfaceTypeMap (alterTM k f m) + + filterTM f (IfaceTypeMap m) = IfaceTypeMap (filterTM f m) + + foldTM f (IfaceTypeMap m) = foldTM f m + +type IfaceTypeMapG = GenMap IfaceTypeMapX + +data IfaceTypeMapX a + = IFM { ifm_lit :: IfaceLiteralMap a + , ifm_var :: UniqDFM IfLclName a + , ifm_app :: IfaceTypeMapG (IfaceAppArgsMap a) + , ifm_fun_ty :: FunTyFlagMap (IfaceTypeMapG (IfaceTypeMapG (IfaceTypeMapG a))) + , ifm_ty_con_app :: IfaceTyConMap (IfaceAppArgsMap a) + , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) + , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) + , ifm_coercion_ty :: IfaceCoercionMap a + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + +type IfaceLiteralMap = Map.Map IfaceTyLit +type FunTyFlagMap = Map.Map FunTyFlag +type IfaceTyConMap = Map.Map IfaceTyCon +type ForAllTyFlagMap = Map.Map ForAllTyFlag +type IfaceCoercionMap = Map.Map IfaceCoercion +type TupleSortMap = Map.Map TupleSort +type PromotionFlagMap = Map.Map PromotionFlag +type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap + +type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) +type IfaceTvBndrMap = Compose (UniqDFM IfLclName) IfaceTypeMapG + +type IfaceBndrMap = Product IfaceIdBndrMap IfaceTvBndrMap + + + + +type IfaceAppArgsMap a = ListMap (Compose IfaceTypeMapG ForAllTyFlagMap) a + +emptyE :: IfaceTypeMapX a +emptyE = IFM { ifm_lit = emptyTM + , ifm_var = emptyTM + , ifm_app = emptyTM + , ifm_fun_ty = emptyTM + , ifm_ty_con_app = emptyTM + , ifm_forall_ty = emptyTM + , ifm_cast_ty = emptyTM + , ifm_coercion_ty = emptyTM + , ifm_tuple_ty = emptyTM } + +instance Functor IfaceTypeMapX where + fmap f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = fmap f ilit + , ifm_var = fmap f ivar + , ifm_app = fmap (fmap f) iapp + , ifm_fun_ty = fmap (fmap (fmap (fmap f))) ift + , ifm_ty_con_app = fmap (fmap f) itc + , ifm_forall_ty = fmap (fmap f) ifal + , ifm_cast_ty = fmap (fmap f) icast + , ifm_coercion_ty = fmap f ico + , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + +instance TrieMap IfaceTypeMapX where + type Key IfaceTypeMapX = IfaceType + + emptyTM = emptyE + lookupTM = lkE + alterTM = xtE + foldTM = fdE + filterTM = ftE + {-# INLINE lookupTM #-} + {-# INLINE alterTM #-} + +{-# INLINE ftE #-} +ftE :: (a -> Bool) -> IfaceTypeMapX a -> IfaceTypeMapX a +ftE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + + = IFM { ifm_lit = filterTM f ilit + , ifm_var = filterTM f ivar + , ifm_app = fmap (filterTM f) iapp + , ifm_fun_ty = fmap (fmap (fmap (filterTM f))) ift + , ifm_ty_con_app = fmap (filterTM f) itc + , ifm_forall_ty = fmap (filterTM f) ifal + , ifm_cast_ty = fmap (filterTM f) icast + , ifm_coercion_ty = filterTM f ico + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + +{-# INLINE fdE #-} +fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b +fdE f IFM { ifm_lit = ilit + , ifm_var = ivar + , ifm_app = iapp + , ifm_fun_ty = ift + , ifm_ty_con_app = itc + , ifm_forall_ty = ifal + , ifm_cast_ty = icast + , ifm_coercion_ty = ico + , ifm_tuple_ty = itup } + = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp + . foldTM (foldTM (foldTM (foldTM f))) ift + . foldTM (foldTM f) itc + . foldTM (foldTM f) ifal + . foldTM (foldTM f) icast + . foldTM f ico + . foldTM (foldTM (foldTM f)) itup + +bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr +bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) +bndrToKey (IfaceTvBndr k) = Right k + +{-# INLINE lkE #-} +lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a +lkE it ifm = go it ifm + where + go (IfaceFreeTyVar {}) = error "ftv" + go (IfaceTyVar var) = ifm_var >.> lookupTM var + go (IfaceLitTy l) = ifm_lit >.> lookupTM l + go (IfaceAppTy ift args) = ifm_app >.> lkG ift >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceFunTy ft t1 t2 t3) = ifm_fun_ty >.> lookupTM ft >=> lkG t1 >=> lkG t2 >=> lkG t3 + go (IfaceForAllTy (Bndr a b) t) = ifm_forall_ty >.> lookupTM (bndrToKey a,b) >=> lkG t + go (IfaceTyConApp tc args) = ifm_ty_con_app >.> lookupTM tc >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + go (IfaceCastTy ty co) = ifm_cast_ty >.> lkG ty >=> lookupTM co + go (IfaceCoercionTy co) = ifm_coercion_ty >.> lookupTM co + go (IfaceTupleTy sort prom args) = ifm_tuple_ty >.> lookupTM sort >=> lookupTM prom >=> lookupTM (appArgsIfaceTypesForAllTyFlags args) + +{-# INLINE xtE #-} +xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceFreeTyVar {}) _ _ = error "ftv" +xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } +xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } +xtE (IfaceAppTy ift args) f m = m { ifm_app = ifm_app m |> xtG ift |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceFunTy ft t1 t2 t3) f m = m { ifm_fun_ty = ifm_fun_ty m |> alterTM ft |>> xtG t1 |>> xtG t2 |>> xtG t3 f } +xtE (IfaceForAllTy (Bndr a b) t) f m = m { ifm_forall_ty = ifm_forall_ty m |> alterTM (bndrToKey a,b) |>> xtG t f } +xtE (IfaceTyConApp tc args) f m = m { ifm_ty_con_app = ifm_ty_con_app m |> alterTM tc |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } +xtE (IfaceCastTy ty co) f m = m { ifm_cast_ty = ifm_cast_ty m |> xtG ty |>> alterTM co f } +xtE (IfaceCoercionTy co) f m = m { ifm_coercion_ty = ifm_coercion_ty m |> alterTM co f } +xtE (IfaceTupleTy sort prom args) f m = m { ifm_tuple_ty = ifm_tuple_ty m |> alterTM sort |>> alterTM prom |>> alterTM (appArgsIfaceTypesForAllTyFlags args) f } ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -124,7 +124,7 @@ data StgArgMap a = SAM , sam_lit :: LiteralMap a } -type LiteralMap a = Map.Map Literal a +type LiteralMap = Map.Map Literal -- TODO(22292): derive instance Functor StgArgMap where ===================================== compiler/ghc.cabal.in ===================================== @@ -594,6 +594,7 @@ Library GHC.Iface.Tidy.StaticPtrTable GHC.IfaceToCore GHC.Iface.Type + GHC.Iface.Type.Map GHC.JS.Ident GHC.JS.Make GHC.JS.Optimizer ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1777,3 +1777,12 @@ as such you shouldn't need to set any of them explicitly. A flag This flag sets the size (in bytes) threshold above which the second approach is used. You can disable the second approach entirely by setting the threshold to 0. + +.. ghc-flag:: -fwrite-if-compression=⟨n⟩ + :shortdesc: *default: 2.* Tweak the level of interface file compression. + :type: dynamic + :category: optimization + + :default: 2 + + TODO ===================================== testsuite/tests/iface/IfaceSharingIfaceType.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingIfaceType (types) where + +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Builtin.Types +import GHC.Types.Name +import GHC.Types.SrcLoc +import GHC.Iface.Type +import GHC.CoreToIface +import GHC.Core.TyCo.Rep +import GHC + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] + +-- Int +intIfaceTy = toIfaceType intTy + +wordIfaceTy = toIfaceType wordTy + +listIntTy = toIfaceType (mkListTy intTy) + +funTy = (intTy `mkVisFunTyMany` wordTy `mkVisFunTyMany` mkListTy intTy) + +funIfaceTy = toIfaceType funTy + +reallyBigFunTy = toIfaceType (funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy `mkVisFunTyMany` funTy) + +forallIfaceTy = toIfaceType (dataConType justDataCon) + + +types = [intIfaceTy, wordIfaceTy, listIntTy, funIfaceTy, reallyBigFunTy, forallIfaceTy] + ===================================== testsuite/tests/iface/IfaceSharingName.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +module IfaceSharingName where + +import Lib +import GHC.Data.FastString +import GHC.Builtin.Uniques +import GHC.Builtin.Names +import GHC.Types.Name +import GHC.Types.SrcLoc + +[f1,f2,f3,f4,f5] = map mkVarOcc ["a", "b","c","d","e"] + +[u1,u2,u3,u4,u5] = map mkPreludeMiscIdUnique [10000..10004] + +names = [ mkExternalName u1 pRELUDE f1 noSrcSpan + , mkExternalName u2 pRELUDE f2 noSrcSpan + , mkExternalName u3 pRELUDE f3 noSrcSpan + , mkExternalName u4 pRELUDE f4 noSrcSpan + , mkExternalName u5 pRELUDE f5 noSrcSpan ] ===================================== testsuite/tests/iface/Lib.hs ===================================== @@ -0,0 +1,15 @@ +module Lib where + +import GHC.Utils.Binary +import GHC.Iface.Binary +import qualified Data.ByteString as B +import System.Environment +import Data.Maybe + +testSize :: Binary a => CompressionIFace -> a -> IO Int +testSize compLvl payload = do + args <- getArgs + bh <- openBinMem 1024 + putWithUserData QuietBinIFace compLvl bh payload + withBinBuffer bh (\b -> return (B.length b)) + ===================================== testsuite/tests/iface/Makefile ===================================== @@ -0,0 +1,4 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + ===================================== testsuite/tests/iface/all.T ===================================== @@ -0,0 +1,24 @@ +test( 'if_faststring' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_name' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingName.hs"])] + , compile_and_run + , ['-package ghc']) + +test( 'if_ifacetype' + , [ stat_from_file('normal', 5, 'NORMALSIZE') + , stat_from_file('medium', 5, 'MEDIUMSIZE') + , stat_from_file('full', 5, 'FULLSIZE') + , extra_files(["Lib.hs", "IfaceSharingIfaceType.hs"])] + , compile_and_run + , ['-package ghc']) + ===================================== testsuite/tests/iface/if_faststring.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} + +import Lib +import GHC.Data.FastString +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 ["abc", "cde", "efg" :: FastString])) + writeFile "NORMALSIZE" (show sz) ===================================== testsuite/tests/iface/if_ifacetype.hs ===================================== @@ -0,0 +1,13 @@ +import Lib +import IfaceSharingIfaceType +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 500 types)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 500 types)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 500 types)) + writeFile "NORMALSIZE" (show sz) + ===================================== testsuite/tests/iface/if_name.hs ===================================== @@ -0,0 +1,12 @@ +import Lib +import IfaceSharingName +import GHC.Iface.Binary + +main :: IO () +main = do + sz <- testSize MaximalCompression (concat (replicate 1000 names)) + writeFile "FULLSIZE" (show sz) + sz <- testSize SafeExtraCompression (concat (replicate 1000 names)) + writeFile "MEDIUMSIZE" (show sz) + sz <- testSize NormalCompression (concat (replicate 1000 names)) + writeFile "NORMALSIZE" (show sz) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c18a8b8dbf12b57bee949fa69de4d8133ca12a2...9227f1a8826046876502fc3a0ea8d20c20cc47a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c18a8b8dbf12b57bee949fa69de4d8133ca12a2...9227f1a8826046876502fc3a0ea8d20c20cc47a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 09:56:47 2024 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Fri, 26 Apr 2024 05:56:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/b/no-signal-9 Message-ID: <662b7a5f43352_3801e235422f4708f@gitlab.mail> Bryan R pushed new branch wip/b/no-signal-9 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/b/no-signal-9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 10:32:24 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 06:32:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Fix missing escaping-kind check in tcPatSynSig Message-ID: <662b82b8679d9_14ae3e344a1878650@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e64e95b4 by Simon Peyton Jones at 2024-04-26T06:32:12-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 98ad7b99 by Alan Zimmerman at 2024-04-26T06:32:13-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 6c1aed88 by Andrew Lelechenko at 2024-04-26T06:32:13-04:00 Document that setEnv is not thread-safe - - - - - 12 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/PprExportWarn.hs - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ceb6077ff4f599a6ae2a757470db546caa7cb41...6c1aed888135517684d0eb07096ce99d5ac61413 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ceb6077ff4f599a6ae2a757470db546caa7cb41...6c1aed888135517684d0eb07096ce99d5ac61413 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 10:48:11 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 06:48:11 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 2 commits: Improve sharing of duplicated values in `ModIface` Message-ID: <662b866b1b9ff_14ae3e65a20c85348@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 5bdba6d5 by Fendor at 2024-04-26T11:30:54+02:00 Improve sharing of duplicated values in `ModIface` As a `ModIface` contains often duplicated values that are not necessarily shared, we improve sharing by serialising the `ModIface` to an in-memory byte array. Serialisation uses deduplication tables, and deserialisation implicitly shares duplicated values. This helps reducing the peak memory usage while compiling in `--make` mode. The peak memory usage is especially reduced when generating interface files with core expressions (`-fwrite-if-simplified-core`). On agda, this reduces the peak memory usage: * `2.2 GB` to `1.9 GB` for a ghci session. On `lib:Cabal`, we report: * `570 MB` to `500 MB` for a ghci session * `790 MB` to `667 MB` for compiling `lib:Cabal` with ghc The execution time is not affected. - - - - - 08c05e51 by Fendor at 2024-04-26T12:47:53+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - 10 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs - utils/haddock Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -966,10 +966,11 @@ loadByteCode iface mod_sum = do -------------------------------------------------------------- + -- Knot tying! See Note [Knot-tying typecheckIface] -- See Note [ModDetails and --make mode] initModDetails :: HscEnv -> ModIface -> IO ModDetails -initModDetails hsc_env iface = +initModDetails hsc_env iface = do fixIO $ \details' -> do let act hpt = addToHpt hpt (moduleName $ mi_module iface) (HomeModInfo iface details' emptyHomeModInfoLinkable) ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -18,6 +18,8 @@ module GHC.Iface.Binary ( getSymtabName, CheckHiWay(..), TraceBinIFace(..), + getIfaceWithExtFields, + putIfaceWithExtFields, getWithUserData, putWithUserData, @@ -61,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -156,18 +159,29 @@ readBinIface readBinIface profile name_cache checkHiWay traceBinIface hi_path = do (src_hash, bh) <- readBinIfaceHeader profile name_cache checkHiWay traceBinIface hi_path - extFields_p <- get bh - - mod_iface <- getWithUserData name_cache bh - - seekBinReader bh extFields_p - extFields <- get bh + mod_iface <- getIfaceWithExtFields name_cache bh return mod_iface - { mi_ext_fields = extFields - , mi_src_hash = src_hash + { mi_src_hash = src_hash } +getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface +getIfaceWithExtFields name_cache bh = do + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh + + mod_iface <- getWithUserData name_cache bh + + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel + extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start + pure mod_iface + { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData + } + + -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. @@ -195,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -227,19 +241,21 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBinWriter bh - put_ bh extFields_p_p - - putWithUserData traceBinIface compressionLevel bh mod_iface - - extFields_p <- tellBinWriter bh - putAt bh extFields_p_p extFields_p - seekBinWriter bh extFields_p - put_ bh (mi_ext_fields mod_iface) + putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface -- And send the result to the file writeBinMem bh hi_path +-- | Puts the 'ModIface' +putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () +putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData + -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. @@ -309,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -522,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -41,7 +41,7 @@ instance Binary ExtensibleFields where -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBinWriter bh - putAt bh field_p_p field_p + putAtRel bh field_p_p field_p seekBinWriter bh field_p put_ bh dat @@ -50,11 +50,11 @@ instance Binary ExtensibleFields where -- Get the names and field pointers: header_entries <- replicateM n $ - (,) <$> get bh <*> get bh + (,) <$> get bh <*> getRelBin bh -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBinReader bh field_p + seekBinReaderRel bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -69,10 +69,13 @@ import GHC.Types.HpcInfo import GHC.Types.CompleteMatch import GHC.Types.SourceText import GHC.Types.SrcLoc ( unLoc ) +import GHC.Types.Name.Cache import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Logger +import GHC.Utils.Binary +import GHC.Iface.Binary import GHC.Data.FastString import GHC.Data.Maybe @@ -147,8 +150,37 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do let unit_state = hsc_units hsc_env putDumpFileMaybe (hsc_logger hsc_env) Opt_D_dump_hi "FINAL INTERFACE" FormatText (pprModIface unit_state full_iface) + final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface + return final_iface + +-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. +-- +-- We compress the 'ModIface' by serialising the 'ModIface' to an in-memory byte array, and then deserialising it. +-- The deserialisation will deduplicate certain values depending on the 'CompressionIFace' level. +-- See Note [Deduplication during iface binary serialisation] for how we do that. +-- +-- Additionally, we cache the serialised byte array, so if the 'ModIface' is not modified +-- after calling 'shareIface', 'writeBinIface' will reuse that buffer without serialising the 'ModIface' again. +-- Modifying the 'ModIface' forces us to re-serialise it again. +shareIface :: NameCache -> CompressionIFace -> ModIface -> IO ModIface +shareIface _ NormalCompression mi = do + -- In 'NormalCompression', the sharing isn't reducing the memory usage, as 'Name's and 'FastString's are + -- already shared, and at this compression level, we don't compress/share anything else. + -- Thus, for a brief moment we simply double the memory residency for no reason. + -- Therefore, we only try to share expensive values if the compression mode is higher than + -- 'NormalCompression' + pure mi +shareIface nc compressionLevel mi = do + bh <- openBinMem (1024 * 1024) + start <- tellBinWriter bh + putIfaceWithExtFields QuietBinIFace compressionLevel bh mi + rbh <- shrinkBinBuffer bh + seekBinReader rbh start + res <- getIfaceWithExtFields nc rbh + let resiface = res { mi_src_hash = mi_src_hash mi } + forceModIface resiface + pure resiface - return full_iface updateDecl :: [IfaceDecl] -> Maybe StgCgInfos -> Maybe CmmCgInfos -> [IfaceDecl] updateDecl decls Nothing Nothing = decls @@ -302,40 +334,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -20,7 +20,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,10 +33,13 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, withBinBuffer, + freezeWriteHandle, + thawReadHandle, foldGet, foldGet', @@ -45,7 +48,9 @@ module GHC.Utils.Binary readBinMemN, putAt, getAt, + putAtRel, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -100,6 +105,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -124,7 +133,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -154,7 +163,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -194,6 +202,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -287,9 +352,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr a) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -310,6 +396,9 @@ class Binary a where putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () putAt bh p x = do seekBinWriter bh p; put_ bh x; return () +putAtRel :: WriteBinHandle -> Bin (RelBinPtr a) -> Bin a -> IO () +putAtRel bh from to = putAt bh from (makeRelativeBin $ toRelBin from to) + getAt :: Binary a => ReadBinHandle -> Bin a -> IO a getAt bh p = do seekBinReader bh p; get bh @@ -328,6 +417,33 @@ openBinMem size , wbm_arr_r = arr_r } +-- | Freeze the given 'WriteBinHandle' and turn it into an equivalent 'ReadBinHandle'. +-- +-- The current offset of the 'WriteBinHandle' is maintained in the new 'ReadBinHandle'. +freezeWriteHandle :: WriteBinHandle -> IO ReadBinHandle +freezeWriteHandle wbm = do + rbm_off_r <- newFastMutInt =<< readFastMutInt (wbm_off_r wbm) + rbm_sz_r <- readFastMutInt (wbm_sz_r wbm) + rbm_arr_r <- readIORef (wbm_arr_r wbm) + pure $ ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = rbm_off_r + , rbm_sz_r = rbm_sz_r + , rbm_arr_r = rbm_arr_r + } + +thawReadHandle :: ReadBinHandle -> IO WriteBinHandle +thawReadHandle rbm = do + wbm_off_r <- newFastMutInt =<< readFastMutInt (rbm_off_r rbm) + wbm_sz_r <- newFastMutInt (rbm_sz_r rbm) + wbm_arr_r <- newIORef (rbm_arr_r rbm) + pure $ WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = wbm_off_r + , wbm_sz_r = wbm_sz_r + , wbm_arr_r = wbm_arr_r + } + tellBinWriter :: WriteBinHandle -> IO (Bin a) tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) @@ -353,12 +469,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1079,6 +1201,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1107,7 +1234,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1119,6 +1246,45 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + let relBin = toRelBin pre_a a + putAt bh pre_a (makeRelativeBin relBin) + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1128,19 +1294,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAt bh pre_a (makeRelativeBin $ toRelBin pre_a q) -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1149,7 +1315,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1443,13 +1609,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit fa76e1ee98906f5bc8fc4598524610020b653412 +Subproject commit 7dc9e5b68793bbb16462001f47b564763ffa3713 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e534e60d2574d7d6603b62b0aa7c58778535effd...08c05e513516d7ffae3a9e0f7c22861c2f5e6f23 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e534e60d2574d7d6603b62b0aa7c58778535effd...08c05e513516d7ffae3a9e0f7c22861c2f5e6f23 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 11:02:09 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 26 Apr 2024 07:02:09 -0400 Subject: [Git][ghc/ghc][wip/T20749] 63 commits: users-guide: Clarify language extension documentation Message-ID: <662b89b11cbc9_14ae3e8b78ec861e3@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - 0bbd0d47 by Sebastian Graf at 2024-04-26T13:01:44+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 2a3cc62d by Sebastian Graf at 2024-04-26T13:01:54+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87b509f2cd35fac07e9013a43747d9b897260e22...2a3cc62dda8025ac99284a6dfbe4446d7a05c193 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87b509f2cd35fac07e9013a43747d9b897260e22...2a3cc62dda8025ac99284a6dfbe4446d7a05c193 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 11:24:46 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 07:24:46 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] Avoid unneccessarily re-serialising the `ModIface` Message-ID: <662b8efdef50b_14ae3eb8e9e4891fe@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 0a121917 by Fendor at 2024-04-26T13:04:19+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - 9 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -166,14 +167,18 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start pure mod_iface { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData } @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -41,7 +41,7 @@ instance Binary ExtensibleFields where -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBinWriter bh - putAt bh field_p_p field_p + putAtRel bh field_p_p field_p seekBinWriter bh field_p put_ bh dat @@ -50,11 +50,11 @@ instance Binary ExtensibleFields where -- Get the names and field pointers: header_entries <- replicateM n $ - (,) <$> get bh <*> get bh + (,) <$> get bh <*> getRelBin bh -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBinReader bh field_p + seekBinReaderRel bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -153,17 +153,33 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface return final_iface +-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. +-- +-- We compress the 'ModIface' by serialising the 'ModIface' to an in-memory byte array, and then deserialising it. +-- The deserialisation will deduplicate certain values depending on the 'CompressionIFace' level. +-- See Note [Deduplication during iface binary serialisation] for how we do that. +-- +-- Additionally, we cache the serialised byte array, so if the 'ModIface' is not modified +-- after calling 'shareIface', 'writeBinIface' will reuse that buffer without serialising the 'ModIface' again. +-- Modifying the 'ModIface' forces us to re-serialise it again. shareIface :: NameCache -> CompressionIFace -> ModIface -> IO ModIface +shareIface _ NormalCompression mi = do + -- In 'NormalCompression', the sharing isn't reducing the memory usage, as 'Name's and 'FastString's are + -- already shared, and at this compression level, we don't compress/share anything else. + -- Thus, for a brief moment we simply double the memory residency for no reason. + -- Therefore, we only try to share expensive values if the compression mode is higher than + -- 'NormalCompression' + pure mi shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } forceModIface resiface - return resiface + pure resiface updateDecl :: [IfaceDecl] -> Maybe StgCgInfos -> Maybe CmmCgInfos -> [IfaceDecl] @@ -318,40 +334,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -20,7 +20,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,6 +33,7 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, @@ -47,7 +48,9 @@ module GHC.Utils.Binary readBinMemN, putAt, getAt, + putAtRel, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -102,6 +105,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -126,7 +133,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -156,7 +163,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -196,6 +202,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -289,9 +352,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr a) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -312,6 +396,9 @@ class Binary a where putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () putAt bh p x = do seekBinWriter bh p; put_ bh x; return () +putAtRel :: WriteBinHandle -> Bin (RelBinPtr a) -> Bin a -> IO () +putAtRel bh from to = putAt bh from (makeRelativeBin $ toRelBin from to) + getAt :: Binary a => ReadBinHandle -> Bin a -> IO a getAt bh p = do seekBinReader bh p; get bh @@ -382,12 +469,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1108,6 +1201,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1136,7 +1234,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1148,6 +1246,45 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + let relBin = toRelBin pre_a a + putAt bh pre_a (makeRelativeBin relBin) + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1157,19 +1294,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAt bh pre_a (makeRelativeBin $ toRelBin pre_a q) -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1178,7 +1315,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1472,13 +1609,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit fa76e1ee98906f5bc8fc4598524610020b653412 +Subproject commit e9eee9ea56dd21f22fff70106a1289d7f35440a3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a121917ac0052300075d3c81d1df806fd523aa7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a121917ac0052300075d3c81d1df806fd523aa7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 11:57:19 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Fri, 26 Apr 2024 07:57:19 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/mksolo-hash] Rename Solo# data constructor to MkSolo# (T24673) Message-ID: <662b969f34a8e_14ae3e1037cac93338@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/mksolo-hash at Glasgow Haskell Compiler / GHC Commits: fdf7ba05 by Andrei Borzenkov at 2024-04-26T15:57:03+04:00 Rename Solo# data constructor to MkSolo# (T24673) - data Solo# a = (# a #) + data Solo# a = MkSolo# a And `(# foo #)` syntax now becomes just a syntactic sugar for `MkSolo# a`. - - - - - 12 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/ghc-experimental/src/Data/Tuple/Experimental.hs - libraries/ghc-prim/GHC/Types.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - + testsuite/tests/rename/should_fail/T24673.hs - + testsuite/tests/rename/should_fail/T24673.stderr - testsuite/tests/rename/should_fail/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/th/TH_tuple1.stdout Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -1015,7 +1015,7 @@ mkUnboxedTupleStr ns 0 | isDataConNameSpace ns = "(##)" | otherwise = "Unit#" mkUnboxedTupleStr ns 1 - | isDataConNameSpace ns = "(# #)" -- See Note [One-tuples] + | isDataConNameSpace ns = "MkSolo#" -- See Note [One-tuples] | otherwise = "Solo#" mkUnboxedTupleStr ns ar | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)" ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -79,7 +79,7 @@ The basic encoding scheme is this. :+ ZCzp () Z0T 0-tuple (,,,,) Z5T 5-tuple - (# #) Z1H unboxed 1-tuple (note the space) + (##) Z0H unboxed 0-tuple (#,,,,#) Z5H unboxed 5-tuple -} @@ -212,7 +212,6 @@ decode_tuple d rest go n (c : rest) | isDigit c = go (10*n + digitToInt c) rest go 0 ('T':rest) = "()" ++ zDecodeString rest go n ('T':rest) = '(' : replicate (n-1) ',' ++ ")" ++ zDecodeString rest - go 1 ('H':rest) = "(# #)" ++ zDecodeString rest go n ('H':rest) = '(' : '#' : replicate (n-1) ',' ++ "#)" ++ zDecodeString rest go n other = error ("decode_tuple: " ++ show n ++ ' ':other) @@ -223,15 +222,13 @@ for 3-tuples or unboxed 3-tuples respectively. No other encoding starts Z * "(##)" is the tycon for an unboxed 0-tuple -* "(# #)" is the tycon for an unboxed 1-tuple -* "()" is the tycon for a boxed 0-tuple. +* "()" is the tycon for a boxed 0-tuple -} maybe_tuple :: UserString -> Maybe EncodedString maybe_tuple "(##)" = Just("Z0H") -maybe_tuple "(# #)" = Just("Z1H") maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing ===================================== libraries/ghc-experimental/src/Data/Tuple/Experimental.hs ===================================== @@ -21,7 +21,7 @@ module Data.Tuple.Experimental ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -65,7 +65,7 @@ module GHC.Types ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, @@ -889,7 +889,7 @@ type Unit# :: TYPE (TupleRep '[]) data Unit# = (# #) type Solo# :: TYPE rep -> TYPE (TupleRep '[rep]) -data Solo# a = (# a #) +data Solo# a = MkSolo# a type Tuple0# = Unit# type Tuple1# = Solo# ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1938,10 +1938,7 @@ mk_tup_name n space boxed solo | space == DataName = "MkSolo" | otherwise = "Solo" - - unboxed_solo - | space == DataName = "(# #)" - | otherwise = "Solo#" + unboxed_solo = solo ++ "#" -- Unboxed sum data and type constructors -- | Unboxed sum data constructor ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -24,7 +24,7 @@ T15226b.testFun1 case y of conrep { __DEFAULT -> case T15226b.MkStrictPair [sat conrep] of sat { - __DEFAULT -> (# #) [sat]; + __DEFAULT -> MkSolo# [sat]; }; }; }; ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -2633,7 +2633,7 @@ module Data.Tuple.Experimental where type Solo :: * -> * data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) - data Solo# a = ... + data Solo# a = MkSolo# a type Tuple0 :: * type Tuple0 = () type Tuple0# :: GHC.Types.ZeroBitType ===================================== testsuite/tests/rename/should_fail/T24673.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE UnboxedTuples, MagicHash, NoListTuplePuns #-} + +module T24673 where + +import Data.Tuple.Experimental + + +f = (# 42 #) + MkSolo# 42 ===================================== testsuite/tests/rename/should_fail/T24673.stderr ===================================== @@ -0,0 +1,20 @@ + +T24673.hs:8:5: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a0 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the first argument of ‘(+)’, namely ‘(# 42 #)’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) + +T24673.hs:8:16: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a1 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the second argument of ‘(+)’, namely ‘MkSolo# 42’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -227,3 +227,4 @@ test('T23570b', [extra_files(['T23570_aux.hs'])], multimod_compile, ['T23570b', test('T17594b', req_th, compile_fail, ['']) test('T14032c', normal, compile_fail, ['']) test('T14032f', normal, compile_fail, ['']) +test('T24673', normal, compile_fail, ['']) ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -20,7 +20,7 @@ T15226b.bar1 sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = T15226b.Str! [sat]; - } in (# #) [sat]; + } in MkSolo# [sat]; }; T15226b.bar ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -6,5 +6,5 @@ GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.MkSolo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.MkSolo# 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdf7ba05000c68bc74e93218fb32abe3f0f70235 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdf7ba05000c68bc74e93218fb32abe3f0f70235 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 12:02:21 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 08:02:21 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/perf-regression-if-simplified-core Message-ID: <662b97cd538ab_14ae3e11900e0943b3@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/perf-regression-if-simplified-core at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/perf-regression-if-simplified-core You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 12:09:10 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 08:09:10 -0400 Subject: [Git][ghc/ghc][wip/fendor/perf-regression-if-simplified-core] Add perf regression test for `-fwrite-if-simplified-core` Message-ID: <662b996649014_14ae3e12fa23c9736b@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/perf-regression-if-simplified-core at Glasgow Haskell Compiler / GHC Commits: 11352d74 by Fendor at 2024-04-26T14:08:56+02:00 Add perf regression test for `-fwrite-if-simplified-core` - - - - - 2 changed files: - testsuite/tests/perf/compiler/Makefile - testsuite/tests/perf/compiler/all.T Changes: ===================================== testsuite/tests/perf/compiler/Makefile ===================================== @@ -23,6 +23,9 @@ MultiModulesRecompDefsWithCore: ./genMultiLayerModulesCore '$(TEST_HC)' --interactive $(TEST_HC_OPTS) -e "" -fwrite-if-simplified-core MultiLayerModules +MultiModulesDefsWithCore: + ./genMultiLayerModulesCore + MultiComponentModulesRecomp: '$(PYTHON)' genMultiComp.py TEST_HC='$(TEST_HC)' TEST_HC_OPTS='$(TEST_HC_OPTS)' ./run ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -419,6 +419,19 @@ test('MultiLayerModulesDefsGhciWithCore', ghci_script, ['MultiLayerModulesDefsGhciWithCore.script']) +test('MultiLayerModulesDefsGhcWithCore', + [ collect_compiler_residency(15), + pre_cmd('$MAKE -s --no-print-directory MultiModulesDefsWithCore'), + extra_files(['genMultiLayerModulesCore']), + compile_timeout_multiplier(5) + # this is _a lot_ + # but this test has been failing every now and then, + # especially on i386. Let's just give it some room + # to complete successfully reliably everywhere. + ], + multimod_compile, + ['MultiLayerModules', '-v0 -fwrite-if-simplified-core']) + test('MultiLayerModulesDefsGhciReload', [ collect_compiler_residency(15), pre_cmd('./genMultiLayerModulesDefs'), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11352d7412b1bab672739a6cb1f1707200aca0e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11352d7412b1bab672739a6cb1f1707200aca0e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 12:20:55 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 08:20:55 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-refact] 2 commits: Refactor the Binary serialisation interface Message-ID: <662b9c27d2355_14ae3e152dc4897662@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-refact at Glasgow Haskell Compiler / GHC Commits: 4f158608 by Fendor at 2024-04-26T14:20:18+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - b8d00133 by Fendor at 2024-04-26T14:20:21+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +30,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +68,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +102,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +140,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1399,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1433,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1480,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be6836a22245743b736ae1fc88b4c0ba3e2cce6e...b8d0013336d92675e46777742e195aafe4805b6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be6836a22245743b736ae1fc88b4c0ba3e2cce6e...b8d0013336d92675e46777742e195aafe4805b6c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 12:48:29 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 26 Apr 2024 08:48:29 -0400 Subject: [Git][ghc/ghc][wip/T20749] 2 commits: CorePrep: Attach evaldUnfolding to floats to detect more values Message-ID: <662ba29dd87cd_14ae3e1934af8111730@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: 386233b0 by Sebastian Graf at 2024-04-26T14:47:58+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - d2eee16b by Sebastian Graf at 2024-04-26T14:47:58+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 29 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Misc.hs - testsuite/tests/dmdanal/sigs/T16859.stderr - testsuite/tests/ghci/should_run/T21052.stdout - testsuite/tests/simplCore/should_compile/T23083.stderr - + testsuite/tests/simplCore/should_run/T20749.hs - + testsuite/tests/simplCore/should_run/T20749.stdout - + testsuite/tests/simplCore/should_run/T24662.hs - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/simplStg/should_compile/T19717.stderr - testsuite/tests/simplStg/should_compile/inferTags002.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -640,6 +640,8 @@ pcDataConWithFixity' declared_infix dc_name wrk_key rri -- See Note [Constructor tag allocation] and #14657 data_con = mkDataCon dc_name declared_infix prom_info (map (const no_bang) arg_tys) + (map (const HsLazy) arg_tys) + (map (const NotMarkedStrict) arg_tys) [] -- No labelled fields tyvars ex_tyvars conc_tyvars ===================================== compiler/GHC/Core.hs ===================================== @@ -42,7 +42,7 @@ module GHC.Core ( foldBindersOfBindStrict, foldBindersOfBindsStrict, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, - collectArgs, stripNArgs, collectArgsTicks, flattenBinds, + collectArgs, collectValArgs, stripNArgs, collectArgsTicks, flattenBinds, collectFunSimple, exprToType, @@ -1029,6 +1029,64 @@ tail position: A cast changes the type, but the type must be the same. But operationally, casts are vacuous, so this is a bit unfortunate! See #14610 for ideas how to fix this. +Note [Strict fields in Core] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Evaluating a data constructor worker evaluates its strict fields. + +In other words, if `MkT` is strict in its first field and `xs` reduces to +`error "boom"`, then `MkT xs b` will throw that error. +Consequently, it is sound to seq the field before the call to the constructor, +e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`. +Let's call this transformation "field seq insertion". + +Note in particular that the data constructor application `MkT xs b` above is +*not* a value, unless `xs` is! + +This has pervasive effect on the Core pipeline: + + * `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the + strict arguments of a DataCon worker are values/ok-for-spec themselves. + + * `exprIsConApp_maybe` inserts field seqs in the `FloatBind`s it returns, so + that the Simplifier, Constant-folding, the pattern-match checker, etc. + all see the inserted field seqs when they match on strict workers. Often this + is just to emphasise strict semantics, but for case-of-known constructor + and case-to-let, field insertion is *vital*, otherwise these transformations + would lose field seqs that the user expects to happen, perhaps in order to + fix a space leak. For example, + case MkT xs b of MkT xs' b' -> b' + optimising this expression with case-of-known-con must leave behind the + field seq on `xs`, thus + case xs of xs' { __DEFAULT -> b } + + * The demand signature of a data constructor is strict in strict field + position when otherwise it is lazy. Likewise the demand *transformer* + of a DataCon worker can stricten up demands on strict field args. + See Note [Demand transformer for data constructors]. + + * In the absence of `-fpedantic-bottoms`, it is still possible that some seqs + are ultimately dropped or delayed due to eta-expansion. + See Note [Dealing with bottom]. + +Strict field semantics is exploited in STG by Note [Tag Inference]: +It performs field seq insertion to statically guarantee *taggedness* of strict +fields, establishing the Note [STG Strict Field Invariant]. (Happily, most +of those seqs are immediately detected as redundant by tag inference and are +omitted.) From then on, DataCon worker semantics are actually lazy, hence it is +important that STG passes maintain the Strict Field Invariant. + +Historical Note: +The delightfully simple description of strict field semantics is the result of +a long saga (#20749, the bits about strict data constructors in #21497, #22475), +where we tried a more lenient (but actually not) semantics first that would +allow both strict and lazy implementations of DataCon workers. This was favoured +because the "pervasive effect" throughout the compiler was deemed too large +(when it really turned out to be quite modest). +Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the +same way as above, otherwise the analysis would not be conservative wrt. the +lenient semantics (which includes the strict one). It is also much harder to +explain and maintain, as it turned out. + ************************************************************************ * * In/Out type synonyms @@ -2158,6 +2216,17 @@ collectArgs expr go (App f a) as = go f (a:as) go e as = (e, as) +-- | Takes a nested application expression and returns the function +-- being applied and the arguments to which it is applied +collectValArgs :: Expr b -> (Expr b, [Arg b]) +collectValArgs expr + = go expr [] + where + go (App f a) as + | isValArg a = go f (a:as) + | otherwise = go f as + go e as = (e, as) + -- | Takes a nested application expression and returns the function -- being applied. Looking through casts and ticks to find it. collectFunSimple :: Expr b -> Expr b ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -49,18 +49,20 @@ module GHC.Core.DataCon ( dataConIsInfix, dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitTyThings, - dataConRepStrictness, dataConImplBangs, dataConBoxer, + dataConRepStrictness, + dataConImplBangs, dataConBoxer, splitDataProductType_maybe, -- ** Predicates on DataCons isNullarySrcDataCon, isNullaryRepDataCon, + isLazyDataConRep, isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon, isUnboxedSumDataCon, isCovertGadtDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, dataConUserTyVarsNeedWrapper, checkDataConTyVars, - isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, + isBanged, isUnpacked, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, -- ** Promotion related functions @@ -524,6 +526,18 @@ data DataCon -- Matches 1-1 with dcOrigArgTys -- Hence length = dataConSourceArity dataCon + dcImplBangs :: [HsImplBang], + -- The actual decisions made (including failures) + -- about the original arguments; 1-1 with orig_arg_tys + -- See Note [Bangs on data constructor arguments] + + dcStricts :: [StrictnessMark], + -- One mark for every field of the DataCon worker; + -- if it's empty, then all fields are lazy, + -- otherwise 1-1 with dataConRepArgTys. + -- See also Note [Strict fields in Core] in GHC.Core + -- for the effect on the strictness signature + dcFields :: [FieldLabel], -- Field labels for this constructor, in the -- same order as the dcOrigArgTys; @@ -826,13 +840,6 @@ data DataConRep -- after unboxing and flattening, -- and *including* all evidence args - , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] - - , dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures) - -- about the original arguments; 1-1 with orig_arg_tys - -- See Note [Bangs on data constructor arguments] - } type DataConEnv a = UniqFM DataCon a -- Keyed by DataCon @@ -901,43 +908,8 @@ eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Data-con worker strictness] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Notice that we do *not* say the worker Id is strict even if the data -constructor is declared strict - e.g. data T = MkT ![Int] Bool -Even though most often the evals are done by the *wrapper* $WMkT, there are -situations in which tag inference will re-insert evals around the worker. -So for all intents and purposes the *worker* MkT is strict, too! - -Unfortunately, if we exposed accurate strictness of DataCon workers, we'd -see the following transformation: - - f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs - ==> { drop-seq, binder swap on xs' } - f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs - ==> { case-to-let } - f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs! - -I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs` -and then doing case-to-let. The issue is that `exprIsHNF` currently says that -every DataCon worker app is a value. The implicit assumption is that surrounding -evals will have evaluated strict fields like `xs` before! But now that we had -just dropped the eval on `xs`, that assumption is no longer valid. - -Long story short: By keeping the demand signature lazy, the Simplifier will not -drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others -remains sound. - -Similarly, during demand analysis in dmdTransformDataConSig, we bump up the -field demand with `C_01`, *not* `C_11`, because the latter exposes too much -strictness that will drop the eval on `xs` above. - -This issue is discussed at length in -"Failed idea: no wrappers for strict data constructors" in #21497 and #22475. - -Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool @@ -963,8 +935,8 @@ Terminology: the flag settings in the importing module. Also see Note [Bangs on imported data constructors] in GHC.Types.Id.Make -* The dcr_bangs field of the dcRep field records the [HsImplBang] - If T was defined in this module, Without -O the dcr_bangs might be +* The dcImplBangs field records the [HsImplBang] + If T was defined in this module, Without -O the dcImplBangs might be [HsStrict _, HsStrict _, HsLazy] With -O it might be [HsStrict _, HsUnpack _, HsLazy] @@ -973,6 +945,19 @@ Terminology: With -XStrictData it might be [HsStrict _, HsUnpack _, HsStrict _] +* Core passes will often need to know whether the DataCon worker or wrapper in + an application is strict in some (lifted) field or not. This is tracked in the + demand signature attached to a DataCon's worker resp. wrapper Id. + + So if you've got a DataCon dc, you can get the demand signature by + `idDmdSig (dataConWorkId dc)` and make out strict args by testing with + `isStrictDmd`. Similarly, `idDmdSig <$> dataConWrapId_maybe dc` gives + you the demand signature of the wrapper, if it exists. + + These demand signatures are set in GHC.Types.Id.Make.mkDataConWorkId, + compute from the single source of truth `dataConRepStrictness`, which is + generated from `dcStricts`. + Note [Detecting useless UNPACK pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to issue a warning when there's an UNPACK pragma in the source code, @@ -1008,7 +993,6 @@ we consult HsImplBang: The boolean flag is used only for this warning. See #11270 for motivation. - ************************************************************************ * * \subsection{Instances} @@ -1110,6 +1094,11 @@ isBanged (HsUnpack {}) = True isBanged (HsStrict {}) = True isBanged HsLazy = False +isUnpacked :: HsImplBang -> Bool +isUnpacked (HsUnpack {}) = True +isUnpacked (HsStrict {}) = False +isUnpacked HsLazy = False + isSrcStrict :: SrcStrictness -> Bool isSrcStrict SrcStrict = True isSrcStrict _ = False @@ -1135,13 +1124,15 @@ cbvFromStrictMark MarkedStrict = MarkedCbv -- | Build a new data constructor mkDataCon :: Name - -> Bool -- ^ Is the constructor declared infix? - -> TyConRepName -- ^ TyConRepName for the promoted TyCon - -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user - -> [FieldLabel] -- ^ Field labels for the constructor, - -- if it is a record, otherwise empty - -> [TyVar] -- ^ Universals. - -> [TyCoVar] -- ^ Existentials. + -> Bool -- ^ Is the constructor declared infix? + -> TyConRepName -- ^ TyConRepName for the promoted TyCon + -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user + -> [HsImplBang] -- ^ Strictness/unpack annotations, as inferred by the compiler + -> [StrictnessMark] -- ^ Strictness marks for the DataCon worker's fields in Core + -> [FieldLabel] -- ^ Field labels for the constructor, + -- if it is a record, otherwise empty + -> [TyVar] -- ^ Universals. + -> [TyCoVar] -- ^ Existentials. -> ConcreteTyVars -- ^ TyVars which must be instantiated with -- concrete types @@ -1163,7 +1154,9 @@ mkDataCon :: Name -- Can get the tag from the TyCon mkDataCon name declared_infix prom_info - arg_stricts -- Must match orig_arg_tys 1-1 + arg_stricts -- Must match orig_arg_tys 1-1 + impl_bangs -- Must match orig_arg_tys 1-1 + str_marks -- Must be empty or match dataConRepArgTys 1-1 fields univ_tvs ex_tvs conc_tvs user_tvbs eq_spec theta @@ -1180,6 +1173,8 @@ mkDataCon name declared_infix prom_info = con where is_vanilla = null ex_tvs && null eq_spec && null theta + str_marks' | not $ any isMarkedStrict str_marks = [] + | otherwise = str_marks con = MkData {dcName = name, dcUnique = nameUnique name, dcVanilla = is_vanilla, dcInfix = declared_infix, @@ -1192,7 +1187,8 @@ mkDataCon name declared_infix prom_info dcStupidTheta = stupid_theta, dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, dcRepTyCon = rep_tycon, - dcSrcBangs = arg_stricts, + dcSrcBangs = arg_stricts, dcImplBangs = impl_bangs, + dcStricts = str_marks', dcFields = fields, dcTag = tag, dcRepType = rep_ty, dcWorkId = work_id, dcRep = rep, @@ -1435,20 +1431,25 @@ isNullarySrcDataCon dc = dataConSourceArity dc == 0 isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 +isLazyDataConRep :: DataCon -> Bool +-- ^ True <==> All fields are lazy +isLazyDataConRep dc = null (dcStricts dc) + dataConRepStrictness :: DataCon -> [StrictnessMark] --- ^ Give the demands on the arguments of a --- Core constructor application (Con dc args) -dataConRepStrictness dc = case dcRep dc of - NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc] - DCR { dcr_stricts = strs } -> strs +-- ^ Give the demands on the runtime arguments of a Core DataCon worker +-- application. +-- The length of the list matches `dataConRepArgTys` (e.g., the number +-- of runtime arguments). +dataConRepStrictness dc + | isLazyDataConRep dc + = replicate (dataConRepArity dc) NotMarkedStrict + | otherwise + = dcStricts dc dataConImplBangs :: DataCon -> [HsImplBang] -- The implementation decisions about the strictness/unpack of each -- source program argument to the data constructor -dataConImplBangs dc - = case dcRep dc of - NoDataConRep -> replicate (dcSourceArity dc) HsLazy - DCR { dcr_bangs = bangs } -> bangs +dataConImplBangs dc = dcImplBangs dc dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -1533,7 +1533,7 @@ myExprIsCheap (AE { am_opts = opts, am_sigs = sigs }) e mb_ty -- See Note [Eta expanding through dictionaries] -- See Note [Eta expanding through CallStacks] - cheap_fun e = exprIsCheapX (myIsCheapApp sigs) e + cheap_fun e = exprIsCheapX (myIsCheapApp sigs) False e -- | A version of 'isCheapApp' that considers results from arity analysis. -- See Note [Arity analysis] for what's in the signature environment and why ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -209,7 +209,7 @@ cprAnal, cprAnal' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' cprAnal env e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ - cprAnal' env e + cprAnal' env e cprAnal' _ (Lit lit) = (topCprType, Lit lit) cprAnal' _ (Type ty) = (topCprType, Type ty) -- Doesn't happen, in fact @@ -296,9 +296,16 @@ data TermFlag -- Better than using a Bool -- See Note [Nested CPR] exprTerminates :: CoreExpr -> TermFlag +-- ^ A /very/ simple termination analysis. exprTerminates e - | exprIsHNF e = Terminates -- A /very/ simple termination analysis. - | otherwise = MightDiverge + | exprIsHNF e = Terminates + | exprOkForSpeculation e = Terminates + | otherwise = MightDiverge + -- Annoyingly, we have to check both for HNF and ok-for-spec. + -- * `I# (x# *# 2#)` is ok-for-spec, but not in HNF. Still worth CPR'ing! + -- * `lvl` is an HNF if its unfolding is evaluated + -- (perhaps `lvl = I# 0#` at top-level). But, tiresomely, it is never + -- ok-for-spec due to Note [exprOkForSpeculation and evaluated variables]. cprAnalApp :: AnalEnv -> CoreExpr -> [(CprType, CoreArg)] -> (CprType, CoreExpr) -- Main function that takes care of /nested/ CPR. See Note [Nested CPR] @@ -367,8 +374,8 @@ cprTransformDataConWork env con args , wkr_arity <= mAX_CPR_SIZE -- See Note [Trimming to mAX_CPR_SIZE] , args `lengthIs` wkr_arity , ae_rec_dc env con /= DefinitelyRecursive -- See Note [CPR for recursive data constructors] - -- , pprTrace "cprTransformDataConWork" (ppr con <+> ppr wkr_arity <+> ppr args) True - = CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) + = -- pprTraceWith "cprTransformDataConWork" (\r -> ppr con <+> ppr wkr_arity <+> ppr args <+> ppr r) $ + CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) | otherwise = topCprType where @@ -505,7 +512,8 @@ cprAnalBind env id rhs | isDataStructure id -- Data structure => no code => no need to analyse rhs = (id, rhs, env) | otherwise - = (id `setIdCprSig` sig', rhs', env') + = -- pprTrace "cprAnalBind" (ppr id <+> ppr sig <+> ppr sig') + (id `setIdCprSig` sig', rhs', env') where (rhs_ty, rhs') = cprAnal env rhs -- possibly trim thunk CPR info ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -835,6 +835,10 @@ to the Divergence lattice, but in practice it turned out to be hard to untaint from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. +You might think that we should check for side-effects rather than just for +precise exceptions. Right you are! See Note [Side-effects and strictness] +for why we unfortunately do not. + Note [Demand analysis for recursive data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T11545 features a single-product, recursive data type ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -8,14 +8,13 @@ module GHC.Core.Opt.Simplify.Env ( -- * The simplifier mode - SimplMode(..), updMode, - smPedanticBottoms, smPlatform, + SimplMode(..), updMode, smPlatform, -- * Environments SimplEnv(..), pprSimplEnv, -- Temp not abstract seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle, seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames, - seOptCoercionOpts, sePedanticBottoms, sePhase, sePlatform, sePreInline, + seOptCoercionOpts, sePhase, sePlatform, sePreInline, seRuleOpts, seRules, seUnfoldingOpts, mkSimplEnv, extendIdSubst, extendCvIdSubst, extendTvSubst, extendCvSubst, @@ -235,9 +234,6 @@ seNames env = sm_names (seMode env) seOptCoercionOpts :: SimplEnv -> OptCoercionOpts seOptCoercionOpts env = sm_co_opt_opts (seMode env) -sePedanticBottoms :: SimplEnv -> Bool -sePedanticBottoms env = smPedanticBottoms (seMode env) - sePhase :: SimplEnv -> CompilerPhase sePhase env = sm_phase (seMode env) @@ -292,9 +288,6 @@ instance Outputable SimplMode where where pp_flag f s = ppUnless f (text "no") <+> s -smPedanticBottoms :: SimplMode -> Bool -smPedanticBottoms opts = ao_ped_bot (sm_arity_opts opts) - smPlatform :: SimplMode -> Platform smPlatform opts = roPlatform (sm_rule_opts opts) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2204,14 +2204,14 @@ zap the SubstEnv. This is VITAL. Consider We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!! -Note [Fast path for data constructors] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Fast path for lazy data constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For applications of a data constructor worker, the full glory of rebuildCall is a waste of effort; * They never inline, obviously * They have no rewrite rules -* They are not strict (see Note [Data-con worker strictness] - in GHC.Core.DataCon) +* Though they might be strict (see Note [Strict fields in Core] in GHC.Core), + we will exploit that strictness through their demand signature So it's fine to zoom straight to `rebuild` which just rebuilds the call in a very straightforward way. @@ -2235,7 +2235,7 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont - | isDataConWorkId var -- See Note [Fast path for data constructors] + | isDataConWorkId var -- See Note [Fast path for lazy data constructors] = rebuild env (Var var) cont | otherwise = case substId env var of @@ -3420,7 +3420,7 @@ a case pattern. This is *important*. Consider We really must record that b is already evaluated so that we don't go and re-evaluate it when constructing the result. -See Note [Data-con worker strictness] in GHC.Core.DataCon +See Note [Strict fields in Core] in GHC.Core. NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1277,11 +1277,8 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplifier produces rhs[exp/a], changing semantics if exp is not ok-for-spec -- Good: returning (Mk#, [x]) with a float of case exp of x { DEFAULT -> [] } -- simplifier produces case exp of a { DEFAULT -> exp[x/a] } - = let arg' = subst_expr subst arg - bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) - float = FloatCase arg' bndr DEFAULT [] - subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) mco) + , (subst', float, bndr) <- case_bind subst arg arg_type + = go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise = go subst floats fun (CC (subst_expr subst arg : args) mco) @@ -1324,8 +1321,10 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun - = succeedWith in_scope floats $ - pushCoDataCon con args mco + , (in_scope', seq_floats, args') <- mkFieldSeqFloats in_scope con args + -- mkFieldSeqFloats: See Note [Strict fields in Core] + = succeedWith in_scope' (seq_floats ++ floats) $ + pushCoDataCon con args' mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1411,6 +1410,38 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr extend (Left in_scope) v e = Right (extendSubst (mkEmptySubst in_scope) v e) extend (Right s) v e = Right (extendSubst s v e) + case_bind :: Either InScopeSet Subst -> CoreExpr -> Type -> (Either InScopeSet Subst, FloatBind, Id) + case_bind subst expr expr_ty = (subst', float, bndr) + where + bndr = setCaseBndrEvald MarkedStrict $ + uniqAway (subst_in_scope subst) $ + mkWildValBinder ManyTy expr_ty + subst' = subst_extend_in_scope subst bndr + expr' = subst_expr subst expr + float = FloatCase expr' bndr DEFAULT [] + + mkFieldSeqFloats :: InScopeSet -> DataCon -> [CoreExpr] -> (InScopeSet, [FloatBind], [CoreExpr]) + -- See Note [Strict fields in Core] for what a field seq is and why we + -- insert them + mkFieldSeqFloats in_scope dc args + | isLazyDataConRep dc + = (in_scope, [], args) + | otherwise + = (in_scope', floats', ty_args ++ val_args') + where + (ty_args, val_args) = splitAtList (dataConUnivAndExTyCoVars dc) args + (in_scope', floats', val_args') = foldr do_one (in_scope, [], []) $ zipEqual "mkFieldSeqFloats" str_marks val_args + str_marks = dataConRepStrictness dc + do_one (str, arg) (in_scope,floats,args) + | NotMarkedStrict <- str = no_seq + | exprIsHNF arg = no_seq + | otherwise = (in_scope', float:floats, Var bndr:args) + where + no_seq = (in_scope, floats, arg:args) + (in_scope', float, bndr) = + case case_bind (Left in_scope) arg (exprType arg) of + (Left in_scope', float, bndr) -> (in_scope', float, bndr) + (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right) -- See Note [exprIsConApp_maybe on literal strings] dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -55,7 +55,7 @@ module GHC.Core.Type ( splitForAllForAllTyBinders, splitForAllForAllTyBinder_maybe, splitForAllTyCoVar_maybe, splitForAllTyCoVar, splitForAllTyVar_maybe, splitForAllCoVar_maybe, - splitPiTy_maybe, splitPiTy, splitPiTys, + splitPiTy_maybe, splitPiTy, splitPiTys, collectPiTyBinders, getRuntimeArgTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, @@ -290,6 +290,7 @@ import GHC.Utils.Panic import GHC.Data.FastString import GHC.Data.Maybe ( orElse, isJust, firstJust ) +import GHC.List (build) -- $type_classification -- #type_classification# @@ -2031,6 +2032,18 @@ splitPiTys ty = split ty ty [] split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs split orig_ty _ bs = (reverse bs, orig_ty) +collectPiTyBinders :: Type -> [PiTyBinder] +collectPiTyBinders ty = build $ \c n -> + let + split (ForAllTy b res) = Named b `c` split res + split (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) + = Anon (Scaled w arg) af `c` split res + split ty | Just ty' <- coreView ty = split ty' + split _ = n + in + split ty +{-# INLINE collectPiTyBinders #-} + -- | Extracts a list of run-time arguments from a function type, -- looking through newtypes to the right of arrows. -- ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1493,18 +1493,23 @@ in this (which it previously was): in \w. v True -} --------------------- -exprIsWorkFree :: CoreExpr -> Bool -- See Note [exprIsWorkFree] -exprIsWorkFree e = exprIsCheapX isWorkFreeApp e - -exprIsCheap :: CoreExpr -> Bool -exprIsCheap e = exprIsCheapX isCheapApp e +------------------------------------- +type CheapAppFun = Id -> Arity -> Bool + -- Is an application of this function to n *value* args + -- always cheap, assuming the arguments are cheap? + -- True mainly of data constructors, partial applications; + -- but with minor variations: + -- isWorkFreeApp + -- isCheapApp + -- isExpandableApp -exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool +exprIsCheapX :: CheapAppFun -> Bool -> CoreExpr -> Bool {-# INLINE exprIsCheapX #-} --- allow specialization of exprIsCheap and exprIsWorkFree +-- allow specialization of exprIsCheap, exprIsWorkFree and exprIsExpandable -- instead of having an unknown call to ok_app -exprIsCheapX ok_app e +-- expandable: Only True for exprIsExpandable, where Case and Let are never +-- expandable. +exprIsCheapX ok_app expandable e = ok e where ok e = go 0 e @@ -1515,7 +1520,7 @@ exprIsCheapX ok_app e go _ (Type {}) = True go _ (Coercion {}) = True go n (Cast e _) = go n e - go n (Case scrut _ _ alts) = ok scrut && + go n (Case scrut _ _ alts) = not expandable && ok scrut && and [ go n rhs | Alt _ _ rhs <- alts ] go n (Tick t e) | tickishCounts t = False | otherwise = go n e @@ -1523,90 +1528,26 @@ exprIsCheapX ok_app e | otherwise = go n e go n (App f e) | isRuntimeArg e = go (n+1) f && ok e | otherwise = go n f - go n (Let (NonRec _ r) e) = go n e && ok r - go n (Let (Rec prs) e) = go n e && all (ok . snd) prs + go n (Let (NonRec _ r) e) = not expandable && go n e && ok r + go n (Let (Rec prs) e) = not expandable && go n e && all (ok . snd) prs -- Case: see Note [Case expressions are work-free] -- App, Let: see Note [Arguments and let-bindings exprIsCheapX] +-------------------- +exprIsWorkFree :: CoreExpr -> Bool +-- See Note [exprIsWorkFree] +exprIsWorkFree e = exprIsCheapX isWorkFreeApp False e -{- Note [exprIsExpandable] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -An expression is "expandable" if we are willing to duplicate it, if doing -so might make a RULE or case-of-constructor fire. Consider - let x = (a,b) - y = build g - in ....(case x of (p,q) -> rhs)....(foldr k z y).... - -We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), -but we do want - - * the case-expression to simplify - (via exprIsConApp_maybe, exprIsLiteral_maybe) - - * the foldr/build RULE to fire - (by expanding the unfolding during rule matching) - -So we classify the unfolding of a let-binding as "expandable" (via the -uf_expandable field) if we want to do this kind of on-the-fly -expansion. Specifically: - -* True of constructor applications (K a b) - -* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. - (NB: exprIsCheap might not be true of this) - -* False of case-expressions. If we have - let x = case ... in ...(case x of ...)... - we won't simplify. We have to inline x. See #14688. - -* False of let-expressions (same reason); and in any case we - float lets out of an RHS if doing so will reveal an expandable - application (see SimplEnv.doFloatFromRhs). - -* Take care: exprIsExpandable should /not/ be true of primops. I - found this in test T5623a: - let q = /\a. Ptr a (a +# b) - in case q @ Float of Ptr v -> ...q... - - q's inlining should not be expandable, else exprIsConApp_maybe will - say that (q @ Float) expands to (Ptr a (a +# b)), and that will - duplicate the (a +# b) primop, which we should not do lightly. - (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) --} +-------------------- +exprIsCheap :: CoreExpr -> Bool +-- See Note [exprIsCheap] +exprIsCheap e = exprIsCheapX isCheapApp False e -------------------------------------- +-------------------- exprIsExpandable :: CoreExpr -> Bool -- See Note [exprIsExpandable] -exprIsExpandable e - = ok e - where - ok e = go 0 e - - -- n is the number of value arguments - go n (Var v) = isExpandableApp v n - go _ (Lit {}) = True - go _ (Type {}) = True - go _ (Coercion {}) = True - go n (Cast e _) = go n e - go n (Tick t e) | tickishCounts t = False - | otherwise = go n e - go n (Lam x e) | isRuntimeVar x = n==0 || go (n-1) e - | otherwise = go n e - go n (App f e) | isRuntimeArg e = go (n+1) f && ok e - | otherwise = go n f - go _ (Case {}) = False - go _ (Let {}) = False - - -------------------------------------- -type CheapAppFun = Id -> Arity -> Bool - -- Is an application of this function to n *value* args - -- always cheap, assuming the arguments are cheap? - -- True mainly of data constructors, partial applications; - -- but with minor variations: - -- isWorkFreeApp - -- isCheapApp +exprIsExpandable e = exprIsCheapX isExpandableApp True e isWorkFreeApp :: CheapAppFun isWorkFreeApp fn n_val_args @@ -1626,7 +1567,7 @@ isCheapApp fn n_val_args | isDeadEndId fn = True -- See Note [isCheapApp: bottoming functions] | otherwise = case idDetails fn of - DataConWorkId {} -> True -- Actually handled by isWorkFreeApp + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId op _ -> primOpIsCheap op @@ -1641,6 +1582,7 @@ isExpandableApp fn n_val_args | isWorkFreeApp fn n_val_args = True | otherwise = case idDetails fn of + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId {} -> False @@ -1672,6 +1614,50 @@ isExpandableApp fn n_val_args I'm not sure why we have a special case for bottoming functions in isCheapApp. Maybe we don't need it. +Note [exprIsExpandable] +~~~~~~~~~~~~~~~~~~~~~~~ +An expression is "expandable" if we are willing to duplicate it, if doing +so might make a RULE or case-of-constructor fire. Consider + let x = (a,b) + y = build g + in ....(case x of (p,q) -> rhs)....(foldr k z y).... + +We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), +but we do want + + * the case-expression to simplify + (via exprIsConApp_maybe, exprIsLiteral_maybe) + + * the foldr/build RULE to fire + (by expanding the unfolding during rule matching) + +So we classify the unfolding of a let-binding as "expandable" (via the +uf_expandable field) if we want to do this kind of on-the-fly +expansion. Specifically: + +* True of constructor applications (K a b) + +* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. + (NB: exprIsCheap might not be true of this) + +* False of case-expressions. If we have + let x = case ... in ...(case x of ...)... + we won't simplify. We have to inline x. See #14688. + +* False of let-expressions (same reason); and in any case we + float lets out of an RHS if doing so will reveal an expandable + application (see SimplEnv.doFloatFromRhs). + +* Take care: exprIsExpandable should /not/ be true of primops. I + found this in test T5623a: + let q = /\a. Ptr a (a +# b) + in case q @ Float of Ptr v -> ...q... + + q's inlining should not be expandable, else exprIsConApp_maybe will + say that (q @ Float) expands to (Ptr a (a +# b)), and that will + duplicate the (a +# b) primop, which we should not do lightly. + (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) + Note [isExpandableApp: bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's important that isExpandableApp does not respond True to bottoming @@ -1852,7 +1838,7 @@ expr_ok fun_ok primop_ok other_expr _ -> False ----------------------------- -app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool +app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreArg] -> Bool app_ok fun_ok primop_ok fun args | not (fun_ok fun) = False -- This code path is only taken for Note [Speculative evaluation] @@ -1867,13 +1853,11 @@ app_ok fun_ok primop_ok fun args -- DFuns terminate, unless the dict is implemented -- with a newtype in which case they may not - DataConWorkId {} -> args_ok - -- The strictness of the constructor has already - -- been expressed by its "wrapper", so we don't need - -- to take the arguments into account - -- Well, we thought so. But it's definitely wrong! - -- See #20749 and Note [How untagged pointers can - -- end up in strict fields] in GHC.Stg.InferTags + DataConWorkId dc + | isLazyDataConRep dc + -> args_ok + | otherwise + -> fields_ok (dataConRepStrictness dc) ClassOpId _ is_terminating_result | is_terminating_result -- See Note [exprOkForSpeculation and type classes] @@ -1923,7 +1907,7 @@ app_ok fun_ok primop_ok fun args -- Even if a function call itself is OK, any unlifted -- args are still evaluated eagerly and must be checked - args_ok = and (zipWith arg_ok arg_tys args) + args_ok = all2Prefix arg_ok arg_tys args arg_ok :: PiTyVarBinder -> CoreExpr -> Bool arg_ok (Named _) _ = True -- A type argument arg_ok (Anon ty _) arg -- A term argument @@ -1932,6 +1916,17 @@ app_ok fun_ok primop_ok fun args | otherwise = expr_ok fun_ok primop_ok arg + -- Used for DataCon worker arguments + fields_ok str_marks = all3Prefix field_ok arg_tys str_marks args + field_ok :: PiTyVarBinder -> StrictnessMark -> CoreExpr -> Bool + field_ok (Named _) _ _ = True + field_ok (Anon ty _) str arg + | NotMarkedStrict <- str -- iff it's a lazy field + , definitelyLiftedType (scaledThing ty) -- and its type is lifted + = True -- then the worker app does not eval + | otherwise + = expr_ok fun_ok primop_ok arg + ----------------------------- altsAreExhaustive :: [Alt b] -> Bool -- True <=> the case alternatives are definitely exhaustive @@ -2157,12 +2152,14 @@ exprIsConLike = exprIsHNFlike isConLikeId isConLikeUnfolding -- or PAPs. -- exprIsHNFlike :: HasDebugCallStack => (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool -exprIsHNFlike is_con is_con_unf = is_hnf_like +exprIsHNFlike is_con is_con_unf e + = -- pprTraceWith "hnf" (\r -> ppr r <+> ppr e) $ + is_hnf_like e where is_hnf_like (Var v) -- NB: There are no value args at this point - = id_app_is_value v 0 -- Catches nullary constructors, - -- so that [] and () are values, for example - -- and (e.g.) primops that don't have unfoldings + = id_app_is_value v [] -- Catches nullary constructors, + -- so that [] and () are values, for example + -- and (e.g.) primops that don't have unfoldings || is_con_unf (idUnfolding v) -- Check the thing's unfolding; it might be bound to a value -- or to a guaranteed-evaluated variable (isEvaldUnfolding) @@ -2186,7 +2183,7 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like -- See Note [exprIsHNF Tick] is_hnf_like (Cast e _) = is_hnf_like e is_hnf_like (App e a) - | isValArg a = app_is_value e 1 + | isValArg a = app_is_value e [a] | otherwise = is_hnf_like e is_hnf_like (Let _ e) = is_hnf_like e -- Lazy let(rec)s don't affect us is_hnf_like (Case e b _ as) @@ -2194,26 +2191,63 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like = is_hnf_like rhs is_hnf_like _ = False - -- 'n' is the number of value args to which the expression is applied - -- And n>0: there is at least one value argument - app_is_value :: CoreExpr -> Int -> Bool - app_is_value (Var f) nva = id_app_is_value f nva - app_is_value (Tick _ f) nva = app_is_value f nva - app_is_value (Cast f _) nva = app_is_value f nva - app_is_value (App f a) nva - | isValArg a = - app_is_value f (nva + 1) && - not (needsCaseBinding (exprType a) a) - -- For example f (x /# y) where f has arity two, and the first - -- argument is unboxed. This is not a value! - -- But f 34# is a value. - -- NB: Check app_is_value first, the arity check is cheaper - | otherwise = app_is_value f nva - app_is_value _ _ = False - - id_app_is_value id n_val_args - = is_con id - || idArity id > n_val_args + -- Collect arguments through Casts and Ticks and call id_app_is_value + app_is_value :: CoreExpr -> [CoreArg] -> Bool + app_is_value (Var f) as = id_app_is_value f as + app_is_value (Tick _ f) as = app_is_value f as + app_is_value (Cast f _) as = app_is_value f as + app_is_value (App f a) as | isValArg a = app_is_value f (a:as) + | otherwise = app_is_value f as + app_is_value _ _ = False + + id_app_is_value id val_args = + case compare (idArity id) (length val_args) of + EQ | is_con id -> -- Saturated app of a DataCon/CONLIKE Id + case mb_str_marks id of + Just str_marks -> -- with strict fields + assert (val_args `equalLength` str_marks) $ + fields_hnf str_marks + Nothing -> -- without strict fields: like PAP + args_hnf -- NB: CONLIKEs are lazy! + + GT -> -- PAP: Check unlifted val_args + args_hnf + + _ -> False + + where + -- Saturated, Strict DataCon: Check unlifted val_args and strict fields + fields_hnf str_marks = all3Prefix check_field val_arg_tys str_marks val_args + + -- PAP: Check unlifted val_args + args_hnf = all2Prefix check_arg val_arg_tys val_args + + fun_ty = idType id + val_arg_tys = mapMaybe anonPiTyBinderType_maybe (collectPiTyBinders fun_ty) + -- val_arg_tys = map exprType val_args, but much less costly. + -- The obvious definition regresses T16577 by 30% so we don't do it. + + check_arg a_ty a + | mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- Check unliftedness; for example f (x /# 12#) where f has arity two, + -- and the first argument is unboxed. This is not a value! + -- But f 34# is a value, so check args for HNFs. + -- NB: We check arity (and CONLIKEness) first because it's cheaper + -- and we reject quickly on saturated apps. + check_field a_ty str a + | isMarkedStrict str || mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- isMarkedStrict: Respect Note [Strict fields in Core] + + mb_str_marks id + | Just dc <- isDataConWorkId_maybe id + , not (isLazyDataConRep dc) + = Just (dataConRepStrictness dc) + | otherwise + = Nothing + +{-# INLINE exprIsHNFlike #-} {- Note [exprIsHNF Tick] @@ -2775,7 +2809,7 @@ This means the seqs on x and y both become no-ops and compared to the first vers The downside is that the caller of $wfoo potentially has to evaluate `y` once if we can't prove it isn't already evaluated. But y coming out of a strict field is in WHNF so safe to evaluated. And most of the time it will be properly tagged+evaluated -already at the call site because of the Strict Field Invariant! See Note [Strict Field Invariant] for more in this. +already at the call site because of the Strict Field Invariant! See Note [STG Strict Field Invariant] for more in this. This makes GHC itself around 1% faster despite doing slightly more work! So this is generally quite good. We only apply this when we think there is a benefit in doing so however. There are a number of cases in which ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -644,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 + (new_float, _bndr2) = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -729,9 +729,9 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env False v rhs2 + ; let (float, v') = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float - , cpeEtaExpand arity (Var v)) }) + , cpeEtaExpand arity (Var v')) }) -- Wrap floating ticks ; let (floats4, rhs4) = wrapTicks floats3 rhs3 @@ -907,10 +907,10 @@ cpeRhsE env (Case scrut bndr ty alts) ; alts'' <- mapM (sat_alt env') alts' ; case alts'' of - [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] - | let is_unlifted = isUnliftedType (idType bndr2) - , let float = mkCaseFloat is_unlifted bndr2 scrut' - -> return (snocFloat floats float, rhs) +-- [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] +-- | let is_unlifted = isUnliftedType (idType bndr2) +-- , let float = mkCaseFloat is_unlifted bndr2 scrut' +-- -> return (snocFloat floats float, rhs) _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) @@ -1570,8 +1570,9 @@ cpeArg env dmd arg ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 -- See Note [Eta expansion of arguments in CorePrep] - ; let arg_float = mkNonRecFloat env is_unlifted v arg3 - ; return (snocFloat floats2 arg_float, varToCoreExpr v) } + ; let (arg_float, v') = mkNonRecFloat env is_unlifted v arg3 + ; pprTraceM "cpeArg" (ppr arg1 $$ ppr dec $$ ppr arg2) + ; return (snocFloat floats2 arg_float, varToCoreExpr v') } } cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity @@ -1793,10 +1794,10 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We pin demand info on floated lets, so that we can see the one-shot thunks. +We pin demand info on floated lets, so that we can see one-shot thunks. For example, f (g x) -where `f` uses its argument at least once, creates a Float for `y = g x` and we +where `f` uses its argument at most once, creates a Float for `y = g x` and we should better pin appropriate demand info on `y`. Note [Flatten case-binds] @@ -1807,7 +1808,7 @@ Suppose we have the following call, where f is strict: `case` out because `f` is strict.) In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` - Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + Float (a = case x of y { DEFAULT -> blah }) CaseBound top-lvl with the call `f a`. When we wrap that `Float` we will get @@ -1826,8 +1827,8 @@ This is easy to avoid: turn that into a FloatingBind of its own. This is easily done in the Case equation for `cpsRhsE`. Then our example will generate /two/ floats: - Float (y = x) CaseBound top_lvl - Float (a = blah) CaseBound top_lvl + Float (y = x) CaseBound str-ctx + Float (a = blah) CaseBound top-lvl and we'll end up with nested cases. @@ -1840,6 +1841,124 @@ Of course, the Simplifier never leaves us with an argument like this, but we and the above footwork in cpsRhsE avoids generating a nested case. +Note [Pin evaluatedness on floats] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider a call to a CBV function, such as a DataCon worker with *strict* fields, +in a *lazy* context, such as in the arg of a lazy function call to `f`: + + + data Box a = Box !a + ... f (Box e) ... -- f lazy, Box strict + +(A live example of this is T24730, inspired by $walexGetByte.) +During ANFisation, we will `mkNonRecFloat` for `e`, binding it to a +fresh binder `sat`, and binding `Box sat` as well to a fresh binder `sat2`. +We want to avoid allocating a thunk for `sat2` as often as possible, building +on the let floating mechanism in Case (2) of Note [wantFloatLocal]. + +Note that this mechanism requires `sat` to be detected as a value after +floating out any ok-for-spec floats, according to `exprIsHNF`. This means we +need an `evaldUnfolding` on `sat`, and `mkNonRecFloat` must do the pinning. + +There are two interesting cases: + + 1. When `e = I# (x +# 1#)`, we decompose into + case x +# 1# of x' -> + --- + I# x' + where everything above --- are floats and below --- is the residual RHS. + Here, `I# x'` is a value because `x'` is (NB: x' is a variable of unlifted type). + Following Case (2) of Note [wantFloatLocal], we want to float out the + ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's + field, to get + case x +# 1# of x' -> + let sat = I# x' in + --- + Box sat + And since we pin an `evaldUnfolding` on `sat`, we may even float out of + `f`'s lazy argument, again by Case (2) of Note [wantFloatLocal] + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 + If `sat` didn't have the `evaldUnfolding`, we'd get a large thunk in f's arg: + let sat2 = + case x +# 1# of x' -> + let sat = I# x' in + Box sat in + f sat2 + 2. + +Although `e` might not be a value, it might still decompose into floats that are +ok-for-spec and a value, for example + e = I# (x +# 1#) +decomposes into +Following Case (2) of Note [wantFloatLocal], we want to float out the +ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's +field, to get + case x +# 1# of x' -> + let sat = I# x' in + Box sat +Nice! But now we want to do the same for the argument to `f`, to get + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 +(NB: Since all floats are ok-for-spec, we may float out of the lazy argument.) +BUT, in order to do that in Case (2) of Note [wantFloatLocal], we must detect +`Box sat` as a value according to `exprIsHNF`; otherwise floating would be +unproductive. Crucially, this means we need `sat` to look evaluated, because +it ends up in a strict field. +We achieve this by attaching and `evaldUnfolding` to `sat` in `mkNonRecFloat`. + +*When + + 1. When `e=Just y` is a value, we will float `sat=Just y` as far as possible, + to top-level, even. It is important that we mark `sat` as evaluated (via + setting its unfolding to `evaldUnfolding`), otherwise we get a superfluous + thunk to carry out the field seq on Box's field, because + `exprIsHNF sat == False`: + + let sat = Just y in + let sat2 = case sat of x { __DEFAULT } -> Box x in + -- NONONO, want just `sat2 = Box x` + f sat2 + + This happened in $walexGetByte, where the thunk caused additional + allocation. + + 2. Similarly, when `e` is not a value, we still know that it is strictly + evaluated. Hence it is going to be case-bound, and we anticipate that `sat` + will be a case binder which is *always* evaluated. + Hence in this case, we also mark `sat` as evaluated via its unfolding. + This happened in GHC.Linker.Deps.$wgetLinkDeps, where without + `evaldUnfolding` we ended up with this: + + Word64Map = ... | Bin ... ... !Word64Map !Word64Map + case ... of { Word64Map.Bin a b l r -> + case insert ... of sat { __DEFAULT -> + case Word64Map.Bin a b l sat of sat2 { __DEFAULT -> + f sat2 + }}} + + Note that *the DataCon app `Bin a b l sat` was case-bound*, because it was + not detected to be a value according to `exprIsHNF`. + That is because the strict field `sat` lacked the `evaldUnfolding`, + although it ended up being case-bound. + + Small wrinkle: + It could be that `sat=insert ...` floats to top-level, where it is not + eagerly evaluated. In this case, we may not give `sat` an `evaldUnfolding`. + We detect this case by looking at the `FloatInfo` of `sat=insert ...`: If + it says `TopLvlFloatable`, we are conservative and will not give `sat` an + `evaldUnfolding`. + +TLDR; when creating a new float `sat=e` in `mkNonRecFloat`, propagate `sat` with +an `evaldUnfolding` if either + + 1. `e` is a value, or + 2. `sat=e` is case-bound, but won't float to top-level. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since call-by-value is much cheaper than call-by-need, we case-bind arguments @@ -2123,15 +2242,16 @@ zipManyFloats = foldr zipFloats emptyFloats mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind mkCaseFloat is_unlifted bndr scrut - = Float (NonRec bndr scrut) bound info + = -- pprTrace "mkCaseFloat" (ppr bndr <+> ppr (bound,info) + -- -- <+> ppr is_lifted <+> ppr is_strict + -- -- <+> ppr ok_for_spec <+> ppr evald + -- $$ ppr scrut) $ + Float (NonRec bndr scrut) bound info where (bound, info) -{- -Eventually we want the following code, when #20749 is fixed. - | is_lifted, is_hnf = (LetBound, TopLvlFloatable) - -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should - -- let-bind `StrictBox x'` after Note [Flatten case-binds]. --} +-- | is_lifted, is_hnf = (LetBound, TopLvlFloatable) +-- -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should +-- -- let-bind `StrictBox x'` after Note [Flatten case-binds]. | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2141,15 +2261,16 @@ Eventually we want the following code, when #20749 is fixed. _is_lifted = not is_unlifted _is_hnf = exprIsHNF scrut -mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> (FloatingBind, Id) mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) - -- <+> ppr is_lifted <+> ppr is_strict - -- <+> ppr ok_for_spec + -- <+> if is_strict then text "strict" else if is_lifted then text "lazy" else text "unlifted" + -- <+> if ok_for_spec then text "ok-for-spec" else empty + -- <+> if evald then text "evald" else empty -- $$ ppr rhs) $ - Float (NonRec bndr rhs) bound info + (Float (NonRec bndr' rhs) bound info, bndr') where - (bound, info) + !(bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs @@ -2180,6 +2301,11 @@ mkNonRecFloat env is_unlifted bndr rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) is_data_con = isJust . isDataConId_maybe + -- See Note [Pin evaluatedness on floats] + evald = is_hnf --- || (bound == CaseBound && info /= TopLvlFloatable) + bndr' | evald = bndr `setIdUnfolding` evaldUnfolding + | otherwise = bndr + -- | Wrap floats around an expression wrapBinds :: Floats -> CpeBody -> CpeBody wrapBinds floats body @@ -2285,6 +2411,10 @@ data FloatDecision = FloatNone | FloatAll +instance Outputable FloatDecision where + ppr FloatNone = text "none" + ppr FloatAll = text "all" + executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) executeFloatDecision dec floats rhs = case dec of @@ -2706,7 +2836,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs + (litAddrFloat, litAddrId') = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) @@ -2719,7 +2849,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do copyContentsCall = Var (primOpId CopyAddrToByteArrayOp) `App` Type realWorldTy - `App` Var litAddrId + `App` Var litAddrId' `App` Var mutableByteArrayId `App` mkIntLit platform 0 `App` contentsLength ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -64,8 +64,8 @@ With nofib being ~0.3% faster as well. See Note [Tag inference passes] for how we proceed to generate and use this information. -Note [Strict Field Invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [STG Strict Field Invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As part of tag inference we introduce the Strict Field Invariant. Which consists of us saying that: @@ -81,7 +81,7 @@ and will be tagged with `001` or `010` respectively. It will never point to a thunk, nor will it be tagged `000` (meaning "might be a thunk"). NB: Note that the proper tag for some objects is indeed `000`. Currently this is the case for PAPs. -This works analogous to how `WorkerLikeId`s work. See also Note [CBV Function Ids]. +This works analogous to how CBV functions work. See also Note [CBV Function Ids]. Why do we care? Because if we have code like: @@ -103,7 +103,7 @@ where we: * If not we convert `StrictJust x` into `case x of x' -> StrictJust x'` This is usually very beneficial but can cause regressions in rare edge cases where -we fail to proof that x is properly tagged, or where it simply isn't. +we fail to prove that x is properly tagged, or where it simply isn't. See Note [How untagged pointers can end up in strict fields] for how the second case can arise. @@ -124,15 +124,33 @@ Note that there are similar constraints around Note [CBV Function Ids]. Note [How untagged pointers can end up in strict fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Since the resolution of #20749 where Core passes assume that DataCon workers +evaluate their strict fields, it is pretty simple to see how the Simplifier +might exploit that knowledge to drop evals. Example: + + data T a = MkT !a + f :: [Int] -> T [Int] + f xs = xs `seq` MkT xs + +in Core we will have + + f = \xs -> MkT @[Int] xs + +No eval left there. + Consider data Set a = Tip | Bin !a (Set a) (Set a) We make a wrapper for Bin that evaluates its arguments $WBin x a b = case x of xv -> Bin xv a b Here `xv` will always be evaluated and properly tagged, just as the -Strict Field Invariant requires. +Note [STG Strict Field Invariant] requires. + +But alas, the Simplifier can destroy the invariant: see #15696. +Indeed, as Note [Strict fields in Core] explains, Core passes +assume that Data constructor workers evaluate their strict fields, +so the Simplifier will drop seqs freely. -But alas the Simplifier can destroy the invariant: see #15696. We start with thk = f () g x = ...(case thk of xv -> Bin xv Tip Tip)... @@ -153,7 +171,7 @@ Now you can see that the argument of Bin, namely thk, points to the thunk, not to the value as it did before. In short, although it may be rare, the output of optimisation passes -cannot guarantee to obey the Strict Field Invariant. For this reason +cannot guarantee to obey the Note [STG Strict Field Invariant]. For this reason we run tag inference. See Note [Tag inference passes]. Note [Tag inference passes] @@ -163,7 +181,7 @@ Tag inference proceeds in two passes: The result is then attached to /binders/. This is implemented by `inferTagsAnal` in GHC.Stg.InferTags * The second pass walks over the AST checking if the Strict Field Invariant is upheld. - See Note [Strict Field Invariant]. + See Note [STG Strict Field Invariant]. If required this pass modifies the program to uphold this invariant. Tag information is also moved from /binders/ to /occurrences/ during this pass. This is done by `GHC.Stg.InferTags.Rewrite (rewriteTopBinds)`. ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -57,7 +57,7 @@ The work of this pass is simple: * For any strict field we check if the argument is known to be properly tagged. * If it's not known to be properly tagged, we wrap the whole thing in a case, which will force the argument before allocation. -This is described in detail in Note [Strict Field Invariant]. +This is described in detail in Note [STG Strict Field Invariant]. The only slight complication is that we have to make sure not to invalidate free variable analysis in the process. @@ -210,7 +210,7 @@ When compiling bytecode we call myCoreToStg to get STG code first. myCoreToStg in turn calls out to stg2stg which runs the STG to STG passes followed by free variables analysis and the tag inference pass including its rewriting phase at the end. -Running tag inference is important as it upholds Note [Strict Field Invariant]. +Running tag inference is important as it upholds Note [STG Strict Field Invariant]. While code executed by GHCi doesn't take advantage of the SFI it can call into compiled code which does. So it must still make sure that the SFI is upheld. See also #21083 and #22042. ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -884,7 +884,7 @@ mostly relating to under what circumstances it evaluates its argument. Today, that story is simple: A dataToTag primop always evaluates its argument, unless tag inference determines the argument was already evaluated and correctly tagged. Getting here was a long journey, with -many similarities to the story behind Note [Strict Field Invariant] in +many similarities to the story behind Note [STG Strict Field Invariant] in GHC.Stg.InferTags. See also #15696. -} ===================================== compiler/GHC/Tc/TyCl/Build.hs ===================================== @@ -183,14 +183,15 @@ buildDataCon fam_envs dc_bang_opts src_name declared_infix prom_info src_bangs tag = lookupNameEnv_NF tag_map src_name -- See Note [Constructor tag allocation], fixes #14657 data_con = mkDataCon src_name declared_infix prom_info - src_bangs field_lbls + src_bangs impl_bangs str_marks field_lbls univ_tvs ex_tvs noConcreteTyVars user_tvbs eq_spec ctxt arg_tys res_ty NoPromInfo rep_tycon tag stupid_ctxt dc_wrk dc_rep dc_wrk = mkDataConWorkId work_name data_con - dc_rep = initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) + (dc_rep, impl_bangs, str_marks) = + initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) ; traceIf (text "buildDataCon 2" <+> ppr src_name) ; return data_con } ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1391,33 +1391,16 @@ arguments. That is the job of dmdTransformDataConSig. More precisely, * it returns the demands on the arguments; in the above example that is [SL, A] -Nasty wrinkle. Consider this code (#22475 has more realistic examples but -assume this is what the demand analyser sees) - - data T = MkT !Int Bool - get :: T -> Bool - get (MkT _ b) = b - - foo = let v::Int = I# 7 - t::T = MkT v True - in get t - -Now `v` is unused by `get`, /but/ we can't give `v` an Absent demand, -else we'll drop the binding and replace it with an error thunk. -Then the code generator (more specifically GHC.Stg.InferTags.Rewrite) -will add an extra eval of MkT's argument to give - foo = let v::Int = error "absent" - t::T = case v of v' -> MkT v' True - in get t - -Boo! Because of this extra eval (added in STG-land), the truth is that `MkT` -may (or may not) evaluate its arguments (as established in #21497). Hence the -use of `bump` in dmdTransformDataConSig, which adds in a `C_01` eval. The -`C_01` says "may or may not evaluate" which is absolutely faithful to what -InferTags.Rewrite does. - -In particular it is very important /not/ to make that a `C_11` eval, -see Note [Data-con worker strictness]. +When the data constructor worker has strict fields, an additional seq +will be inserted for each field (Note [Strict fields in Core]). +Hence we add an additional `seqDmd` for each strict field to emulate +field seq insertion. + +For example, consider `data SP a b = MkSP !a !b` and expression `MkSP x y`, +with the same sub-demand P(SL,A). +The strict fields bump up the strictness; we'd get [SL,1!A] for the field +demands. Note that the first demand was unaffected by the seq, whereas +the second, previously absent demand became `seqDmd` exactly. -} {- ********************************************************************* @@ -1617,6 +1600,29 @@ a bad fit because expression may not throw a precise exception (increasing precision of the analysis), but that's just a favourable guess. +Note [Side-effects and strictness] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Due to historic reasons and the continued effort not to cause performance +regressions downstream, Strictness Analysis is currently prone to discarding +observable side-effects (other than precise exceptions, see +Note [Precise exceptions and strictness analysis]) in some cases. For example, + f :: MVar () -> Int -> IO Int + f mv x = putMVar mv () >> (x `seq` return x) +The call to `putMVar` is an observable side-effect. Yet, Strictness Analysis +currently concludes that `f` is strict in `x` and uses call-by-value. +That means `f mv (error "boom")` will error out with the imprecise exception +rather performing the side-effect. + +This is a conscious violation of the semantics described in the paper +"a semantics for imprecise exceptions"; so it would be great if we could +identify the offending primops and extend the idea in +Note [Which scrutinees may throw precise exceptions] to general side-effects. + +Unfortunately, the existing has-side-effects classification for primops is +too conservative, listing `writeMutVar#` and even `readMutVar#` as +side-effecting. That is due to #3207. A possible way forward is described in +#17900, but no effort has been so far towards a resolution. + Note [Exceptions and strictness] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to smart about catching exceptions, but we aren't anymore. @@ -2333,7 +2339,8 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd - str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] + str_field_dmd = seqDmd -- See the bit about strict fields + -- in Note [Demand transformer for data constructors] -- | A special 'DmdTransformer' for dictionary selectors that feeds the demand -- on the result into the indicated dictionary component (if saturated). ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -260,7 +260,7 @@ The invariants around the arguments of call by value function like Ids are then: * Any `WorkerLikeId` * Some `JoinId` bindings. -This works analogous to the Strict Field Invariant. See also Note [Strict Field Invariant]. +This works analogous to the Strict Field Invariant. See also Note [STG Strict Field Invariant]. To make this work what we do is: * During W/W and SpecConstr any worker/specialized binding we introduce ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Core.Coercion import GHC.Core.Reduction import GHC.Core.Make import GHC.Core.FVs ( mkRuleInfo ) -import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase, coreAltsType ) +import GHC.Core.Utils ( exprType, mkCast, coreAltsType ) import GHC.Core.Unfold.Make import GHC.Core.SimpleOpt import GHC.Core.TyCon @@ -597,8 +597,12 @@ mkDataConWorkId wkr_name data_con = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty alg_wkr_info where - tycon = dataConTyCon data_con -- The representation TyCon - wkr_ty = dataConRepType data_con + tycon = dataConTyCon data_con -- The representation TyCon + wkr_ty = dataConRepType data_con + univ_tvs = dataConUnivTyVars data_con + ex_tcvs = dataConExTyCoVars data_con + arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys + str_marks = dataConRepStrictness data_con ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo @@ -606,12 +610,19 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setDmdSigInfo` wkr_sig + -- Workers eval their strict fields + -- See Note [Strict fields in Core] `setLFInfo` wkr_lf_info - -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + wkr_sig = mkClosedDmdSig wkr_dmds topDiv + wkr_dmds = map mk_dmd str_marks + mk_dmd MarkedStrict = evalDmd + mk_dmd NotMarkedStrict = topDmd + -- See Note [LFInfo of DataCon workers and wrappers] wkr_lf_info | wkr_arity == 0 = LFCon data_con @@ -619,9 +630,6 @@ mkDataConWorkId wkr_name data_con -- LFInfo stores post-unarisation arity ----------- Workers for newtypes -------------- - univ_tvs = dataConUnivTyVars data_con - ex_tcvs = dataConExTyCoVars data_con - arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma @@ -789,10 +797,10 @@ mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon - -> UniqSM DataConRep + -> UniqSM (DataConRep, [HsImplBang], [StrictnessMark]) mkDataConRep dc_bang_opts fam_envs wrap_name data_con | not wrapper_reqd - = return NoDataConRep + = return (NoDataConRep, arg_ibangs, rep_strs) | otherwise = do { wrap_args <- mapM (newLocal (fsLit "conrep")) wrap_arg_tys @@ -856,11 +864,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con ; return (DCR { dcr_wrap_id = wrap_id , dcr_boxer = mk_boxer boxers - , dcr_arg_tys = rep_tys - , dcr_stricts = rep_strs - -- For newtypes, dcr_bangs is always [HsLazy]. - -- See Note [HsImplBangs for newtypes]. - , dcr_bangs = arg_ibangs }) } + , dcr_arg_tys = rep_tys } + , arg_ibangs, rep_strs) } where (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys, _orig_res_ty) @@ -918,8 +923,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. -- See dataConUserTyVarsNeedWrapper below. - && (any isBanged (ev_ibangs ++ arg_ibangs))) - -- Some forcing/unboxing (includes eq_spec) + && (any isUnpacked (ev_ibangs ++ arg_ibangs))) + -- Some unboxing (includes eq_spec) || isFamInstTyCon tycon -- Cast result @@ -1185,7 +1190,7 @@ dataConArgRep arg_ty HsLazy = ([(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) dataConArgRep arg_ty (HsStrict _) - = ([(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) + = ([(arg_ty, MarkedStrict)], (unitUnboxer, unitBoxer)) -- Seqs are inserted in STG dataConArgRep arg_ty (HsUnpack Nothing) = dataConArgUnpack arg_ty @@ -1215,9 +1220,6 @@ wrapCo co rep_ty (unbox_rep, box_rep) -- co :: arg_ty ~ rep_ty ; return (rep_ids, rep_expr `Cast` mkSymCo sco) } ------------------------ -seqUnboxer :: Unboxer -seqUnboxer v = return ([v], mkDefaultCase (Var v) v) - unitUnboxer :: Unboxer unitUnboxer v = return ([v], \e -> e) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Utils.Misc ( dropWhileEndLE, spanEnd, last2, lastMaybe, onJust, - List.foldl1', foldl2, count, countWhile, all2, + List.foldl1', foldl2, count, countWhile, all2, all2Prefix, all3Prefix, lengthExceeds, lengthIs, lengthIsNot, lengthAtLeast, lengthAtMost, lengthLessThan, @@ -652,6 +652,30 @@ all2 _ [] [] = True all2 p (x:xs) (y:ys) = p x y && all2 p xs ys all2 _ _ _ = False +all2Prefix :: (a -> b -> Bool) -> [a] -> [b] -> Bool +-- ^ `all2Prefix p xs ys` is a fused version of `and $ zipWith2 p xs ys`. +-- So if one list is shorter than the other, `p` is assumed to be `True` for the +-- suffix. +all2Prefix p = foldr k z + where + k x go ys' = case ys' of + (y:ys'') -> p x y && go ys'' + _ -> True + z _ = True +{-# INLINE all2Prefix #-} + +all3Prefix :: (a -> b -> c -> Bool) -> [a] -> [b] -> [c] -> Bool +-- ^ `all3Prefix p xs ys zs` is a fused version of `and $ zipWith3 p xs ys zs`. +-- So if one list is shorter than the others, `p` is assumed to be `True` for +-- the suffix. +all3Prefix p = foldr k z + where + k x go ys' zs' = case (ys',zs') of + (y:ys'',z:zs'') -> p x y z && go ys'' zs'' + _ -> False + z _ _ = True +{-# INLINE all3Prefix #-} + -- Count the number of times a predicate is true count :: (a -> Bool) -> [a] -> Int ===================================== testsuite/tests/dmdanal/sigs/T16859.stderr ===================================== @@ -4,7 +4,7 @@ T16859.bar: <1!A> T16859.baz: <1L><1!P(L)><1C(1,L)> T16859.buz: <1!P(L,L)> T16859.foo: <1L> -T16859.mkInternalName: <1!P(L)><1L><1L> +T16859.mkInternalName: <1!P(L)> T16859.n_loc: <1!P(A,A,A,1L)> T16859.n_occ: <1!P(A,1!P(L,L),A,A)> T16859.n_sort: <1!P(1L,A,A,A)> ===================================== testsuite/tests/ghci/should_run/T21052.stdout ===================================== @@ -5,7 +5,7 @@ BCO_toplevel :: GHC.Types.IO [GHC.Types.Any] {} \u [] let { sat :: [GHC.Types.Any] - [LclId] = + [LclId, Unf=OtherCon []] = :! [GHC.Tuple.() GHC.Types.[]]; } in GHC.Internal.Base.returnIO sat; ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -14,8 +14,8 @@ T23083.g = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> let { sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer - [LclId] - sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + [LclId, Unf=OtherCon []] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1, Dmd=SL] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in f sat -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/simplCore/should_run/T20749.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE UnliftedDatatypes #-} +import Data.Kind +import GHC.Exts + +type StrictPair :: Type -> Type -> UnliftedType +data StrictPair a b = SP !a !b + +f :: StrictPair Int Int -> StrictPair Int Int -> Int -> Bool +{-# OPAQUE f #-} +f (SP x _) (SP _ y) z = x < y + z + +g :: Int -> [Int] -> Int +{-# OPAQUE g #-} +g x ys = h ys + where + h [] = 0 + h (y:ys) = case SP x 27 of + u -> if f u u y then x else x + h ys + +main :: IO () +main = print (g undefined []) ===================================== testsuite/tests/simplCore/should_run/T20749.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/T24662.hs ===================================== @@ -0,0 +1,27 @@ +{-# LANGUAGE MagicHash #-} + +module T24662 where + +import GHC.Exts + +f1 :: a -> Int# -> Int -> Int +{-# OPAQUE f1 #-} +f1 _ x (I# y) = I# (x +# y) + +f2 :: Int# -> a -> Int -> Int +{-# OPAQUE f2 #-} +f2 x _ (I# y) = I# (x +# y) + +loopy :: Int -> Int# +loopy x | x>0 = loopy x + | otherwise = 0# + +-- Should either let or case-bind t (preferrably the latter), but we should do +-- it consistently in foo1 and foo2. +foo1 x = let t :: Int -> Int + t = f1 True (loopy x) in + t `seq` (x, t) + +foo2 x = let t :: Int -> Int + t = f2 True (loopy x) in + t `seq` (x, t) ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -107,6 +107,7 @@ test('UnliftedArgRule', normal, compile_and_run, ['']) test('T21229', normal, compile_and_run, ['-O']) test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) +test('T20749', normal, compile_and_run, ['']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) @@ -114,3 +115,4 @@ test('T23184', normal, compile_and_run, ['-O']) test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) test('T23289', normal, compile_and_run, ['']) test('T23056', [only_ways(['ghci-opt'])], ghci_script, ['T23056.script']) +test('T24662', normal, compile_and_run, ['']) ===================================== testsuite/tests/simplStg/should_compile/T19717.stderr ===================================== @@ -3,15 +3,15 @@ Foo.f :: forall {a}. a -> [GHC.Internal.Maybe.Maybe a] [GblId, Arity=1, Str=<1L>, Unf=OtherCon []] = {} \r [x] - case x of x1 { + case x of x1 [Dmd=SL] { __DEFAULT -> let { sat [Occ=Once1] :: GHC.Internal.Maybe.Maybe a - [LclId] = + [LclId, Unf=OtherCon []] = GHC.Internal.Maybe.Just! [x1]; } in let { sat [Occ=Once1] :: [GHC.Internal.Maybe.Maybe a] - [LclId] = + [LclId, Unf=OtherCon []] = :! [sat GHC.Types.[]]; } in : [sat sat]; }; ===================================== testsuite/tests/simplStg/should_compile/inferTags002.stderr ===================================== @@ -1,88 +1,30 @@ -==================== Output Cmm ==================== -[M.$WMkT_entry() { // [R3, R2] - { info_tbls: [(cym, - label: block_cym_info - rep: StackRep [False] - srt: Nothing), - (cyp, - label: M.$WMkT_info - rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } - srt: Nothing), - (cys, - label: block_cys_info - rep: StackRep [False] - srt: Nothing)] - stack_info: arg_space: 8 - } - {offset - cyp: // global - if ((Sp + -16) < SpLim) (likely: False) goto cyv; else goto cyw; - cyv: // global - R1 = M.$WMkT_closure; - call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - cyw: // global - I64[Sp - 16] = cym; - R1 = R2; - P64[Sp - 8] = R3; - Sp = Sp - 16; - if (R1 & 7 != 0) goto cym; else goto cyn; - cyn: // global - call (I64[R1])(R1) returns to cym, args: 8, res: 8, upd: 8; - cym: // global - I64[Sp] = cys; - _sy8::P64 = R1; - R1 = P64[Sp + 8]; - P64[Sp + 8] = _sy8::P64; - call stg_ap_0_fast(R1) returns to cys, args: 8, res: 8, upd: 8; - cys: // global - Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto cyA; else goto cyz; - cyA: // global - HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cys, args: 8, res: 8, upd: 8; - cyz: // global - I64[Hp - 16] = M.MkT_con_info; - P64[Hp - 8] = P64[Sp + 8]; - P64[Hp] = R1; - R1 = Hp - 15; - Sp = Sp + 16; - call (P64[Sp])(R1) args: 8, res: 0, upd: 8; - } - }, - section ""data" . M.$WMkT_closure" { - M.$WMkT_closure: - const M.$WMkT_info; - }] - - - ==================== Output Cmm ==================== [M.f_entry() { // [R2] - { info_tbls: [(cyK, - label: block_cyK_info + { info_tbls: [(cAs, + label: block_info rep: StackRep [] srt: Nothing), - (cyN, + (cAv, label: M.f_info rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} } srt: Nothing)] stack_info: arg_space: 8 } {offset - cyN: // global - if ((Sp + -8) < SpLim) (likely: False) goto cyO; else goto cyP; - cyO: // global + _lbl_: // global + if ((Sp + -8) < SpLim) (likely: False) goto cAw; else goto cAx; + _lbl_: // global R1 = M.f_closure; call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8; - cyP: // global - I64[Sp - 8] = cyK; + _lbl_: // global + I64[Sp - 8] = cAs; R1 = R2; Sp = Sp - 8; - if (R1 & 7 != 0) goto cyK; else goto cyL; - cyL: // global - call (I64[R1])(R1) returns to cyK, args: 8, res: 8, upd: 8; - cyK: // global + if (R1 & 7 != 0) goto cAs; else goto cAt; + _lbl_: // global + call (I64[R1])(R1) returns to cAs, args: 8, res: 8, upd: 8; + _lbl_: // global R1 = P64[R1 + 15]; Sp = Sp + 8; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; @@ -97,47 +39,47 @@ ==================== Output Cmm ==================== [M.MkT_entry() { // [R3, R2] - { info_tbls: [(cz1, - label: block_cz1_info + { info_tbls: [(cAJ, + label: block_info rep: StackRep [False] srt: Nothing), - (cz4, + (cAM, label: M.MkT_info rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } srt: Nothing), - (cz7, - label: block_cz7_info + (cAP, + label: block_info rep: StackRep [False] srt: Nothing)] stack_info: arg_space: 8 } {offset - cz4: // global - if ((Sp + -16) < SpLim) (likely: False) goto cza; else goto czb; - cza: // global + _lbl_: // global + if ((Sp + -16) < SpLim) (likely: False) goto cAS; else goto cAT; + _lbl_: // global R1 = M.MkT_closure; call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - czb: // global - I64[Sp - 16] = cz1; + _lbl_: // global + I64[Sp - 16] = cAJ; R1 = R2; P64[Sp - 8] = R3; Sp = Sp - 16; - if (R1 & 7 != 0) goto cz1; else goto cz2; - cz2: // global - call (I64[R1])(R1) returns to cz1, args: 8, res: 8, upd: 8; - cz1: // global - I64[Sp] = cz7; - _tyf::P64 = R1; + if (R1 & 7 != 0) goto cAJ; else goto cAK; + _lbl_: // global + call (I64[R1])(R1) returns to cAJ, args: 8, res: 8, upd: 8; + _lbl_: // global + I64[Sp] = cAP; + __locVar_::P64 = R1; R1 = P64[Sp + 8]; - P64[Sp + 8] = _tyf::P64; - call stg_ap_0_fast(R1) returns to cz7, args: 8, res: 8, upd: 8; - cz7: // global + P64[Sp + 8] = __locVar_::P64; + call stg_ap_0_fast(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto czf; else goto cze; - czf: // global + if (Hp > HpLim) (likely: False) goto cAX; else goto cAW; + _lbl_: // global HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cz7, args: 8, res: 8, upd: 8; - cze: // global + call stg_gc_unpt_r1(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global I64[Hp - 16] = M.MkT_con_info; P64[Hp - 8] = P64[Sp + 8]; P64[Hp] = R1; @@ -155,14 +97,14 @@ ==================== Output Cmm ==================== [M.MkT_con_entry() { // [] - { info_tbls: [(czl, + { info_tbls: [(cB3, label: M.MkT_con_info rep: HeapRep 2 ptrs { Con {tag: 0 descr:"main:M.MkT"} } srt: Nothing)] stack_info: arg_space: 8 } {offset - czl: // global + _lbl_: // global R1 = R1 + 1; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a3cc62dda8025ac99284a6dfbe4446d7a05c193...d2eee16b6f7e16d42db5c37a3483f9e0135fc7c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a3cc62dda8025ac99284a6dfbe4446d7a05c193...d2eee16b6f7e16d42db5c37a3483f9e0135fc7c0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 13:20:03 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 26 Apr 2024 09:20:03 -0400 Subject: [Git][ghc/ghc][wip/T20749] 2 commits: CorePrep: Attach evaldUnfolding to floats to detect more values Message-ID: <662baa02f37c9_14ae3e1d6ed94114115@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: e4a7f0b8 by Sebastian Graf at 2024-04-26T15:19:24+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - a4713774 by Sebastian Graf at 2024-04-26T15:19:24+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 29 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Misc.hs - testsuite/tests/dmdanal/sigs/T16859.stderr - testsuite/tests/ghci/should_run/T21052.stdout - testsuite/tests/simplCore/should_compile/T23083.stderr - + testsuite/tests/simplCore/should_run/T20749.hs - + testsuite/tests/simplCore/should_run/T20749.stdout - + testsuite/tests/simplCore/should_run/T24662.hs - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/simplStg/should_compile/T19717.stderr - testsuite/tests/simplStg/should_compile/inferTags002.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -640,6 +640,8 @@ pcDataConWithFixity' declared_infix dc_name wrk_key rri -- See Note [Constructor tag allocation] and #14657 data_con = mkDataCon dc_name declared_infix prom_info (map (const no_bang) arg_tys) + (map (const HsLazy) arg_tys) + (map (const NotMarkedStrict) arg_tys) [] -- No labelled fields tyvars ex_tyvars conc_tyvars ===================================== compiler/GHC/Core.hs ===================================== @@ -42,7 +42,7 @@ module GHC.Core ( foldBindersOfBindStrict, foldBindersOfBindsStrict, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, - collectArgs, stripNArgs, collectArgsTicks, flattenBinds, + collectArgs, collectValArgs, stripNArgs, collectArgsTicks, flattenBinds, collectFunSimple, exprToType, @@ -1029,6 +1029,64 @@ tail position: A cast changes the type, but the type must be the same. But operationally, casts are vacuous, so this is a bit unfortunate! See #14610 for ideas how to fix this. +Note [Strict fields in Core] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Evaluating a data constructor worker evaluates its strict fields. + +In other words, if `MkT` is strict in its first field and `xs` reduces to +`error "boom"`, then `MkT xs b` will throw that error. +Consequently, it is sound to seq the field before the call to the constructor, +e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`. +Let's call this transformation "field seq insertion". + +Note in particular that the data constructor application `MkT xs b` above is +*not* a value, unless `xs` is! + +This has pervasive effect on the Core pipeline: + + * `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the + strict arguments of a DataCon worker are values/ok-for-spec themselves. + + * `exprIsConApp_maybe` inserts field seqs in the `FloatBind`s it returns, so + that the Simplifier, Constant-folding, the pattern-match checker, etc. + all see the inserted field seqs when they match on strict workers. Often this + is just to emphasise strict semantics, but for case-of-known constructor + and case-to-let, field insertion is *vital*, otherwise these transformations + would lose field seqs that the user expects to happen, perhaps in order to + fix a space leak. For example, + case MkT xs b of MkT xs' b' -> b' + optimising this expression with case-of-known-con must leave behind the + field seq on `xs`, thus + case xs of xs' { __DEFAULT -> b } + + * The demand signature of a data constructor is strict in strict field + position when otherwise it is lazy. Likewise the demand *transformer* + of a DataCon worker can stricten up demands on strict field args. + See Note [Demand transformer for data constructors]. + + * In the absence of `-fpedantic-bottoms`, it is still possible that some seqs + are ultimately dropped or delayed due to eta-expansion. + See Note [Dealing with bottom]. + +Strict field semantics is exploited in STG by Note [Tag Inference]: +It performs field seq insertion to statically guarantee *taggedness* of strict +fields, establishing the Note [STG Strict Field Invariant]. (Happily, most +of those seqs are immediately detected as redundant by tag inference and are +omitted.) From then on, DataCon worker semantics are actually lazy, hence it is +important that STG passes maintain the Strict Field Invariant. + +Historical Note: +The delightfully simple description of strict field semantics is the result of +a long saga (#20749, the bits about strict data constructors in #21497, #22475), +where we tried a more lenient (but actually not) semantics first that would +allow both strict and lazy implementations of DataCon workers. This was favoured +because the "pervasive effect" throughout the compiler was deemed too large +(when it really turned out to be quite modest). +Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the +same way as above, otherwise the analysis would not be conservative wrt. the +lenient semantics (which includes the strict one). It is also much harder to +explain and maintain, as it turned out. + ************************************************************************ * * In/Out type synonyms @@ -2158,6 +2216,17 @@ collectArgs expr go (App f a) as = go f (a:as) go e as = (e, as) +-- | Takes a nested application expression and returns the function +-- being applied and the arguments to which it is applied +collectValArgs :: Expr b -> (Expr b, [Arg b]) +collectValArgs expr + = go expr [] + where + go (App f a) as + | isValArg a = go f (a:as) + | otherwise = go f as + go e as = (e, as) + -- | Takes a nested application expression and returns the function -- being applied. Looking through casts and ticks to find it. collectFunSimple :: Expr b -> Expr b ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -49,18 +49,20 @@ module GHC.Core.DataCon ( dataConIsInfix, dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitTyThings, - dataConRepStrictness, dataConImplBangs, dataConBoxer, + dataConRepStrictness, + dataConImplBangs, dataConBoxer, splitDataProductType_maybe, -- ** Predicates on DataCons isNullarySrcDataCon, isNullaryRepDataCon, + isLazyDataConRep, isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon, isUnboxedSumDataCon, isCovertGadtDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, dataConUserTyVarsNeedWrapper, checkDataConTyVars, - isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, + isBanged, isUnpacked, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, -- ** Promotion related functions @@ -524,6 +526,18 @@ data DataCon -- Matches 1-1 with dcOrigArgTys -- Hence length = dataConSourceArity dataCon + dcImplBangs :: [HsImplBang], + -- The actual decisions made (including failures) + -- about the original arguments; 1-1 with orig_arg_tys + -- See Note [Bangs on data constructor arguments] + + dcStricts :: [StrictnessMark], + -- One mark for every field of the DataCon worker; + -- if it's empty, then all fields are lazy, + -- otherwise 1-1 with dataConRepArgTys. + -- See also Note [Strict fields in Core] in GHC.Core + -- for the effect on the strictness signature + dcFields :: [FieldLabel], -- Field labels for this constructor, in the -- same order as the dcOrigArgTys; @@ -826,13 +840,6 @@ data DataConRep -- after unboxing and flattening, -- and *including* all evidence args - , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] - - , dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures) - -- about the original arguments; 1-1 with orig_arg_tys - -- See Note [Bangs on data constructor arguments] - } type DataConEnv a = UniqFM DataCon a -- Keyed by DataCon @@ -901,43 +908,8 @@ eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Data-con worker strictness] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Notice that we do *not* say the worker Id is strict even if the data -constructor is declared strict - e.g. data T = MkT ![Int] Bool -Even though most often the evals are done by the *wrapper* $WMkT, there are -situations in which tag inference will re-insert evals around the worker. -So for all intents and purposes the *worker* MkT is strict, too! - -Unfortunately, if we exposed accurate strictness of DataCon workers, we'd -see the following transformation: - - f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs - ==> { drop-seq, binder swap on xs' } - f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs - ==> { case-to-let } - f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs! - -I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs` -and then doing case-to-let. The issue is that `exprIsHNF` currently says that -every DataCon worker app is a value. The implicit assumption is that surrounding -evals will have evaluated strict fields like `xs` before! But now that we had -just dropped the eval on `xs`, that assumption is no longer valid. - -Long story short: By keeping the demand signature lazy, the Simplifier will not -drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others -remains sound. - -Similarly, during demand analysis in dmdTransformDataConSig, we bump up the -field demand with `C_01`, *not* `C_11`, because the latter exposes too much -strictness that will drop the eval on `xs` above. - -This issue is discussed at length in -"Failed idea: no wrappers for strict data constructors" in #21497 and #22475. - -Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool @@ -963,8 +935,8 @@ Terminology: the flag settings in the importing module. Also see Note [Bangs on imported data constructors] in GHC.Types.Id.Make -* The dcr_bangs field of the dcRep field records the [HsImplBang] - If T was defined in this module, Without -O the dcr_bangs might be +* The dcImplBangs field records the [HsImplBang] + If T was defined in this module, Without -O the dcImplBangs might be [HsStrict _, HsStrict _, HsLazy] With -O it might be [HsStrict _, HsUnpack _, HsLazy] @@ -973,6 +945,19 @@ Terminology: With -XStrictData it might be [HsStrict _, HsUnpack _, HsStrict _] +* Core passes will often need to know whether the DataCon worker or wrapper in + an application is strict in some (lifted) field or not. This is tracked in the + demand signature attached to a DataCon's worker resp. wrapper Id. + + So if you've got a DataCon dc, you can get the demand signature by + `idDmdSig (dataConWorkId dc)` and make out strict args by testing with + `isStrictDmd`. Similarly, `idDmdSig <$> dataConWrapId_maybe dc` gives + you the demand signature of the wrapper, if it exists. + + These demand signatures are set in GHC.Types.Id.Make.mkDataConWorkId, + compute from the single source of truth `dataConRepStrictness`, which is + generated from `dcStricts`. + Note [Detecting useless UNPACK pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to issue a warning when there's an UNPACK pragma in the source code, @@ -1008,7 +993,6 @@ we consult HsImplBang: The boolean flag is used only for this warning. See #11270 for motivation. - ************************************************************************ * * \subsection{Instances} @@ -1110,6 +1094,11 @@ isBanged (HsUnpack {}) = True isBanged (HsStrict {}) = True isBanged HsLazy = False +isUnpacked :: HsImplBang -> Bool +isUnpacked (HsUnpack {}) = True +isUnpacked (HsStrict {}) = False +isUnpacked HsLazy = False + isSrcStrict :: SrcStrictness -> Bool isSrcStrict SrcStrict = True isSrcStrict _ = False @@ -1135,13 +1124,15 @@ cbvFromStrictMark MarkedStrict = MarkedCbv -- | Build a new data constructor mkDataCon :: Name - -> Bool -- ^ Is the constructor declared infix? - -> TyConRepName -- ^ TyConRepName for the promoted TyCon - -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user - -> [FieldLabel] -- ^ Field labels for the constructor, - -- if it is a record, otherwise empty - -> [TyVar] -- ^ Universals. - -> [TyCoVar] -- ^ Existentials. + -> Bool -- ^ Is the constructor declared infix? + -> TyConRepName -- ^ TyConRepName for the promoted TyCon + -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user + -> [HsImplBang] -- ^ Strictness/unpack annotations, as inferred by the compiler + -> [StrictnessMark] -- ^ Strictness marks for the DataCon worker's fields in Core + -> [FieldLabel] -- ^ Field labels for the constructor, + -- if it is a record, otherwise empty + -> [TyVar] -- ^ Universals. + -> [TyCoVar] -- ^ Existentials. -> ConcreteTyVars -- ^ TyVars which must be instantiated with -- concrete types @@ -1163,7 +1154,9 @@ mkDataCon :: Name -- Can get the tag from the TyCon mkDataCon name declared_infix prom_info - arg_stricts -- Must match orig_arg_tys 1-1 + arg_stricts -- Must match orig_arg_tys 1-1 + impl_bangs -- Must match orig_arg_tys 1-1 + str_marks -- Must be empty or match dataConRepArgTys 1-1 fields univ_tvs ex_tvs conc_tvs user_tvbs eq_spec theta @@ -1180,6 +1173,8 @@ mkDataCon name declared_infix prom_info = con where is_vanilla = null ex_tvs && null eq_spec && null theta + str_marks' | not $ any isMarkedStrict str_marks = [] + | otherwise = str_marks con = MkData {dcName = name, dcUnique = nameUnique name, dcVanilla = is_vanilla, dcInfix = declared_infix, @@ -1192,7 +1187,8 @@ mkDataCon name declared_infix prom_info dcStupidTheta = stupid_theta, dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, dcRepTyCon = rep_tycon, - dcSrcBangs = arg_stricts, + dcSrcBangs = arg_stricts, dcImplBangs = impl_bangs, + dcStricts = str_marks', dcFields = fields, dcTag = tag, dcRepType = rep_ty, dcWorkId = work_id, dcRep = rep, @@ -1435,20 +1431,25 @@ isNullarySrcDataCon dc = dataConSourceArity dc == 0 isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 +isLazyDataConRep :: DataCon -> Bool +-- ^ True <==> All fields are lazy +isLazyDataConRep dc = null (dcStricts dc) + dataConRepStrictness :: DataCon -> [StrictnessMark] --- ^ Give the demands on the arguments of a --- Core constructor application (Con dc args) -dataConRepStrictness dc = case dcRep dc of - NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc] - DCR { dcr_stricts = strs } -> strs +-- ^ Give the demands on the runtime arguments of a Core DataCon worker +-- application. +-- The length of the list matches `dataConRepArgTys` (e.g., the number +-- of runtime arguments). +dataConRepStrictness dc + | isLazyDataConRep dc + = replicate (dataConRepArity dc) NotMarkedStrict + | otherwise + = dcStricts dc dataConImplBangs :: DataCon -> [HsImplBang] -- The implementation decisions about the strictness/unpack of each -- source program argument to the data constructor -dataConImplBangs dc - = case dcRep dc of - NoDataConRep -> replicate (dcSourceArity dc) HsLazy - DCR { dcr_bangs = bangs } -> bangs +dataConImplBangs dc = dcImplBangs dc dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -1533,7 +1533,7 @@ myExprIsCheap (AE { am_opts = opts, am_sigs = sigs }) e mb_ty -- See Note [Eta expanding through dictionaries] -- See Note [Eta expanding through CallStacks] - cheap_fun e = exprIsCheapX (myIsCheapApp sigs) e + cheap_fun e = exprIsCheapX (myIsCheapApp sigs) False e -- | A version of 'isCheapApp' that considers results from arity analysis. -- See Note [Arity analysis] for what's in the signature environment and why ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -209,7 +209,7 @@ cprAnal, cprAnal' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' cprAnal env e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ - cprAnal' env e + cprAnal' env e cprAnal' _ (Lit lit) = (topCprType, Lit lit) cprAnal' _ (Type ty) = (topCprType, Type ty) -- Doesn't happen, in fact @@ -296,9 +296,16 @@ data TermFlag -- Better than using a Bool -- See Note [Nested CPR] exprTerminates :: CoreExpr -> TermFlag +-- ^ A /very/ simple termination analysis. exprTerminates e - | exprIsHNF e = Terminates -- A /very/ simple termination analysis. - | otherwise = MightDiverge + | exprIsHNF e = Terminates + | exprOkForSpeculation e = Terminates + | otherwise = MightDiverge + -- Annoyingly, we have to check both for HNF and ok-for-spec. + -- * `I# (x# *# 2#)` is ok-for-spec, but not in HNF. Still worth CPR'ing! + -- * `lvl` is an HNF if its unfolding is evaluated + -- (perhaps `lvl = I# 0#` at top-level). But, tiresomely, it is never + -- ok-for-spec due to Note [exprOkForSpeculation and evaluated variables]. cprAnalApp :: AnalEnv -> CoreExpr -> [(CprType, CoreArg)] -> (CprType, CoreExpr) -- Main function that takes care of /nested/ CPR. See Note [Nested CPR] @@ -367,8 +374,8 @@ cprTransformDataConWork env con args , wkr_arity <= mAX_CPR_SIZE -- See Note [Trimming to mAX_CPR_SIZE] , args `lengthIs` wkr_arity , ae_rec_dc env con /= DefinitelyRecursive -- See Note [CPR for recursive data constructors] - -- , pprTrace "cprTransformDataConWork" (ppr con <+> ppr wkr_arity <+> ppr args) True - = CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) + = -- pprTraceWith "cprTransformDataConWork" (\r -> ppr con <+> ppr wkr_arity <+> ppr args <+> ppr r) $ + CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) | otherwise = topCprType where @@ -505,7 +512,8 @@ cprAnalBind env id rhs | isDataStructure id -- Data structure => no code => no need to analyse rhs = (id, rhs, env) | otherwise - = (id `setIdCprSig` sig', rhs', env') + = -- pprTrace "cprAnalBind" (ppr id <+> ppr sig <+> ppr sig') + (id `setIdCprSig` sig', rhs', env') where (rhs_ty, rhs') = cprAnal env rhs -- possibly trim thunk CPR info ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -835,6 +835,10 @@ to the Divergence lattice, but in practice it turned out to be hard to untaint from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. +You might think that we should check for side-effects rather than just for +precise exceptions. Right you are! See Note [Side-effects and strictness] +for why we unfortunately do not. + Note [Demand analysis for recursive data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T11545 features a single-product, recursive data type ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -8,14 +8,13 @@ module GHC.Core.Opt.Simplify.Env ( -- * The simplifier mode - SimplMode(..), updMode, - smPedanticBottoms, smPlatform, + SimplMode(..), updMode, smPlatform, -- * Environments SimplEnv(..), pprSimplEnv, -- Temp not abstract seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle, seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames, - seOptCoercionOpts, sePedanticBottoms, sePhase, sePlatform, sePreInline, + seOptCoercionOpts, sePhase, sePlatform, sePreInline, seRuleOpts, seRules, seUnfoldingOpts, mkSimplEnv, extendIdSubst, extendCvIdSubst, extendTvSubst, extendCvSubst, @@ -235,9 +234,6 @@ seNames env = sm_names (seMode env) seOptCoercionOpts :: SimplEnv -> OptCoercionOpts seOptCoercionOpts env = sm_co_opt_opts (seMode env) -sePedanticBottoms :: SimplEnv -> Bool -sePedanticBottoms env = smPedanticBottoms (seMode env) - sePhase :: SimplEnv -> CompilerPhase sePhase env = sm_phase (seMode env) @@ -292,9 +288,6 @@ instance Outputable SimplMode where where pp_flag f s = ppUnless f (text "no") <+> s -smPedanticBottoms :: SimplMode -> Bool -smPedanticBottoms opts = ao_ped_bot (sm_arity_opts opts) - smPlatform :: SimplMode -> Platform smPlatform opts = roPlatform (sm_rule_opts opts) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2204,14 +2204,14 @@ zap the SubstEnv. This is VITAL. Consider We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!! -Note [Fast path for data constructors] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Fast path for lazy data constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For applications of a data constructor worker, the full glory of rebuildCall is a waste of effort; * They never inline, obviously * They have no rewrite rules -* They are not strict (see Note [Data-con worker strictness] - in GHC.Core.DataCon) +* Though they might be strict (see Note [Strict fields in Core] in GHC.Core), + we will exploit that strictness through their demand signature So it's fine to zoom straight to `rebuild` which just rebuilds the call in a very straightforward way. @@ -2235,7 +2235,7 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont - | isDataConWorkId var -- See Note [Fast path for data constructors] + | isDataConWorkId var -- See Note [Fast path for lazy data constructors] = rebuild env (Var var) cont | otherwise = case substId env var of @@ -3420,7 +3420,7 @@ a case pattern. This is *important*. Consider We really must record that b is already evaluated so that we don't go and re-evaluate it when constructing the result. -See Note [Data-con worker strictness] in GHC.Core.DataCon +See Note [Strict fields in Core] in GHC.Core. NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1277,11 +1277,8 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplifier produces rhs[exp/a], changing semantics if exp is not ok-for-spec -- Good: returning (Mk#, [x]) with a float of case exp of x { DEFAULT -> [] } -- simplifier produces case exp of a { DEFAULT -> exp[x/a] } - = let arg' = subst_expr subst arg - bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) - float = FloatCase arg' bndr DEFAULT [] - subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) mco) + , (subst', float, bndr) <- case_bind subst arg arg_type + = go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise = go subst floats fun (CC (subst_expr subst arg : args) mco) @@ -1324,8 +1321,10 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun - = succeedWith in_scope floats $ - pushCoDataCon con args mco + , (in_scope', seq_floats, args') <- mkFieldSeqFloats in_scope con args + -- mkFieldSeqFloats: See Note [Strict fields in Core] + = succeedWith in_scope' (seq_floats ++ floats) $ + pushCoDataCon con args' mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1411,6 +1410,38 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr extend (Left in_scope) v e = Right (extendSubst (mkEmptySubst in_scope) v e) extend (Right s) v e = Right (extendSubst s v e) + case_bind :: Either InScopeSet Subst -> CoreExpr -> Type -> (Either InScopeSet Subst, FloatBind, Id) + case_bind subst expr expr_ty = (subst', float, bndr) + where + bndr = setCaseBndrEvald MarkedStrict $ + uniqAway (subst_in_scope subst) $ + mkWildValBinder ManyTy expr_ty + subst' = subst_extend_in_scope subst bndr + expr' = subst_expr subst expr + float = FloatCase expr' bndr DEFAULT [] + + mkFieldSeqFloats :: InScopeSet -> DataCon -> [CoreExpr] -> (InScopeSet, [FloatBind], [CoreExpr]) + -- See Note [Strict fields in Core] for what a field seq is and why we + -- insert them + mkFieldSeqFloats in_scope dc args + | isLazyDataConRep dc + = (in_scope, [], args) + | otherwise + = (in_scope', floats', ty_args ++ val_args') + where + (ty_args, val_args) = splitAtList (dataConUnivAndExTyCoVars dc) args + (in_scope', floats', val_args') = foldr do_one (in_scope, [], []) $ zipEqual "mkFieldSeqFloats" str_marks val_args + str_marks = dataConRepStrictness dc + do_one (str, arg) (in_scope,floats,args) + | NotMarkedStrict <- str = no_seq + | exprIsHNF arg = no_seq + | otherwise = (in_scope', float:floats, Var bndr:args) + where + no_seq = (in_scope, floats, arg:args) + (in_scope', float, bndr) = + case case_bind (Left in_scope) arg (exprType arg) of + (Left in_scope', float, bndr) -> (in_scope', float, bndr) + (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right) -- See Note [exprIsConApp_maybe on literal strings] dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -55,7 +55,7 @@ module GHC.Core.Type ( splitForAllForAllTyBinders, splitForAllForAllTyBinder_maybe, splitForAllTyCoVar_maybe, splitForAllTyCoVar, splitForAllTyVar_maybe, splitForAllCoVar_maybe, - splitPiTy_maybe, splitPiTy, splitPiTys, + splitPiTy_maybe, splitPiTy, splitPiTys, collectPiTyBinders, getRuntimeArgTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, @@ -290,6 +290,7 @@ import GHC.Utils.Panic import GHC.Data.FastString import GHC.Data.Maybe ( orElse, isJust, firstJust ) +import GHC.List (build) -- $type_classification -- #type_classification# @@ -2031,6 +2032,18 @@ splitPiTys ty = split ty ty [] split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs split orig_ty _ bs = (reverse bs, orig_ty) +collectPiTyBinders :: Type -> [PiTyBinder] +collectPiTyBinders ty = build $ \c n -> + let + split (ForAllTy b res) = Named b `c` split res + split (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) + = Anon (Scaled w arg) af `c` split res + split ty | Just ty' <- coreView ty = split ty' + split _ = n + in + split ty +{-# INLINE collectPiTyBinders #-} + -- | Extracts a list of run-time arguments from a function type, -- looking through newtypes to the right of arrows. -- ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1493,18 +1493,23 @@ in this (which it previously was): in \w. v True -} --------------------- -exprIsWorkFree :: CoreExpr -> Bool -- See Note [exprIsWorkFree] -exprIsWorkFree e = exprIsCheapX isWorkFreeApp e - -exprIsCheap :: CoreExpr -> Bool -exprIsCheap e = exprIsCheapX isCheapApp e +------------------------------------- +type CheapAppFun = Id -> Arity -> Bool + -- Is an application of this function to n *value* args + -- always cheap, assuming the arguments are cheap? + -- True mainly of data constructors, partial applications; + -- but with minor variations: + -- isWorkFreeApp + -- isCheapApp + -- isExpandableApp -exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool +exprIsCheapX :: CheapAppFun -> Bool -> CoreExpr -> Bool {-# INLINE exprIsCheapX #-} --- allow specialization of exprIsCheap and exprIsWorkFree +-- allow specialization of exprIsCheap, exprIsWorkFree and exprIsExpandable -- instead of having an unknown call to ok_app -exprIsCheapX ok_app e +-- expandable: Only True for exprIsExpandable, where Case and Let are never +-- expandable. +exprIsCheapX ok_app expandable e = ok e where ok e = go 0 e @@ -1515,7 +1520,7 @@ exprIsCheapX ok_app e go _ (Type {}) = True go _ (Coercion {}) = True go n (Cast e _) = go n e - go n (Case scrut _ _ alts) = ok scrut && + go n (Case scrut _ _ alts) = not expandable && ok scrut && and [ go n rhs | Alt _ _ rhs <- alts ] go n (Tick t e) | tickishCounts t = False | otherwise = go n e @@ -1523,90 +1528,26 @@ exprIsCheapX ok_app e | otherwise = go n e go n (App f e) | isRuntimeArg e = go (n+1) f && ok e | otherwise = go n f - go n (Let (NonRec _ r) e) = go n e && ok r - go n (Let (Rec prs) e) = go n e && all (ok . snd) prs + go n (Let (NonRec _ r) e) = not expandable && go n e && ok r + go n (Let (Rec prs) e) = not expandable && go n e && all (ok . snd) prs -- Case: see Note [Case expressions are work-free] -- App, Let: see Note [Arguments and let-bindings exprIsCheapX] +-------------------- +exprIsWorkFree :: CoreExpr -> Bool +-- See Note [exprIsWorkFree] +exprIsWorkFree e = exprIsCheapX isWorkFreeApp False e -{- Note [exprIsExpandable] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -An expression is "expandable" if we are willing to duplicate it, if doing -so might make a RULE or case-of-constructor fire. Consider - let x = (a,b) - y = build g - in ....(case x of (p,q) -> rhs)....(foldr k z y).... - -We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), -but we do want - - * the case-expression to simplify - (via exprIsConApp_maybe, exprIsLiteral_maybe) - - * the foldr/build RULE to fire - (by expanding the unfolding during rule matching) - -So we classify the unfolding of a let-binding as "expandable" (via the -uf_expandable field) if we want to do this kind of on-the-fly -expansion. Specifically: - -* True of constructor applications (K a b) - -* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. - (NB: exprIsCheap might not be true of this) - -* False of case-expressions. If we have - let x = case ... in ...(case x of ...)... - we won't simplify. We have to inline x. See #14688. - -* False of let-expressions (same reason); and in any case we - float lets out of an RHS if doing so will reveal an expandable - application (see SimplEnv.doFloatFromRhs). - -* Take care: exprIsExpandable should /not/ be true of primops. I - found this in test T5623a: - let q = /\a. Ptr a (a +# b) - in case q @ Float of Ptr v -> ...q... - - q's inlining should not be expandable, else exprIsConApp_maybe will - say that (q @ Float) expands to (Ptr a (a +# b)), and that will - duplicate the (a +# b) primop, which we should not do lightly. - (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) --} +-------------------- +exprIsCheap :: CoreExpr -> Bool +-- See Note [exprIsCheap] +exprIsCheap e = exprIsCheapX isCheapApp False e -------------------------------------- +-------------------- exprIsExpandable :: CoreExpr -> Bool -- See Note [exprIsExpandable] -exprIsExpandable e - = ok e - where - ok e = go 0 e - - -- n is the number of value arguments - go n (Var v) = isExpandableApp v n - go _ (Lit {}) = True - go _ (Type {}) = True - go _ (Coercion {}) = True - go n (Cast e _) = go n e - go n (Tick t e) | tickishCounts t = False - | otherwise = go n e - go n (Lam x e) | isRuntimeVar x = n==0 || go (n-1) e - | otherwise = go n e - go n (App f e) | isRuntimeArg e = go (n+1) f && ok e - | otherwise = go n f - go _ (Case {}) = False - go _ (Let {}) = False - - -------------------------------------- -type CheapAppFun = Id -> Arity -> Bool - -- Is an application of this function to n *value* args - -- always cheap, assuming the arguments are cheap? - -- True mainly of data constructors, partial applications; - -- but with minor variations: - -- isWorkFreeApp - -- isCheapApp +exprIsExpandable e = exprIsCheapX isExpandableApp True e isWorkFreeApp :: CheapAppFun isWorkFreeApp fn n_val_args @@ -1626,7 +1567,7 @@ isCheapApp fn n_val_args | isDeadEndId fn = True -- See Note [isCheapApp: bottoming functions] | otherwise = case idDetails fn of - DataConWorkId {} -> True -- Actually handled by isWorkFreeApp + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId op _ -> primOpIsCheap op @@ -1641,6 +1582,7 @@ isExpandableApp fn n_val_args | isWorkFreeApp fn n_val_args = True | otherwise = case idDetails fn of + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId {} -> False @@ -1672,6 +1614,50 @@ isExpandableApp fn n_val_args I'm not sure why we have a special case for bottoming functions in isCheapApp. Maybe we don't need it. +Note [exprIsExpandable] +~~~~~~~~~~~~~~~~~~~~~~~ +An expression is "expandable" if we are willing to duplicate it, if doing +so might make a RULE or case-of-constructor fire. Consider + let x = (a,b) + y = build g + in ....(case x of (p,q) -> rhs)....(foldr k z y).... + +We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), +but we do want + + * the case-expression to simplify + (via exprIsConApp_maybe, exprIsLiteral_maybe) + + * the foldr/build RULE to fire + (by expanding the unfolding during rule matching) + +So we classify the unfolding of a let-binding as "expandable" (via the +uf_expandable field) if we want to do this kind of on-the-fly +expansion. Specifically: + +* True of constructor applications (K a b) + +* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. + (NB: exprIsCheap might not be true of this) + +* False of case-expressions. If we have + let x = case ... in ...(case x of ...)... + we won't simplify. We have to inline x. See #14688. + +* False of let-expressions (same reason); and in any case we + float lets out of an RHS if doing so will reveal an expandable + application (see SimplEnv.doFloatFromRhs). + +* Take care: exprIsExpandable should /not/ be true of primops. I + found this in test T5623a: + let q = /\a. Ptr a (a +# b) + in case q @ Float of Ptr v -> ...q... + + q's inlining should not be expandable, else exprIsConApp_maybe will + say that (q @ Float) expands to (Ptr a (a +# b)), and that will + duplicate the (a +# b) primop, which we should not do lightly. + (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) + Note [isExpandableApp: bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's important that isExpandableApp does not respond True to bottoming @@ -1852,7 +1838,7 @@ expr_ok fun_ok primop_ok other_expr _ -> False ----------------------------- -app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool +app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreArg] -> Bool app_ok fun_ok primop_ok fun args | not (fun_ok fun) = False -- This code path is only taken for Note [Speculative evaluation] @@ -1867,13 +1853,11 @@ app_ok fun_ok primop_ok fun args -- DFuns terminate, unless the dict is implemented -- with a newtype in which case they may not - DataConWorkId {} -> args_ok - -- The strictness of the constructor has already - -- been expressed by its "wrapper", so we don't need - -- to take the arguments into account - -- Well, we thought so. But it's definitely wrong! - -- See #20749 and Note [How untagged pointers can - -- end up in strict fields] in GHC.Stg.InferTags + DataConWorkId dc + | isLazyDataConRep dc + -> args_ok + | otherwise + -> fields_ok (dataConRepStrictness dc) ClassOpId _ is_terminating_result | is_terminating_result -- See Note [exprOkForSpeculation and type classes] @@ -1923,7 +1907,7 @@ app_ok fun_ok primop_ok fun args -- Even if a function call itself is OK, any unlifted -- args are still evaluated eagerly and must be checked - args_ok = and (zipWith arg_ok arg_tys args) + args_ok = all2Prefix arg_ok arg_tys args arg_ok :: PiTyVarBinder -> CoreExpr -> Bool arg_ok (Named _) _ = True -- A type argument arg_ok (Anon ty _) arg -- A term argument @@ -1932,6 +1916,17 @@ app_ok fun_ok primop_ok fun args | otherwise = expr_ok fun_ok primop_ok arg + -- Used for DataCon worker arguments + fields_ok str_marks = all3Prefix field_ok arg_tys str_marks args + field_ok :: PiTyVarBinder -> StrictnessMark -> CoreExpr -> Bool + field_ok (Named _) _ _ = True + field_ok (Anon ty _) str arg + | NotMarkedStrict <- str -- iff it's a lazy field + , definitelyLiftedType (scaledThing ty) -- and its type is lifted + = True -- then the worker app does not eval + | otherwise + = expr_ok fun_ok primop_ok arg + ----------------------------- altsAreExhaustive :: [Alt b] -> Bool -- True <=> the case alternatives are definitely exhaustive @@ -2157,12 +2152,14 @@ exprIsConLike = exprIsHNFlike isConLikeId isConLikeUnfolding -- or PAPs. -- exprIsHNFlike :: HasDebugCallStack => (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool -exprIsHNFlike is_con is_con_unf = is_hnf_like +exprIsHNFlike is_con is_con_unf e + = -- pprTraceWith "hnf" (\r -> ppr r <+> ppr e) $ + is_hnf_like e where is_hnf_like (Var v) -- NB: There are no value args at this point - = id_app_is_value v 0 -- Catches nullary constructors, - -- so that [] and () are values, for example - -- and (e.g.) primops that don't have unfoldings + = id_app_is_value v [] -- Catches nullary constructors, + -- so that [] and () are values, for example + -- and (e.g.) primops that don't have unfoldings || is_con_unf (idUnfolding v) -- Check the thing's unfolding; it might be bound to a value -- or to a guaranteed-evaluated variable (isEvaldUnfolding) @@ -2186,7 +2183,7 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like -- See Note [exprIsHNF Tick] is_hnf_like (Cast e _) = is_hnf_like e is_hnf_like (App e a) - | isValArg a = app_is_value e 1 + | isValArg a = app_is_value e [a] | otherwise = is_hnf_like e is_hnf_like (Let _ e) = is_hnf_like e -- Lazy let(rec)s don't affect us is_hnf_like (Case e b _ as) @@ -2194,26 +2191,63 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like = is_hnf_like rhs is_hnf_like _ = False - -- 'n' is the number of value args to which the expression is applied - -- And n>0: there is at least one value argument - app_is_value :: CoreExpr -> Int -> Bool - app_is_value (Var f) nva = id_app_is_value f nva - app_is_value (Tick _ f) nva = app_is_value f nva - app_is_value (Cast f _) nva = app_is_value f nva - app_is_value (App f a) nva - | isValArg a = - app_is_value f (nva + 1) && - not (needsCaseBinding (exprType a) a) - -- For example f (x /# y) where f has arity two, and the first - -- argument is unboxed. This is not a value! - -- But f 34# is a value. - -- NB: Check app_is_value first, the arity check is cheaper - | otherwise = app_is_value f nva - app_is_value _ _ = False - - id_app_is_value id n_val_args - = is_con id - || idArity id > n_val_args + -- Collect arguments through Casts and Ticks and call id_app_is_value + app_is_value :: CoreExpr -> [CoreArg] -> Bool + app_is_value (Var f) as = id_app_is_value f as + app_is_value (Tick _ f) as = app_is_value f as + app_is_value (Cast f _) as = app_is_value f as + app_is_value (App f a) as | isValArg a = app_is_value f (a:as) + | otherwise = app_is_value f as + app_is_value _ _ = False + + id_app_is_value id val_args = + case compare (idArity id) (length val_args) of + EQ | is_con id -> -- Saturated app of a DataCon/CONLIKE Id + case mb_str_marks id of + Just str_marks -> -- with strict fields + assert (val_args `equalLength` str_marks) $ + fields_hnf str_marks + Nothing -> -- without strict fields: like PAP + args_hnf -- NB: CONLIKEs are lazy! + + GT -> -- PAP: Check unlifted val_args + args_hnf + + _ -> False + + where + -- Saturated, Strict DataCon: Check unlifted val_args and strict fields + fields_hnf str_marks = all3Prefix check_field val_arg_tys str_marks val_args + + -- PAP: Check unlifted val_args + args_hnf = all2Prefix check_arg val_arg_tys val_args + + fun_ty = idType id + val_arg_tys = mapMaybe anonPiTyBinderType_maybe (collectPiTyBinders fun_ty) + -- val_arg_tys = map exprType val_args, but much less costly. + -- The obvious definition regresses T16577 by 30% so we don't do it. + + check_arg a_ty a + | mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- Check unliftedness; for example f (x /# 12#) where f has arity two, + -- and the first argument is unboxed. This is not a value! + -- But f 34# is a value, so check args for HNFs. + -- NB: We check arity (and CONLIKEness) first because it's cheaper + -- and we reject quickly on saturated apps. + check_field a_ty str a + | isMarkedStrict str || mightBeUnliftedType a_ty = is_hnf_like a + | otherwise = True + -- isMarkedStrict: Respect Note [Strict fields in Core] + + mb_str_marks id + | Just dc <- isDataConWorkId_maybe id + , not (isLazyDataConRep dc) + = Just (dataConRepStrictness dc) + | otherwise + = Nothing + +{-# INLINE exprIsHNFlike #-} {- Note [exprIsHNF Tick] @@ -2775,7 +2809,7 @@ This means the seqs on x and y both become no-ops and compared to the first vers The downside is that the caller of $wfoo potentially has to evaluate `y` once if we can't prove it isn't already evaluated. But y coming out of a strict field is in WHNF so safe to evaluated. And most of the time it will be properly tagged+evaluated -already at the call site because of the Strict Field Invariant! See Note [Strict Field Invariant] for more in this. +already at the call site because of the Strict Field Invariant! See Note [STG Strict Field Invariant] for more in this. This makes GHC itself around 1% faster despite doing slightly more work! So this is generally quite good. We only apply this when we think there is a benefit in doing so however. There are a number of cases in which ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -644,7 +644,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 + (new_float, _bndr2) = mkNonRecFloat env is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -729,9 +729,9 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env False v rhs2 + ; let (float, v') = mkNonRecFloat env False v rhs2 ; return ( snocFloat floats2 float - , cpeEtaExpand arity (Var v)) }) + , cpeEtaExpand arity (Var v')) }) -- Wrap floating ticks ; let (floats4, rhs4) = wrapTicks floats3 rhs3 @@ -907,10 +907,10 @@ cpeRhsE env (Case scrut bndr ty alts) ; alts'' <- mapM (sat_alt env') alts' ; case alts'' of - [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] - | let is_unlifted = isUnliftedType (idType bndr2) - , let float = mkCaseFloat is_unlifted bndr2 scrut' - -> return (snocFloat floats float, rhs) +-- [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] +-- | let is_unlifted = isUnliftedType (idType bndr2) +-- , let float = mkCaseFloat is_unlifted bndr2 scrut' +-- -> return (snocFloat floats float, rhs) _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where sat_alt env (Alt con bs rhs) @@ -1570,8 +1570,9 @@ cpeArg env dmd arg ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 -- See Note [Eta expansion of arguments in CorePrep] - ; let arg_float = mkNonRecFloat env is_unlifted v arg3 - ; return (snocFloat floats2 arg_float, varToCoreExpr v) } + ; let (arg_float, v') = mkNonRecFloat env is_unlifted v arg3 + ---; pprTraceM "cpeArg" (ppr arg1 $$ ppr dec $$ ppr arg2) + ; return (snocFloat floats2 arg_float, varToCoreExpr v') } } cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity @@ -1793,10 +1794,10 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We pin demand info on floated lets, so that we can see the one-shot thunks. +We pin demand info on floated lets, so that we can see one-shot thunks. For example, f (g x) -where `f` uses its argument at least once, creates a Float for `y = g x` and we +where `f` uses its argument at most once, creates a Float for `y = g x` and we should better pin appropriate demand info on `y`. Note [Flatten case-binds] @@ -1807,7 +1808,7 @@ Suppose we have the following call, where f is strict: `case` out because `f` is strict.) In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` - Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + Float (a = case x of y { DEFAULT -> blah }) CaseBound top-lvl with the call `f a`. When we wrap that `Float` we will get @@ -1826,8 +1827,8 @@ This is easy to avoid: turn that into a FloatingBind of its own. This is easily done in the Case equation for `cpsRhsE`. Then our example will generate /two/ floats: - Float (y = x) CaseBound top_lvl - Float (a = blah) CaseBound top_lvl + Float (y = x) CaseBound str-ctx + Float (a = blah) CaseBound top-lvl and we'll end up with nested cases. @@ -1840,6 +1841,124 @@ Of course, the Simplifier never leaves us with an argument like this, but we and the above footwork in cpsRhsE avoids generating a nested case. +Note [Pin evaluatedness on floats] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider a call to a CBV function, such as a DataCon worker with *strict* fields, +in a *lazy* context, such as in the arg of a lazy function call to `f`: + + + data Box a = Box !a + ... f (Box e) ... -- f lazy, Box strict + +(A live example of this is T24730, inspired by $walexGetByte.) +During ANFisation, we will `mkNonRecFloat` for `e`, binding it to a +fresh binder `sat`, and binding `Box sat` as well to a fresh binder `sat2`. +We want to avoid allocating a thunk for `sat2` as often as possible, building +on the let floating mechanism in Case (2) of Note [wantFloatLocal]. + +Note that this mechanism requires `sat` to be detected as a value after +floating out any ok-for-spec floats, according to `exprIsHNF`. This means we +need an `evaldUnfolding` on `sat`, and `mkNonRecFloat` must do the pinning. + +There are two interesting cases: + + 1. When `e = I# (x +# 1#)`, we decompose into + case x +# 1# of x' -> + --- + I# x' + where everything above --- are floats and below --- is the residual RHS. + Here, `I# x'` is a value because `x'` is (NB: x' is a variable of unlifted type). + Following Case (2) of Note [wantFloatLocal], we want to float out the + ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's + field, to get + case x +# 1# of x' -> + let sat = I# x' in + --- + Box sat + And since we pin an `evaldUnfolding` on `sat`, we may even float out of + `f`'s lazy argument, again by Case (2) of Note [wantFloatLocal] + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 + If `sat` didn't have the `evaldUnfolding`, we'd get a large thunk in f's arg: + let sat2 = + case x +# 1# of x' -> + let sat = I# x' in + Box sat in + f sat2 + 2. + +Although `e` might not be a value, it might still decompose into floats that are +ok-for-spec and a value, for example + e = I# (x +# 1#) +decomposes into +Following Case (2) of Note [wantFloatLocal], we want to float out the +ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's +field, to get + case x +# 1# of x' -> + let sat = I# x' in + Box sat +Nice! But now we want to do the same for the argument to `f`, to get + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 +(NB: Since all floats are ok-for-spec, we may float out of the lazy argument.) +BUT, in order to do that in Case (2) of Note [wantFloatLocal], we must detect +`Box sat` as a value according to `exprIsHNF`; otherwise floating would be +unproductive. Crucially, this means we need `sat` to look evaluated, because +it ends up in a strict field. +We achieve this by attaching and `evaldUnfolding` to `sat` in `mkNonRecFloat`. + +*When + + 1. When `e=Just y` is a value, we will float `sat=Just y` as far as possible, + to top-level, even. It is important that we mark `sat` as evaluated (via + setting its unfolding to `evaldUnfolding`), otherwise we get a superfluous + thunk to carry out the field seq on Box's field, because + `exprIsHNF sat == False`: + + let sat = Just y in + let sat2 = case sat of x { __DEFAULT } -> Box x in + -- NONONO, want just `sat2 = Box x` + f sat2 + + This happened in $walexGetByte, where the thunk caused additional + allocation. + + 2. Similarly, when `e` is not a value, we still know that it is strictly + evaluated. Hence it is going to be case-bound, and we anticipate that `sat` + will be a case binder which is *always* evaluated. + Hence in this case, we also mark `sat` as evaluated via its unfolding. + This happened in GHC.Linker.Deps.$wgetLinkDeps, where without + `evaldUnfolding` we ended up with this: + + Word64Map = ... | Bin ... ... !Word64Map !Word64Map + case ... of { Word64Map.Bin a b l r -> + case insert ... of sat { __DEFAULT -> + case Word64Map.Bin a b l sat of sat2 { __DEFAULT -> + f sat2 + }}} + + Note that *the DataCon app `Bin a b l sat` was case-bound*, because it was + not detected to be a value according to `exprIsHNF`. + That is because the strict field `sat` lacked the `evaldUnfolding`, + although it ended up being case-bound. + + Small wrinkle: + It could be that `sat=insert ...` floats to top-level, where it is not + eagerly evaluated. In this case, we may not give `sat` an `evaldUnfolding`. + We detect this case by looking at the `FloatInfo` of `sat=insert ...`: If + it says `TopLvlFloatable`, we are conservative and will not give `sat` an + `evaldUnfolding`. + +TLDR; when creating a new float `sat=e` in `mkNonRecFloat`, propagate `sat` with +an `evaldUnfolding` if either + + 1. `e` is a value, or + 2. `sat=e` is case-bound, but won't float to top-level. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since call-by-value is much cheaper than call-by-need, we case-bind arguments @@ -2123,15 +2242,16 @@ zipManyFloats = foldr zipFloats emptyFloats mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind mkCaseFloat is_unlifted bndr scrut - = Float (NonRec bndr scrut) bound info + = -- pprTrace "mkCaseFloat" (ppr bndr <+> ppr (bound,info) + -- -- <+> ppr is_lifted <+> ppr is_strict + -- -- <+> ppr ok_for_spec <+> ppr evald + -- $$ ppr scrut) $ + Float (NonRec bndr scrut) bound info where (bound, info) -{- -Eventually we want the following code, when #20749 is fixed. - | is_lifted, is_hnf = (LetBound, TopLvlFloatable) - -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should - -- let-bind `StrictBox x'` after Note [Flatten case-binds]. --} +-- | is_lifted, is_hnf = (LetBound, TopLvlFloatable) +-- -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should +-- -- let-bind `StrictBox x'` after Note [Flatten case-binds]. | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) -- String literals are unboxed (so must be case-bound) and float to -- the top-level @@ -2141,15 +2261,16 @@ Eventually we want the following code, when #20749 is fixed. _is_lifted = not is_unlifted _is_hnf = exprIsHNF scrut -mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind +mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> (FloatingBind, Id) mkNonRecFloat env is_unlifted bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) - -- <+> ppr is_lifted <+> ppr is_strict - -- <+> ppr ok_for_spec + -- <+> if is_strict then text "strict" else if is_lifted then text "lazy" else text "unlifted" + -- <+> if ok_for_spec then text "ok-for-spec" else empty + -- <+> if evald then text "evald" else empty -- $$ ppr rhs) $ - Float (NonRec bndr rhs) bound info + (Float (NonRec bndr' rhs) bound info, bndr') where - (bound, info) + !(bound, info) | is_lifted, is_hnf = (LetBound, TopLvlFloatable) -- is_lifted: We currently don't allow unlifted values at the -- top-level or inside letrecs @@ -2180,6 +2301,11 @@ mkNonRecFloat env is_unlifted bndr rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) is_data_con = isJust . isDataConId_maybe + -- See Note [Pin evaluatedness on floats] + evald = is_hnf --- || (bound == CaseBound && info /= TopLvlFloatable) + bndr' | evald = bndr `setIdUnfolding` evaldUnfolding + | otherwise = bndr + -- | Wrap floats around an expression wrapBinds :: Floats -> CpeBody -> CpeBody wrapBinds floats body @@ -2285,6 +2411,10 @@ data FloatDecision = FloatNone | FloatAll +instance Outputable FloatDecision where + ppr FloatNone = text "none" + ppr FloatAll = text "all" + executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) executeFloatDecision dec floats rhs = case dec of @@ -2706,7 +2836,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs + (litAddrFloat, litAddrId') = mkNonRecFloat env True litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) @@ -2719,7 +2849,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do copyContentsCall = Var (primOpId CopyAddrToByteArrayOp) `App` Type realWorldTy - `App` Var litAddrId + `App` Var litAddrId' `App` Var mutableByteArrayId `App` mkIntLit platform 0 `App` contentsLength ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -64,8 +64,8 @@ With nofib being ~0.3% faster as well. See Note [Tag inference passes] for how we proceed to generate and use this information. -Note [Strict Field Invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [STG Strict Field Invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As part of tag inference we introduce the Strict Field Invariant. Which consists of us saying that: @@ -81,7 +81,7 @@ and will be tagged with `001` or `010` respectively. It will never point to a thunk, nor will it be tagged `000` (meaning "might be a thunk"). NB: Note that the proper tag for some objects is indeed `000`. Currently this is the case for PAPs. -This works analogous to how `WorkerLikeId`s work. See also Note [CBV Function Ids]. +This works analogous to how CBV functions work. See also Note [CBV Function Ids]. Why do we care? Because if we have code like: @@ -103,7 +103,7 @@ where we: * If not we convert `StrictJust x` into `case x of x' -> StrictJust x'` This is usually very beneficial but can cause regressions in rare edge cases where -we fail to proof that x is properly tagged, or where it simply isn't. +we fail to prove that x is properly tagged, or where it simply isn't. See Note [How untagged pointers can end up in strict fields] for how the second case can arise. @@ -124,15 +124,33 @@ Note that there are similar constraints around Note [CBV Function Ids]. Note [How untagged pointers can end up in strict fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Since the resolution of #20749 where Core passes assume that DataCon workers +evaluate their strict fields, it is pretty simple to see how the Simplifier +might exploit that knowledge to drop evals. Example: + + data T a = MkT !a + f :: [Int] -> T [Int] + f xs = xs `seq` MkT xs + +in Core we will have + + f = \xs -> MkT @[Int] xs + +No eval left there. + Consider data Set a = Tip | Bin !a (Set a) (Set a) We make a wrapper for Bin that evaluates its arguments $WBin x a b = case x of xv -> Bin xv a b Here `xv` will always be evaluated and properly tagged, just as the -Strict Field Invariant requires. +Note [STG Strict Field Invariant] requires. + +But alas, the Simplifier can destroy the invariant: see #15696. +Indeed, as Note [Strict fields in Core] explains, Core passes +assume that Data constructor workers evaluate their strict fields, +so the Simplifier will drop seqs freely. -But alas the Simplifier can destroy the invariant: see #15696. We start with thk = f () g x = ...(case thk of xv -> Bin xv Tip Tip)... @@ -153,7 +171,7 @@ Now you can see that the argument of Bin, namely thk, points to the thunk, not to the value as it did before. In short, although it may be rare, the output of optimisation passes -cannot guarantee to obey the Strict Field Invariant. For this reason +cannot guarantee to obey the Note [STG Strict Field Invariant]. For this reason we run tag inference. See Note [Tag inference passes]. Note [Tag inference passes] @@ -163,7 +181,7 @@ Tag inference proceeds in two passes: The result is then attached to /binders/. This is implemented by `inferTagsAnal` in GHC.Stg.InferTags * The second pass walks over the AST checking if the Strict Field Invariant is upheld. - See Note [Strict Field Invariant]. + See Note [STG Strict Field Invariant]. If required this pass modifies the program to uphold this invariant. Tag information is also moved from /binders/ to /occurrences/ during this pass. This is done by `GHC.Stg.InferTags.Rewrite (rewriteTopBinds)`. ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -57,7 +57,7 @@ The work of this pass is simple: * For any strict field we check if the argument is known to be properly tagged. * If it's not known to be properly tagged, we wrap the whole thing in a case, which will force the argument before allocation. -This is described in detail in Note [Strict Field Invariant]. +This is described in detail in Note [STG Strict Field Invariant]. The only slight complication is that we have to make sure not to invalidate free variable analysis in the process. @@ -210,7 +210,7 @@ When compiling bytecode we call myCoreToStg to get STG code first. myCoreToStg in turn calls out to stg2stg which runs the STG to STG passes followed by free variables analysis and the tag inference pass including its rewriting phase at the end. -Running tag inference is important as it upholds Note [Strict Field Invariant]. +Running tag inference is important as it upholds Note [STG Strict Field Invariant]. While code executed by GHCi doesn't take advantage of the SFI it can call into compiled code which does. So it must still make sure that the SFI is upheld. See also #21083 and #22042. ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -884,7 +884,7 @@ mostly relating to under what circumstances it evaluates its argument. Today, that story is simple: A dataToTag primop always evaluates its argument, unless tag inference determines the argument was already evaluated and correctly tagged. Getting here was a long journey, with -many similarities to the story behind Note [Strict Field Invariant] in +many similarities to the story behind Note [STG Strict Field Invariant] in GHC.Stg.InferTags. See also #15696. -} ===================================== compiler/GHC/Tc/TyCl/Build.hs ===================================== @@ -183,14 +183,15 @@ buildDataCon fam_envs dc_bang_opts src_name declared_infix prom_info src_bangs tag = lookupNameEnv_NF tag_map src_name -- See Note [Constructor tag allocation], fixes #14657 data_con = mkDataCon src_name declared_infix prom_info - src_bangs field_lbls + src_bangs impl_bangs str_marks field_lbls univ_tvs ex_tvs noConcreteTyVars user_tvbs eq_spec ctxt arg_tys res_ty NoPromInfo rep_tycon tag stupid_ctxt dc_wrk dc_rep dc_wrk = mkDataConWorkId work_name data_con - dc_rep = initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) + (dc_rep, impl_bangs, str_marks) = + initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) ; traceIf (text "buildDataCon 2" <+> ppr src_name) ; return data_con } ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1391,33 +1391,16 @@ arguments. That is the job of dmdTransformDataConSig. More precisely, * it returns the demands on the arguments; in the above example that is [SL, A] -Nasty wrinkle. Consider this code (#22475 has more realistic examples but -assume this is what the demand analyser sees) - - data T = MkT !Int Bool - get :: T -> Bool - get (MkT _ b) = b - - foo = let v::Int = I# 7 - t::T = MkT v True - in get t - -Now `v` is unused by `get`, /but/ we can't give `v` an Absent demand, -else we'll drop the binding and replace it with an error thunk. -Then the code generator (more specifically GHC.Stg.InferTags.Rewrite) -will add an extra eval of MkT's argument to give - foo = let v::Int = error "absent" - t::T = case v of v' -> MkT v' True - in get t - -Boo! Because of this extra eval (added in STG-land), the truth is that `MkT` -may (or may not) evaluate its arguments (as established in #21497). Hence the -use of `bump` in dmdTransformDataConSig, which adds in a `C_01` eval. The -`C_01` says "may or may not evaluate" which is absolutely faithful to what -InferTags.Rewrite does. - -In particular it is very important /not/ to make that a `C_11` eval, -see Note [Data-con worker strictness]. +When the data constructor worker has strict fields, an additional seq +will be inserted for each field (Note [Strict fields in Core]). +Hence we add an additional `seqDmd` for each strict field to emulate +field seq insertion. + +For example, consider `data SP a b = MkSP !a !b` and expression `MkSP x y`, +with the same sub-demand P(SL,A). +The strict fields bump up the strictness; we'd get [SL,1!A] for the field +demands. Note that the first demand was unaffected by the seq, whereas +the second, previously absent demand became `seqDmd` exactly. -} {- ********************************************************************* @@ -1617,6 +1600,29 @@ a bad fit because expression may not throw a precise exception (increasing precision of the analysis), but that's just a favourable guess. +Note [Side-effects and strictness] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Due to historic reasons and the continued effort not to cause performance +regressions downstream, Strictness Analysis is currently prone to discarding +observable side-effects (other than precise exceptions, see +Note [Precise exceptions and strictness analysis]) in some cases. For example, + f :: MVar () -> Int -> IO Int + f mv x = putMVar mv () >> (x `seq` return x) +The call to `putMVar` is an observable side-effect. Yet, Strictness Analysis +currently concludes that `f` is strict in `x` and uses call-by-value. +That means `f mv (error "boom")` will error out with the imprecise exception +rather performing the side-effect. + +This is a conscious violation of the semantics described in the paper +"a semantics for imprecise exceptions"; so it would be great if we could +identify the offending primops and extend the idea in +Note [Which scrutinees may throw precise exceptions] to general side-effects. + +Unfortunately, the existing has-side-effects classification for primops is +too conservative, listing `writeMutVar#` and even `readMutVar#` as +side-effecting. That is due to #3207. A possible way forward is described in +#17900, but no effort has been so far towards a resolution. + Note [Exceptions and strictness] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to smart about catching exceptions, but we aren't anymore. @@ -2333,7 +2339,8 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd - str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] + str_field_dmd = seqDmd -- See the bit about strict fields + -- in Note [Demand transformer for data constructors] -- | A special 'DmdTransformer' for dictionary selectors that feeds the demand -- on the result into the indicated dictionary component (if saturated). ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -260,7 +260,7 @@ The invariants around the arguments of call by value function like Ids are then: * Any `WorkerLikeId` * Some `JoinId` bindings. -This works analogous to the Strict Field Invariant. See also Note [Strict Field Invariant]. +This works analogous to the Strict Field Invariant. See also Note [STG Strict Field Invariant]. To make this work what we do is: * During W/W and SpecConstr any worker/specialized binding we introduce ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Core.Coercion import GHC.Core.Reduction import GHC.Core.Make import GHC.Core.FVs ( mkRuleInfo ) -import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase, coreAltsType ) +import GHC.Core.Utils ( exprType, mkCast, coreAltsType ) import GHC.Core.Unfold.Make import GHC.Core.SimpleOpt import GHC.Core.TyCon @@ -597,8 +597,12 @@ mkDataConWorkId wkr_name data_con = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty alg_wkr_info where - tycon = dataConTyCon data_con -- The representation TyCon - wkr_ty = dataConRepType data_con + tycon = dataConTyCon data_con -- The representation TyCon + wkr_ty = dataConRepType data_con + univ_tvs = dataConUnivTyVars data_con + ex_tcvs = dataConExTyCoVars data_con + arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys + str_marks = dataConRepStrictness data_con ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo @@ -606,12 +610,19 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setDmdSigInfo` wkr_sig + -- Workers eval their strict fields + -- See Note [Strict fields in Core] `setLFInfo` wkr_lf_info - -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + wkr_sig = mkClosedDmdSig wkr_dmds topDiv + wkr_dmds = map mk_dmd str_marks + mk_dmd MarkedStrict = evalDmd + mk_dmd NotMarkedStrict = topDmd + -- See Note [LFInfo of DataCon workers and wrappers] wkr_lf_info | wkr_arity == 0 = LFCon data_con @@ -619,9 +630,6 @@ mkDataConWorkId wkr_name data_con -- LFInfo stores post-unarisation arity ----------- Workers for newtypes -------------- - univ_tvs = dataConUnivTyVars data_con - ex_tcvs = dataConExTyCoVars data_con - arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma @@ -789,10 +797,10 @@ mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon - -> UniqSM DataConRep + -> UniqSM (DataConRep, [HsImplBang], [StrictnessMark]) mkDataConRep dc_bang_opts fam_envs wrap_name data_con | not wrapper_reqd - = return NoDataConRep + = return (NoDataConRep, arg_ibangs, rep_strs) | otherwise = do { wrap_args <- mapM (newLocal (fsLit "conrep")) wrap_arg_tys @@ -856,11 +864,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con ; return (DCR { dcr_wrap_id = wrap_id , dcr_boxer = mk_boxer boxers - , dcr_arg_tys = rep_tys - , dcr_stricts = rep_strs - -- For newtypes, dcr_bangs is always [HsLazy]. - -- See Note [HsImplBangs for newtypes]. - , dcr_bangs = arg_ibangs }) } + , dcr_arg_tys = rep_tys } + , arg_ibangs, rep_strs) } where (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys, _orig_res_ty) @@ -918,8 +923,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. -- See dataConUserTyVarsNeedWrapper below. - && (any isBanged (ev_ibangs ++ arg_ibangs))) - -- Some forcing/unboxing (includes eq_spec) + && (any isUnpacked (ev_ibangs ++ arg_ibangs))) + -- Some unboxing (includes eq_spec) || isFamInstTyCon tycon -- Cast result @@ -1185,7 +1190,7 @@ dataConArgRep arg_ty HsLazy = ([(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) dataConArgRep arg_ty (HsStrict _) - = ([(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) + = ([(arg_ty, MarkedStrict)], (unitUnboxer, unitBoxer)) -- Seqs are inserted in STG dataConArgRep arg_ty (HsUnpack Nothing) = dataConArgUnpack arg_ty @@ -1215,9 +1220,6 @@ wrapCo co rep_ty (unbox_rep, box_rep) -- co :: arg_ty ~ rep_ty ; return (rep_ids, rep_expr `Cast` mkSymCo sco) } ------------------------ -seqUnboxer :: Unboxer -seqUnboxer v = return ([v], mkDefaultCase (Var v) v) - unitUnboxer :: Unboxer unitUnboxer v = return ([v], \e -> e) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Utils.Misc ( dropWhileEndLE, spanEnd, last2, lastMaybe, onJust, - List.foldl1', foldl2, count, countWhile, all2, + List.foldl1', foldl2, count, countWhile, all2, all2Prefix, all3Prefix, lengthExceeds, lengthIs, lengthIsNot, lengthAtLeast, lengthAtMost, lengthLessThan, @@ -652,6 +652,30 @@ all2 _ [] [] = True all2 p (x:xs) (y:ys) = p x y && all2 p xs ys all2 _ _ _ = False +all2Prefix :: (a -> b -> Bool) -> [a] -> [b] -> Bool +-- ^ `all2Prefix p xs ys` is a fused version of `and $ zipWith2 p xs ys`. +-- So if one list is shorter than the other, `p` is assumed to be `True` for the +-- suffix. +all2Prefix p = foldr k z + where + k x go ys' = case ys' of + (y:ys'') -> p x y && go ys'' + _ -> True + z _ = True +{-# INLINE all2Prefix #-} + +all3Prefix :: (a -> b -> c -> Bool) -> [a] -> [b] -> [c] -> Bool +-- ^ `all3Prefix p xs ys zs` is a fused version of `and $ zipWith3 p xs ys zs`. +-- So if one list is shorter than the others, `p` is assumed to be `True` for +-- the suffix. +all3Prefix p = foldr k z + where + k x go ys' zs' = case (ys',zs') of + (y:ys'',z:zs'') -> p x y z && go ys'' zs'' + _ -> False + z _ _ = True +{-# INLINE all3Prefix #-} + -- Count the number of times a predicate is true count :: (a -> Bool) -> [a] -> Int ===================================== testsuite/tests/dmdanal/sigs/T16859.stderr ===================================== @@ -4,7 +4,7 @@ T16859.bar: <1!A> T16859.baz: <1L><1!P(L)><1C(1,L)> T16859.buz: <1!P(L,L)> T16859.foo: <1L> -T16859.mkInternalName: <1!P(L)><1L><1L> +T16859.mkInternalName: <1!P(L)> T16859.n_loc: <1!P(A,A,A,1L)> T16859.n_occ: <1!P(A,1!P(L,L),A,A)> T16859.n_sort: <1!P(1L,A,A,A)> ===================================== testsuite/tests/ghci/should_run/T21052.stdout ===================================== @@ -5,7 +5,7 @@ BCO_toplevel :: GHC.Types.IO [GHC.Types.Any] {} \u [] let { sat :: [GHC.Types.Any] - [LclId] = + [LclId, Unf=OtherCon []] = :! [GHC.Tuple.() GHC.Types.[]]; } in GHC.Internal.Base.returnIO sat; ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -14,8 +14,8 @@ T23083.g = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> let { sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer - [LclId] - sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + [LclId, Unf=OtherCon []] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1, Dmd=SL] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in f sat -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/simplCore/should_run/T20749.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE UnliftedDatatypes #-} +import Data.Kind +import GHC.Exts + +type StrictPair :: Type -> Type -> UnliftedType +data StrictPair a b = SP !a !b + +f :: StrictPair Int Int -> StrictPair Int Int -> Int -> Bool +{-# OPAQUE f #-} +f (SP x _) (SP _ y) z = x < y + z + +g :: Int -> [Int] -> Int +{-# OPAQUE g #-} +g x ys = h ys + where + h [] = 0 + h (y:ys) = case SP x 27 of + u -> if f u u y then x else x + h ys + +main :: IO () +main = print (g undefined []) ===================================== testsuite/tests/simplCore/should_run/T20749.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/T24662.hs ===================================== @@ -0,0 +1,27 @@ +{-# LANGUAGE MagicHash #-} + +module T24662 where + +import GHC.Exts + +f1 :: a -> Int# -> Int -> Int +{-# OPAQUE f1 #-} +f1 _ x (I# y) = I# (x +# y) + +f2 :: Int# -> a -> Int -> Int +{-# OPAQUE f2 #-} +f2 x _ (I# y) = I# (x +# y) + +loopy :: Int -> Int# +loopy x | x>0 = loopy x + | otherwise = 0# + +-- Should either let or case-bind t (preferrably the latter), but we should do +-- it consistently in foo1 and foo2. +foo1 x = let t :: Int -> Int + t = f1 True (loopy x) in + t `seq` (x, t) + +foo2 x = let t :: Int -> Int + t = f2 True (loopy x) in + t `seq` (x, t) ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -107,6 +107,7 @@ test('UnliftedArgRule', normal, compile_and_run, ['']) test('T21229', normal, compile_and_run, ['-O']) test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) +test('T20749', normal, compile_and_run, ['']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) @@ -114,3 +115,4 @@ test('T23184', normal, compile_and_run, ['-O']) test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) test('T23289', normal, compile_and_run, ['']) test('T23056', [only_ways(['ghci-opt'])], ghci_script, ['T23056.script']) +test('T24662', normal, compile_and_run, ['']) ===================================== testsuite/tests/simplStg/should_compile/T19717.stderr ===================================== @@ -3,15 +3,15 @@ Foo.f :: forall {a}. a -> [GHC.Internal.Maybe.Maybe a] [GblId, Arity=1, Str=<1L>, Unf=OtherCon []] = {} \r [x] - case x of x1 { + case x of x1 [Dmd=SL] { __DEFAULT -> let { sat [Occ=Once1] :: GHC.Internal.Maybe.Maybe a - [LclId] = + [LclId, Unf=OtherCon []] = GHC.Internal.Maybe.Just! [x1]; } in let { sat [Occ=Once1] :: [GHC.Internal.Maybe.Maybe a] - [LclId] = + [LclId, Unf=OtherCon []] = :! [sat GHC.Types.[]]; } in : [sat sat]; }; ===================================== testsuite/tests/simplStg/should_compile/inferTags002.stderr ===================================== @@ -1,88 +1,30 @@ -==================== Output Cmm ==================== -[M.$WMkT_entry() { // [R3, R2] - { info_tbls: [(cym, - label: block_cym_info - rep: StackRep [False] - srt: Nothing), - (cyp, - label: M.$WMkT_info - rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } - srt: Nothing), - (cys, - label: block_cys_info - rep: StackRep [False] - srt: Nothing)] - stack_info: arg_space: 8 - } - {offset - cyp: // global - if ((Sp + -16) < SpLim) (likely: False) goto cyv; else goto cyw; - cyv: // global - R1 = M.$WMkT_closure; - call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - cyw: // global - I64[Sp - 16] = cym; - R1 = R2; - P64[Sp - 8] = R3; - Sp = Sp - 16; - if (R1 & 7 != 0) goto cym; else goto cyn; - cyn: // global - call (I64[R1])(R1) returns to cym, args: 8, res: 8, upd: 8; - cym: // global - I64[Sp] = cys; - _sy8::P64 = R1; - R1 = P64[Sp + 8]; - P64[Sp + 8] = _sy8::P64; - call stg_ap_0_fast(R1) returns to cys, args: 8, res: 8, upd: 8; - cys: // global - Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto cyA; else goto cyz; - cyA: // global - HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cys, args: 8, res: 8, upd: 8; - cyz: // global - I64[Hp - 16] = M.MkT_con_info; - P64[Hp - 8] = P64[Sp + 8]; - P64[Hp] = R1; - R1 = Hp - 15; - Sp = Sp + 16; - call (P64[Sp])(R1) args: 8, res: 0, upd: 8; - } - }, - section ""data" . M.$WMkT_closure" { - M.$WMkT_closure: - const M.$WMkT_info; - }] - - - ==================== Output Cmm ==================== [M.f_entry() { // [R2] - { info_tbls: [(cyK, - label: block_cyK_info + { info_tbls: [(cAs, + label: block_info rep: StackRep [] srt: Nothing), - (cyN, + (cAv, label: M.f_info rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} } srt: Nothing)] stack_info: arg_space: 8 } {offset - cyN: // global - if ((Sp + -8) < SpLim) (likely: False) goto cyO; else goto cyP; - cyO: // global + _lbl_: // global + if ((Sp + -8) < SpLim) (likely: False) goto cAw; else goto cAx; + _lbl_: // global R1 = M.f_closure; call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8; - cyP: // global - I64[Sp - 8] = cyK; + _lbl_: // global + I64[Sp - 8] = cAs; R1 = R2; Sp = Sp - 8; - if (R1 & 7 != 0) goto cyK; else goto cyL; - cyL: // global - call (I64[R1])(R1) returns to cyK, args: 8, res: 8, upd: 8; - cyK: // global + if (R1 & 7 != 0) goto cAs; else goto cAt; + _lbl_: // global + call (I64[R1])(R1) returns to cAs, args: 8, res: 8, upd: 8; + _lbl_: // global R1 = P64[R1 + 15]; Sp = Sp + 8; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; @@ -97,47 +39,47 @@ ==================== Output Cmm ==================== [M.MkT_entry() { // [R3, R2] - { info_tbls: [(cz1, - label: block_cz1_info + { info_tbls: [(cAJ, + label: block_info rep: StackRep [False] srt: Nothing), - (cz4, + (cAM, label: M.MkT_info rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } srt: Nothing), - (cz7, - label: block_cz7_info + (cAP, + label: block_info rep: StackRep [False] srt: Nothing)] stack_info: arg_space: 8 } {offset - cz4: // global - if ((Sp + -16) < SpLim) (likely: False) goto cza; else goto czb; - cza: // global + _lbl_: // global + if ((Sp + -16) < SpLim) (likely: False) goto cAS; else goto cAT; + _lbl_: // global R1 = M.MkT_closure; call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - czb: // global - I64[Sp - 16] = cz1; + _lbl_: // global + I64[Sp - 16] = cAJ; R1 = R2; P64[Sp - 8] = R3; Sp = Sp - 16; - if (R1 & 7 != 0) goto cz1; else goto cz2; - cz2: // global - call (I64[R1])(R1) returns to cz1, args: 8, res: 8, upd: 8; - cz1: // global - I64[Sp] = cz7; - _tyf::P64 = R1; + if (R1 & 7 != 0) goto cAJ; else goto cAK; + _lbl_: // global + call (I64[R1])(R1) returns to cAJ, args: 8, res: 8, upd: 8; + _lbl_: // global + I64[Sp] = cAP; + __locVar_::P64 = R1; R1 = P64[Sp + 8]; - P64[Sp + 8] = _tyf::P64; - call stg_ap_0_fast(R1) returns to cz7, args: 8, res: 8, upd: 8; - cz7: // global + P64[Sp + 8] = __locVar_::P64; + call stg_ap_0_fast(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto czf; else goto cze; - czf: // global + if (Hp > HpLim) (likely: False) goto cAX; else goto cAW; + _lbl_: // global HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cz7, args: 8, res: 8, upd: 8; - cze: // global + call stg_gc_unpt_r1(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global I64[Hp - 16] = M.MkT_con_info; P64[Hp - 8] = P64[Sp + 8]; P64[Hp] = R1; @@ -155,14 +97,14 @@ ==================== Output Cmm ==================== [M.MkT_con_entry() { // [] - { info_tbls: [(czl, + { info_tbls: [(cB3, label: M.MkT_con_info rep: HeapRep 2 ptrs { Con {tag: 0 descr:"main:M.MkT"} } srt: Nothing)] stack_info: arg_space: 8 } {offset - czl: // global + _lbl_: // global R1 = R1 + 1; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d2eee16b6f7e16d42db5c37a3483f9e0135fc7c0...a471377446f7158fe14d9c781f62b50b1eb6b894 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d2eee16b6f7e16d42db5c37a3483f9e0135fc7c0...a471377446f7158fe14d9c781f62b50b1eb6b894 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 13:20:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 09:20:30 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] Avoid unneccessarily re-serialising the `ModIface` Message-ID: <662baa1ebcc9_14ae3e1db74541143c6@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 21816fcb by Fendor at 2024-04-26T15:19:55+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - 10 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,7 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict -- --------------------------------------------------------------------------- @@ -166,14 +167,18 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh + modIfaceData <- freezeBinHandle2 bh start pure mod_iface { mi_ext_fields = extFields + , mi_hi_bytes = FullIfaceBinHandle $ Strict.Just modIfaceData } @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -468,7 +477,7 @@ to the table we need to deserialise first. What deduplication tables exist and the order of serialisation is currently statically specified in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility -functions such as 'forwardGet'. +functions such as 'forwardGetRel'. Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -235,7 +235,7 @@ readHieFileContents bh0 name_cache = do get bh1 where get_dictionary tbl bin_handle = do - fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + fsTable <- Binary.forwardGetRel bin_handle (getTable tbl bin_handle) let fsReader = mkReaderFromTable tbl fsTable bhFs = addReaderToUserData fsReader bin_handle ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -41,7 +41,7 @@ instance Binary ExtensibleFields where -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBinWriter bh - putAt bh field_p_p field_p + putAtRel bh field_p_p field_p seekBinWriter bh field_p put_ bh dat @@ -50,11 +50,11 @@ instance Binary ExtensibleFields where -- Get the names and field pointers: header_entries <- replicateM n $ - (,) <$> get bh <*> get bh + (,) <$> get bh <*> getRelBin bh -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBinReader bh field_p + seekBinReaderRel bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1107,7 +1107,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1148,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -153,17 +153,33 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface return final_iface +-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. +-- +-- We compress the 'ModIface' by serialising the 'ModIface' to an in-memory byte array, and then deserialising it. +-- The deserialisation will deduplicate certain values depending on the 'CompressionIFace' level. +-- See Note [Deduplication during iface binary serialisation] for how we do that. +-- +-- Additionally, we cache the serialised byte array, so if the 'ModIface' is not modified +-- after calling 'shareIface', 'writeBinIface' will reuse that buffer without serialising the 'ModIface' again. +-- Modifying the 'ModIface' forces us to re-serialise it again. shareIface :: NameCache -> CompressionIFace -> ModIface -> IO ModIface +shareIface _ NormalCompression mi = do + -- In 'NormalCompression', the sharing isn't reducing the memory usage, as 'Name's and 'FastString's are + -- already shared, and at this compression level, we don't compress/share anything else. + -- Thus, for a brief moment we simply double the memory residency for no reason. + -- Therefore, we only try to share expensive values if the compression mode is higher than + -- 'NormalCompression' + pure mi shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } forceModIface resiface - return resiface + pure resiface updateDecl :: [IfaceDecl] -> Maybe StgCgInfos -> Maybe CmmCgInfos -> [IfaceDecl] @@ -318,40 +334,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,59 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +110,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +192,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -262,8 +317,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes :: !(IfaceBinHandle phase) } {- @@ -349,6 +405,7 @@ instance Binary ModIface where mi_src_hash = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file + mi_hi_bytes = _hi_bytes, -- TODO: explain mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -449,6 +506,7 @@ instance Binary ModIface where mi_hsc_src = hsc_src, mi_src_hash = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read + mi_hi_bytes = FullIfaceBinHandle Strict.Nothing, mi_deps = deps, mi_usages = usages, mi_exports = exports, @@ -487,6 +545,7 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo @@ -496,6 +555,7 @@ emptyPartialModIface mod mi_sig_of = Nothing, mi_hsc_src = HsSrcFile, mi_src_hash = fingerprint0, + mi_hi_bytes = PartialIfaceBinHandle, mi_deps = noDependencies, mi_usages = [], mi_exports = [], @@ -522,6 +582,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_decls = [] + , mi_hi_bytes = FullIfaceBinHandle Strict.Nothing , mi_final_exts = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, @@ -626,5 +687,97 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls = decls + , mi_extra_decls = extra_decls + , mi_final_exts = final_exts + , mi_hi_bytes = hi_bytes + } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns = val } +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -4,7 +4,6 @@ {-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} -{-# LANGUAGE TypeFamilies #-} -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected @@ -20,7 +19,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -33,6 +32,7 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, @@ -47,7 +47,9 @@ module GHC.Utils.Binary readBinMemN, putAt, getAt, + putAtRel, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -102,6 +104,10 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + shrinkBinBuffer, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -126,7 +132,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -156,7 +162,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -196,6 +201,63 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -289,9 +351,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr a) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -312,6 +395,9 @@ class Binary a where putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () putAt bh p x = do seekBinWriter bh p; put_ bh x; return () +putAtRel :: WriteBinHandle -> Bin (RelBinPtr a) -> Bin a -> IO () +putAtRel bh from to = putAt bh from (makeRelativeBin $ toRelBin from to) + getAt :: Binary a => ReadBinHandle -> Bin a -> IO a getAt bh p = do seekBinReader bh p; get bh @@ -382,12 +468,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1108,6 +1200,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1136,7 +1233,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1148,6 +1245,43 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPutRel put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference. +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + putAtRel bh pre_a a + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1157,19 +1291,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAtRel bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1178,7 +1312,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1472,13 +1606,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit fa76e1ee98906f5bc8fc4598524610020b653412 +Subproject commit e9eee9ea56dd21f22fff70106a1289d7f35440a3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21816fcb43f9ba80413a58febf1c9e4406d94aae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21816fcb43f9ba80413a58febf1c9e4406d94aae You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 13:21:17 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 09:21:17 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-delay-serialisation] 82 commits: EPA: Use EpaLocation for RecFieldsDotDot Message-ID: <662baa4d5479b_14ae3e1ea4e98115198@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-delay-serialisation at Glasgow Haskell Compiler / GHC Commits: 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - d636f6a2 by Fendor at 2024-04-24T09:47:56+02:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - be6836a2 by Fendor at 2024-04-24T09:47:56+02:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - a0f3d1f7 by Fendor at 2024-04-24T09:49:28+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 61407888 by Fendor at 2024-04-24T09:49:28+02:00 Break cyclic module dependency - - - - - 9932b31d by Fendor at 2024-04-24T09:49:28+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - 7ddf8ecf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: T21839c T24471 ------------------------- - - - - - 2c32fbcf by Matthew Pickering at 2024-04-24T09:49:28+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 5c18a8b8 by Fendor at 2024-04-24T09:49:28+02:00 Implement TrieMap for IfaceType - - - - - 5bdba6d5 by Fendor at 2024-04-26T11:30:54+02:00 Improve sharing of duplicated values in `ModIface` As a `ModIface` contains often duplicated values that are not necessarily shared, we improve sharing by serialising the `ModIface` to an in-memory byte array. Serialisation uses deduplication tables, and deserialisation implicitly shares duplicated values. This helps reducing the peak memory usage while compiling in `--make` mode. The peak memory usage is especially reduced when generating interface files with core expressions (`-fwrite-if-simplified-core`). On agda, this reduces the peak memory usage: * `2.2 GB` to `1.9 GB` for a ghci session. On `lib:Cabal`, we report: * `570 MB` to `500 MB` for a ghci session * `790 MB` to `667 MB` for compiling `lib:Cabal` with ghc The execution time is not affected. - - - - - 21816fcb by Fendor at 2024-04-26T15:19:55+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - d81ec7d8 by Matthew Pickering at 2024-04-26T15:21:05+02:00 Delay deserialisation of `IfaceType` until needed Introduces `IfaceSerialisationType` which holds onto a ByteString in-memory. All `IfaceType`'s are first deserialised to `IfaceSerialisationType`, so no actual deserialisation happens until the value is requested. Then, we decode `IfaceSerialisationType` into the real `IfaceType` value. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/939a1c746f49bab04821ae7615bccb8005020519...d81ec7d8cede176933864359db26241e31fa0abb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/939a1c746f49bab04821ae7615bccb8005020519...d81ec7d8cede176933864359db26241e31fa0abb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 13:28:11 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 26 Apr 2024 09:28:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.10 Message-ID: <662babeb91f48_14ae3e1fdae201153cf@gitlab.mail> Ben Gamari pushed new branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.10 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 15:33:30 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 11:33:30 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-delay-serialisation] Delay deserialisation of `IfaceType` until needed Message-ID: <662bc94a12e56_3ff819e648441119dc@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-delay-serialisation at Glasgow Haskell Compiler / GHC Commits: fbdc1671 by Matthew Pickering at 2024-04-26T17:33:15+02:00 Delay deserialisation of `IfaceType` until needed Introduces `IfaceSerialisationType` which holds onto a ByteString in-memory. All `IfaceType`'s are first deserialised to `IfaceSerialisationType`, so no actual deserialisation happens until the value is requested. Then, we decode `IfaceSerialisationType` into the real `IfaceType` value. - - - - - 9 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -43,7 +43,6 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt -import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -59,12 +58,17 @@ import Data.Array.IO import Data.Array.Unsafe import Data.Char import Data.IORef +import Control.Monad +import GHC.Iface.Type (IfaceType, getIfaceType, putIfaceType) +import System.IO.Unsafe import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) import qualified GHC.Data.Strict as Strict +import GHC.Data.FastString +import GHC.Iface.Type -- --------------------------------------------------------------------------- -- Reading and writing binary interface files @@ -509,11 +513,18 @@ Here, a visualisation of the table structure we currently have (ignoring 'Extens -- The symbol table -- +readFromSymTab :: ReaderUserData -> ReadBinHandle -> IO FullBinData +readFromSymTab ud bh = do + p <- getRelBin bh -- a BinPtr + frozen_bh <- freezeBinHandle (makeAbsoluteBin p) (setReaderUserData bh ud) + seekBinReaderRel bh p -- skip over the object for now + return frozen_bh + initReadIfaceTypeTable :: ReaderUserData -> IO (ReaderTable IfaceType) initReadIfaceTypeTable ud = do pure $ ReaderTable - { getTable = getGenericSymbolTable (\bh -> lazyGet' getIfaceType (setReaderUserData bh ud)) + { getTable = getGenericSymbolTable (\bh -> IfaceSerialisedType <$!> readFromSymTab ud bh) , mkReaderFromTable = \tbl -> mkReader (getGenericSymtab tbl) } @@ -582,7 +593,6 @@ initNameWriterTable = do , mkWriter $ putName bin_symtab ) - putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -172,10 +172,8 @@ shareIface _ NormalCompression mi = do pure mi shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) - start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi rbh <- shrinkBinBuffer bh - seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } forceModIface resiface @@ -272,6 +270,7 @@ mkIfaceTc hsc_env safe_mode mod_details mod_summary mb_program mkFullIface hsc_env partial_iface Nothing Nothing + mkIface_ :: HscEnv -> Module -> CoreProgram -> HscSource -> Bool -> Dependencies -> GlobalRdrEnv -> NameEnv FixItem -> Warnings GhcRn -> HpcInfo ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -37,6 +37,8 @@ module GHC.Iface.Syntax ( fromIfaceWarnings, fromIfaceWarningTxt, + getIfaceExpr, + -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, freeNamesIfConDecls, @@ -615,7 +617,8 @@ fromIfaceStringLiteral (IfStringLiteral st fs) = StringLiteral st fs Nothing -} data IfaceExpr - = IfaceLcl IfLclName + = IfaceSerialisedExpr !FullBinData + | IfaceLcl IfLclName | IfaceExt IfExtName | IfaceType IfaceType | IfaceCo IfaceCoercion @@ -2478,6 +2481,9 @@ instance Binary IfaceAlt where return (IfaceAlt a b c) instance Binary IfaceExpr where + put_ bh (IfaceSerialisedExpr f) = do + deserialised <- getIfaceExpr =<< thawBinHandle f + put_ bh deserialised put_ bh (IfaceLcl aa) = do putByte bh 0 put_ bh aa @@ -2537,7 +2543,20 @@ instance Binary IfaceExpr where put_ bh (IfaceLitRubbish ConstraintLike r) = do putByte bh 15 put_ bh r + get bh = do + start <- tellBinReader @() bh + _ <- getIfaceExpr bh + end <- tellBinReader @() bh + seekBinReader bh start + frozen <- IfaceSerialisedExpr <$> freezeBinHandle end bh + seekBinReader bh end + return frozen + + + +getIfaceExpr :: ReadBinHandle -> IO IfaceExpr +getIfaceExpr bh = do h <- getByte bh case h of 0 -> do aa <- get bh @@ -2831,6 +2850,7 @@ instance NFData IfaceUnfolding where instance NFData IfaceExpr where rnf = \case + IfaceSerialisedExpr bd -> bd `seq` () IfaceLcl nm -> rnf nm IfaceExt nm -> rnf nm IfaceType ty -> rnf ty ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -175,7 +175,8 @@ type IfaceKind = IfaceType -- Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType' -- before being printed. See Note [Pretty printing via Iface syntax] in "GHC.Types.TyThing.Ppr" data IfaceType - = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType] + = IfaceSerialisedType !FullBinData + | IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType] | IfaceTyVar IfLclName -- Type/coercion variable only, not tycon | IfaceLitTy IfaceTyLit | IfaceAppTy IfaceType IfaceAppArgs @@ -2230,6 +2231,10 @@ getIfaceTypeShared bh = do else seekBinReader bh start >> getIfaceType bh putIfaceType :: WriteBinHandle -> IfaceType -> IO () +putIfaceType bh (IfaceSerialisedType fb) = do + ity <- getIfaceType =<< thawBinHandle fb + putIfaceType bh ity + putIfaceType _ (IfaceFreeTyVar tv) = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv) @@ -2287,8 +2292,9 @@ getIfaceType bh = do 8 -> do { s <- get bh; i <- get bh; tys <- get bh ; return (IfaceTupleTy s i tys) } - _ -> do n <- get bh + 9 -> do n <- get bh return (IfaceLitTy n) + n -> panic $ "getIfaceType: " ++ show n instance Binary IfLclName where put_ bh = put_ bh . ifLclNameFS @@ -2487,6 +2493,7 @@ instance Binary (DefMethSpec IfaceType) where instance NFData IfaceType where rnf = \case + IfaceSerialisedType bh -> bh `seq` () IfaceFreeTyVar f1 -> f1 `seq` () IfaceTyVar f1 -> rnf f1 IfaceLitTy f1 -> rnf f1 ===================================== compiler/GHC/Iface/Type/Map.hs ===================================== @@ -11,6 +11,7 @@ import Control.Monad ((>=>)) import GHC.Types.Unique.DFM import Data.Functor.Product import GHC.Types.Var (VarBndr(..)) +import GHC.Utils.Binary newtype IfaceTypeMap a = IfaceTypeMap (IfaceTypeMapG a) @@ -42,7 +43,8 @@ data IfaceTypeMapX a , ifm_forall_ty :: IfaceForAllBndrMap (IfaceTypeMapG a) , ifm_cast_ty :: IfaceTypeMapG (IfaceCoercionMap a) , ifm_coercion_ty :: IfaceCoercionMap a - , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) } + , ifm_tuple_ty :: TupleSortMap (PromotionFlagMap (IfaceAppArgsMap a)) + , ifm_serialised_ty :: ForeignBinDataMap (OffsetBinDataMap a) } type IfaceLiteralMap = Map.Map IfaceTyLit type FunTyFlagMap = Map.Map FunTyFlag @@ -51,6 +53,8 @@ type ForAllTyFlagMap = Map.Map ForAllTyFlag type IfaceCoercionMap = Map.Map IfaceCoercion type TupleSortMap = Map.Map TupleSort type PromotionFlagMap = Map.Map PromotionFlag +type ForeignBinDataMap = Map.Map BinArray +type OffsetBinDataMap = Map.Map Int type IfaceForAllBndrMap = Compose IfaceBndrMap ForAllTyFlagMap type IfaceIdBndrMap = Compose IfaceTypeMapG (Compose (UniqDFM IfLclName) IfaceTypeMapG) @@ -72,7 +76,9 @@ emptyE = IFM { ifm_lit = emptyTM , ifm_forall_ty = emptyTM , ifm_cast_ty = emptyTM , ifm_coercion_ty = emptyTM - , ifm_tuple_ty = emptyTM } + , ifm_tuple_ty = emptyTM + , ifm_serialised_ty = emptyTM + } instance Functor IfaceTypeMapX where fmap f IFM { ifm_lit = ilit @@ -83,7 +89,8 @@ instance Functor IfaceTypeMapX where , ifm_forall_ty = ifal , ifm_cast_ty = icast , ifm_coercion_ty = ico - , ifm_tuple_ty = itup } + , ifm_tuple_ty = itup + , ifm_serialised_ty = iser } = IFM { ifm_lit = fmap f ilit , ifm_var = fmap f ivar @@ -93,7 +100,9 @@ instance Functor IfaceTypeMapX where , ifm_forall_ty = fmap (fmap f) ifal , ifm_cast_ty = fmap (fmap f) icast , ifm_coercion_ty = fmap f ico - , ifm_tuple_ty = fmap (fmap (fmap f)) itup } + , ifm_tuple_ty = fmap (fmap (fmap f)) itup + , ifm_serialised_ty = fmap (fmap f) iser + } instance TrieMap IfaceTypeMapX where type Key IfaceTypeMapX = IfaceType @@ -116,7 +125,8 @@ ftE f IFM { ifm_lit = ilit , ifm_forall_ty = ifal , ifm_cast_ty = icast , ifm_coercion_ty = ico - , ifm_tuple_ty = itup } + , ifm_tuple_ty = itup + , ifm_serialised_ty = iser } = IFM { ifm_lit = filterTM f ilit , ifm_var = filterTM f ivar @@ -126,7 +136,9 @@ ftE f IFM { ifm_lit = ilit , ifm_forall_ty = fmap (filterTM f) ifal , ifm_cast_ty = fmap (filterTM f) icast , ifm_coercion_ty = filterTM f ico - , ifm_tuple_ty = fmap (fmap (filterTM f)) itup } + , ifm_tuple_ty = fmap (fmap (filterTM f)) itup + , ifm_serialised_ty = fmap (filterTM f) iser + } {-# INLINE fdE #-} fdE :: (a -> b -> b) -> IfaceTypeMapX a -> b -> b @@ -138,7 +150,8 @@ fdE f IFM { ifm_lit = ilit , ifm_forall_ty = ifal , ifm_cast_ty = icast , ifm_coercion_ty = ico - , ifm_tuple_ty = itup } + , ifm_tuple_ty = itup + , ifm_serialised_ty= iser } = foldTM f ilit . foldTM f ivar . foldTM (foldTM f) iapp . foldTM (foldTM (foldTM (foldTM f))) ift . foldTM (foldTM f) itc @@ -146,6 +159,7 @@ fdE f IFM { ifm_lit = ilit . foldTM (foldTM f) icast . foldTM f ico . foldTM (foldTM (foldTM f)) itup + . foldTM (foldTM f) iser bndrToKey :: IfaceBndr -> Either (IfaceType, (IfLclName, IfaceType)) IfaceTvBndr bndrToKey (IfaceIdBndr (a,b,c)) = Left (a, (b,c)) @@ -155,6 +169,7 @@ bndrToKey (IfaceTvBndr k) = Right k lkE :: IfaceType -> IfaceTypeMapX a -> Maybe a lkE it ifm = go it ifm where + go (IfaceSerialisedType binData) = ifm_serialised_ty >.> lookupTM (fbd_buffer binData) >=> lookupTM (fbd_off_s binData) go (IfaceFreeTyVar {}) = error "ftv" go (IfaceTyVar var) = ifm_var >.> lookupTM var go (IfaceLitTy l) = ifm_lit >.> lookupTM l @@ -168,6 +183,7 @@ lkE it ifm = go it ifm {-# INLINE xtE #-} xtE :: IfaceType -> XT a -> IfaceTypeMapX a -> IfaceTypeMapX a +xtE (IfaceSerialisedType binData) f m = m { ifm_serialised_ty = ifm_serialised_ty m |> alterTM (fbd_buffer binData) |>> alterTM (fbd_off_s binData) f } xtE (IfaceFreeTyVar {}) _ _ = error "ftv" xtE (IfaceTyVar var) f m = m { ifm_var = ifm_var m |> alterTM var f } xtE (IfaceLitTy l) f m = m { ifm_lit = ifm_lit m |> alterTM l f } ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -131,6 +131,7 @@ import Data.Foldable import GHC.Builtin.Names (ioTyConName, rOOT_MAIN) import GHC.Iface.Errors.Types import Language.Haskell.Syntax.Extension (NoExtField (NoExtField)) +import GHC.Utils.Binary {- This module takes @@ -1386,6 +1387,11 @@ loop. See #19744. tcIfaceType :: IfaceType -> IfL Type tcIfaceType = go where + go i@(IfaceSerialisedType bs) = do + deserialised <- liftIO (getIfaceType =<< thawBinHandle bs) + go deserialised + + go (IfaceTyVar n) = TyVarTy <$> tcIfaceTyVar n go (IfaceFreeTyVar n) = pprPanic "tcIfaceType:IfaceFreeTyVar" (ppr n) go (IfaceLitTy l) = LitTy <$> tcIfaceTyLit l @@ -1504,6 +1510,9 @@ tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -} tcIfaceExpr :: IfaceExpr -> IfL CoreExpr +tcIfaceExpr (IfaceSerialisedExpr fbh) = do + deserialised <- liftIO (getIfaceExpr =<< thawBinHandle fbh) + tcIfaceExpr deserialised tcIfaceExpr (IfaceType ty) = Type <$> tcIfaceType ty ===================================== compiler/GHC/Tc/Types.hs ===================================== @@ -342,7 +342,7 @@ data IfLclEnv -- Whether or not the IfaceDecl came from a boot -- file or not; we'll use this to choose between -- NoUnfolding and BootUnfolding - if_boot :: IsBootInterface, + if_boot :: !IsBootInterface, -- The field is used only for error reporting -- if (say) there's a Lint error in it ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -458,6 +458,7 @@ instance Binary ModIface where lazyPut bh warns lazyPut bh anns put_ bh decls + --lazyPutMaybe bh extra_decls put_ bh extra_decls put_ bh insts put_ bh fam_insts @@ -490,6 +491,7 @@ instance Binary ModIface where warns <- {-# SCC "bin_warns" #-} lazyGet bh anns <- {-# SCC "bin_anns" #-} lazyGet bh decls <- {-# SCC "bin_tycldecls" #-} get bh +-- extra_decls <- lazyGetMaybe bh extra_decls <- get bh insts <- {-# SCC "bin_insts" #-} get bh fam_insts <- {-# SCC "bin_fam_insts" #-} get bh ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -19,7 +19,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, RelBin(..), getRelBin, + ( {-type-} Bin, RelBin(..), getRelBin, makeAbsoluteBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -39,6 +39,7 @@ module GHC.Utils.Binary withBinBuffer, freezeWriteHandle, thawReadHandle, + shrinkBinBuffer, foldGet, foldGet', @@ -246,18 +247,6 @@ thawBinHandle (FullBinData user_data ix _end sz ba) = do ixr <- newFastMutInt ix return $ ReadBinMem user_data ixr sz ba --- Copy the BinBuffer to a new BinBuffer which is exactly the right size. --- This performs a copy of the underlying buffer. --- The buffer may be truncated if the offset is not at the end of the written --- output. --- --- UserData is also discarded during the copy --- You should just use this when translating a Put handle into a Get handle. -shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle -shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do - unsafeUnpackBinBuffer (copy bs) - - --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -276,6 +265,8 @@ data WriteBinHandle wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } + -- XXX: should really store a "high water mark" for dumping out + -- the binary data to a file. -- | A read-only handle that can be used to deserialise binary data from a buffer. -- @@ -344,6 +335,17 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do ix_r <- newFastMutInt 0 return (ReadBinMem noReaderUserData ix_r len arr) +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + --------------------------------------------------------------- -- Bin --------------------------------------------------------------- @@ -1277,7 +1279,7 @@ forwardGetRel bh get_A = do -- store current position p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinReader bh $ makeAbsoluteBin p + seekBinReaderRel bh p r <- get_A seekBinReader bh p_a pure r @@ -1615,7 +1617,7 @@ getGenericSymbolTable deserialiser bh = do sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do - f <- deserialiser bh + !f <- deserialiser bh writeArray mut_arr i f unsafeFreeze mut_arr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbdc16716431c447a0493313cecbceb693e25541 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbdc16716431c447a0493313cecbceb693e25541 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 16:12:59 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Fri, 26 Apr 2024 12:12:59 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 6 commits: Add run-time configurability of .hi file compression Message-ID: <662bd28b7f853_3ff81913d1854123295@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 58c19f2d by Matthew Pickering at 2024-04-26T11:15:09+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: MultiLayerModulesDefsGhciWithCore T21839c T24471 ------------------------- - - - - - ec52327c by Matthew Pickering at 2024-04-26T11:15:36+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 9227f1a8 by Fendor at 2024-04-26T11:15:36+02:00 Implement TrieMap for IfaceType - - - - - 4c32894a by Fendor at 2024-04-26T18:10:10+02:00 Improve sharing of duplicated values in `ModIface` As a `ModIface` contains often duplicated values that are not necessarily shared, we improve sharing by serialising the `ModIface` to an in-memory byte array. Serialisation uses deduplication tables, and deserialisation implicitly shares duplicated values. This helps reducing the peak memory usage while compiling in `--make` mode. The peak memory usage is especially reduced when generating interface files with core expressions (`-fwrite-if-simplified-core`). On agda, this reduces the peak memory usage: * `2.2 GB` to `1.9 GB` for a ghci session. On `lib:Cabal`, we report: * `570 MB` to `500 MB` for a ghci session * `790 MB` to `667 MB` for compiling `lib:Cabal` with ghc The execution time is not affected. - - - - - 48b11db1 by Fendor at 2024-04-26T18:10:10+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - df5db6c2 by Fendor at 2024-04-26T18:10:10+02:00 Make sure to always invalidate correctly - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs - compiler/ghc.cabal.in - docs/users_guide/using-optimisation.rst - + testsuite/tests/iface/IfaceSharingIfaceType.hs - + testsuite/tests/iface/IfaceSharingName.hs - + testsuite/tests/iface/Lib.hs - + testsuite/tests/iface/Makefile - + testsuite/tests/iface/all.T - + testsuite/tests/iface/if_faststring.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21816fcb43f9ba80413a58febf1c9e4406d94aae...df5db6c2050ba85e99ac814b18feb775e60faaac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21816fcb43f9ba80413a58febf1c9e4406d94aae...df5db6c2050ba85e99ac814b18feb775e60faaac You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 18:33:47 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 14:33:47 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Refactor the Binary serialisation interface Message-ID: <662bf38b8fe51_3ff8192531bbc135427@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f27ce3de by Fendor at 2024-04-26T14:33:04-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - 416e92c7 by Fendor at 2024-04-26T14:33:05-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 0572c5d7 by Simon Peyton Jones at 2024-04-26T14:33:05-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - d6b65579 by Alan Zimmerman at 2024-04-26T14:33:06-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 09fba9c7 by Andrew Lelechenko at 2024-04-26T14:33:06-04:00 Document that setEnv is not thread-safe - - - - - 9028ad54 by Bryan Richter at 2024-04-26T14:33:06-04:00 CI: Work around frequent Signal 9 errors - - - - - 28 changed files: - .gitlab-ci.yml - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/PprExportWarn.hs - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - utils/check-exact/Main.hs - utils/haddock Changes: ===================================== .gitlab-ci.yml ===================================== @@ -297,6 +297,12 @@ lint-ci-config: GIT_SUBMODULE_STRATEGY: none before_script: - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + # Note [Nix-in-Docker] + # ~~~~~~~~~~~~~~~~~~~~ + # FIXME: This is a workaround for a Nix-in-Docker issue. See + # https://gitlab.haskell.org/ghc/head.hackage/-/issues/38#note_560487 for + # discussion. + - nix-shell -p gnused --run "sed -i -e 's/nixbld//' /etc/nix/nix.conf" script: - nix run .gitlab/generate-ci#generate-jobs # 1 if .gitlab/generate_jobs changed the output of the generated config @@ -1106,6 +1112,8 @@ project-version: GIT_SUBMODULE_STRATEGY: "none" before_script: - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + # FIXME: See Note [Nix-in-Docker] + - nix-shell -p gnused --run "sed -i -e 's/nixbld//' /etc/nix/nix.conf" - nix-channel --update - cat version.sh # Calculate the project version ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +30,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +68,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +102,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +140,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1399,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1433,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1480,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c1aed888135517684d0eb07096ce99d5ac61413...9028ad549e217f55055ab635faf51be729dd41f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c1aed888135517684d0eb07096ce99d5ac61413...9028ad549e217f55055ab635faf51be729dd41f3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 18:39:25 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 26 Apr 2024 14:39:25 -0400 Subject: [Git][ghc/ghc][ghc-9.10] docs: Don't use str.isascii Message-ID: <662bf4dce81fe_3ff81927ad9b81502bb@gitlab.mail> Ben Gamari pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 57b07e02 by Ben Gamari at 2024-04-26T09:26:51-04:00 docs: Don't use str.isascii `str.isascii` is only supported in Python 3.7 and later. - - - - - 1 changed file: - docs/users_guide/conf.py Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -202,6 +202,10 @@ def parse_flag(env, sig, signode): # Reference name left unchanged return sig +def isascii(c): + """ N.B. str.isascii isn't available until Python 3.7 """ + return ord(c) < 128 + def haddock_role(lib): """ For instance, @@ -241,7 +245,7 @@ def haddock_role(lib): # Escape any symbols in the identifier; # see also Haddock.Utils.makeAnchorId def escapeChar(c): - if (c in ':_.') or (c.isascii() and c.isalnum()): + if (c in ':_.') or (isascii(c) and c.isalnum()): return c return '-%d-' % ord(c) thing = ''.join(escapeChar(c) for c in thing) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57b07e0266712f9bb71fda508d2bdb93b19f70da -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57b07e0266712f9bb71fda508d2bdb93b19f70da You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 19:38:53 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 26 Apr 2024 15:38:53 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24726 Message-ID: <662c02cd11b98_2fdea85aaac801eb@gitlab.mail> Simon Peyton Jones pushed new branch wip/T24726 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24726 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 20:32:04 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 26 Apr 2024 16:32:04 -0400 Subject: [Git][ghc/ghc][wip/romes/fixes-2] 1362 commits: Avoid desugaring non-recursive lets into recursive lets Message-ID: <662c0f445f191_2fdeae8f4a49178c@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/fixes-2 at Glasgow Haskell Compiler / GHC Commits: 3e80c2b4 by Arnaud Spiwack at 2023-06-20T03:19:41-04:00 Avoid desugaring non-recursive lets into recursive lets This prepares for having linear let expressions in the frontend. When desugaring lets, SPECIALISE statements create more copies of a let binding. Because of the rewrite rules attached to the bindings, there are dependencies between the generated binds. Before this commit, we simply wrapped all these in a mutually recursive let block, and left it to the simplified to sort it out. With this commit: we are careful to generate the bindings in dependency order, so that we can wrap them in consecutive lets (if the source is non-recursive). - - - - - 9fad49e0 by Ben Gamari at 2023-06-20T03:20:19-04:00 rts: Do not call exit() from SIGINT handler Previously `shutdown_handler` would call `stg_exit` if the scheduler was Oalready found to be in `SCHED_INTERRUPTING` state (or higher). However, `stg_exit` is not signal-safe as it calls `exit` (which calls `atexit` handlers). The only safe thing to do in this situation is to call `_exit`, which terminates with minimal cleanup. Fixes #23417. - - - - - 7485f848 by Andrew Lelechenko at 2023-06-20T03:20:57-04:00 Bump Cabal submodule This requires changing the recomp007 test because now cabal passes `this-unit-id` to executable components, and that unit-id contains a hash which includes the ABI of the dependencies. Therefore changing the dependencies means that -this-unit-id changes and recompilation is triggered. The spririt of the test is to test GHC's recompilation logic assuming that `-this-unit-id` is constant, so we explicitly pass `-ipid` to `./configure` rather than letting `Cabal` work it out. - - - - - 1464a2a8 by mangoiv at 2023-06-20T03:21:34-04:00 [feat] add a hint to `HasField` error message - add a hint that indicates that the record that the record dot is used on might just be missing a field - as the intention of the programmer is not entirely clear, it is only shown if the type is known - This addresses in part issue #22382 - - - - - b65e78dd by Ben Gamari at 2023-06-20T16:56:43-04:00 rts/ipe: Fix unused lock warning - - - - - 6086effd by Ben Gamari at 2023-06-20T16:56:44-04:00 rts/ProfilerReportJson: Fix memory leak - - - - - 1e48c434 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Various warnings fixes - - - - - 471486b9 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix printf format mismatch - - - - - 80603fb3 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect #include <sys/poll.h> According to Alpine's warnings and poll(2), <poll.h> should be preferred. - - - - - ff18e6fd by Ben Gamari at 2023-06-20T16:56:44-04:00 nonmoving: Fix unused definition warrnings - - - - - 6e7fe8ee by Ben Gamari at 2023-06-20T16:56:44-04:00 Disable futimens on Darwin. See #22938 - - - - - b7706508 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect CPP guard - - - - - 94f00e9b by Ben Gamari at 2023-06-20T16:56:44-04:00 hadrian: Ensure that -Werror is passed when compiling the RTS. Previously the `+werror` transformer would only pass `-Werror` to GHC, which does not ensure that the same is passed to the C compiler when building the RTS. Arguably this is itself a bug but for now we will just work around this by passing `-optc-Werror` to GHC. I tried to enable `-Werror` in all C compilations but the boot libraries are something of a portability nightmare. - - - - - 5fb54bf8 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Disable `#pragma GCC`s on clang compilers Otherwise the build fails due to warnings. See #23530. - - - - - cf87f380 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix capitalization of prototype - - - - - 17f250d7 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect format specifier - - - - - 0ff1c501 by Josh Meredith at 2023-06-20T16:57:20-04:00 JS: remove js_broken(22576) in favour of the pre-existing wordsize(32) condition (#22576) - - - - - 3d1d42b7 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Memory usage fixes for Haddock - Do not include `mi_globals` in the `NoBackend` backend. It was only included for Haddock, but Haddock does not actually need it. This causes a 200MB reduction in max residency when generating haddocks on the Agda codebase (roughly 1GB to 800MB). - Make haddock_{parser,renamer}_perf tests more accurate by forcing docs to be written to interface files using `-fwrite-interface` Bumps haddock submodule. Metric Decrease: haddock.base - - - - - 8185b1c2 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Fix associated data family doc structure items Associated data families were being given their own export DocStructureItems, which resulted in them being documented separately from their classes in haddocks. This commit fixes it. - - - - - 4d356ea3 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: implement TH support - Add ghc-interp.js bootstrap script for the JS interpreter - Interactively link and execute iserv code from the ghci package - Incrementally load and run JS code for splices into the running iserv Co-authored-by: Luite Stegeman <stegeman at gmail.com> - - - - - 3249cf12 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Don't use getKey - - - - - f84ff161 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Stg: return imported FVs This is used to determine what to link when using the interpreter. For now it's only used by the JS interpreter but it could easily be used by the native interpreter too (instead of extracting names from compiled BCOs). - - - - - fab2ad23 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Fix some recompilation avoidance tests - - - - - a897dc13 by Sylvain Henry at 2023-06-21T12:04:59-04:00 TH_import_loop is now broken as expected - - - - - dbb4ad51 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: always recompile when TH is enabled (cf #23013) - - - - - 711b1d24 by Bartłomiej Cieślar at 2023-06-21T12:59:27-04:00 Add support for deprecating exported items (proposal #134) This is an implementation of the deprecated exports proposal #134. The proposal introduces an ability to introduce warnings to exports. This allows for deprecating a name only when it is exported from a specific module, rather than always depreacting its usage. In this example: module A ({-# DEPRECATED "do not use" #-} x) where x = undefined --- module B where import A(x) `x` will emit a warning when it is explicitly imported. Like the declaration warnings, export warnings are first accumulated within the `Warnings` struct, then passed into the ModIface, from which they are then looked up and warned about in the importing module in the `lookup_ie` helpers of the `filterImports` function (for the explicitly imported names) and in the `addUsedGRE(s)` functions where they warn about regular usages of the imported name. In terms of the AST information, the custom warning is stored in the extension field of the variants of the `IE` type (see Trees that Grow for more information). The commit includes a bump to the haddock submodule added in MR #28 Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - c1865854 by Ben Gamari at 2023-06-21T12:59:30-04:00 configure: Bump version to 9.8 Bumps Haddock submodule - - - - - 4e1de71c by Ben Gamari at 2023-06-21T21:07:48-04:00 configure: Bump version to 9.9 Bumps haddock submodule. - - - - - 5b6612bc by Ben Gamari at 2023-06-23T03:56:49-04:00 rts: Work around missing prototypes errors Darwin's toolchain inexpliciably claims that `write_barrier` and friends have declarations without prototypes, despite the fact that (a) they are definitions, and (b) the prototypes appear only a few lines above. Work around this by making the definitions proper prototypes. - - - - - 43b66a13 by Matthew Pickering at 2023-06-23T03:57:26-04:00 ghcup-metadata: Fix date modifier (M = minutes, m = month) Fixes #23552 - - - - - 564164ef by Luite Stegeman at 2023-06-24T10:27:29+09:00 Support large stack frames/offsets in GHCi bytecode interpreter Bytecode instructions like PUSH_L (push a local variable) contain an operand that refers to the stack slot. Before this patch, the operand type was SmallOp (Word16), limiting the maximum stack offset to 65535 words. This could cause compiler panics in some cases (See #22888). This patch changes the operand type for stack offsets from SmallOp to Op, removing the stack offset limit. Fixes #22888 - - - - - 8d6574bc by Sylvain Henry at 2023-06-26T13:15:06-04:00 JS: support levity-polymorphic datatypes (#22360,#22291) - thread knowledge about levity into PrimRep instead of panicking - JS: remove assumption that unlifted heap objects are rts objects (TVar#, etc.) Doing this also fixes #22291 (test added). There is a small performance hit (~1% more allocations). Metric Increase: T18698a T18698b - - - - - 5578bbad by Matthew Pickering at 2023-06-26T13:15:43-04:00 MR Review Template: Mention "Blocked on Review" label In order to improve our MR review processes we now have the label "Blocked on Review" which allows people to signal that a MR is waiting on a review to happen. See: https://mail.haskell.org/pipermail/ghc-devs/2023-June/021255.html - - - - - 4427e9cf by Matthew Pickering at 2023-06-26T13:15:43-04:00 Move MR template to Default.md This makes it more obvious what you have to modify to affect the default template rather than looking in the project settings. - - - - - 522bd584 by Arnaud Spiwack at 2023-06-26T13:16:33-04:00 Revert "Avoid desugaring non-recursive lets into recursive lets" This (temporary) reverts commit 3e80c2b40213bebe302b1bd239af48b33f1b30ef. Fixes #23550 - - - - - c59fbb0b by Torsten Schmits at 2023-06-26T19:34:20+02:00 Propagate breakpoint information when inlining across modules Tracking ticket: #23394 MR: !10448 * Add constructor `IfaceBreakpoint` to `IfaceTickish` * Store breakpoint data in interface files * Store `BreakArray` for the breakpoint's module, not the current module, in BCOs * Store module name in BCOs instead of `Unique`, since the `Unique` from an `Iface` doesn't match the modules in GHCi's state * Allocate module name in `ModBreaks`, like `BreakArray` * Lookup breakpoint by module name in GHCi * Skip creating breakpoint instructions when no `ModBreaks` are available, rather than injecting `ModBreaks` in the linker when breakpoints are enabled, and panicking when `ModBreaks` is missing - - - - - 6f904808 by Greg Steuck at 2023-06-27T16:53:07-04:00 Remove undefined FP_PROG_LD_BUILD_ID from configure.ac's - - - - - e89aa072 by Andrei Borzenkov at 2023-06-27T16:53:44-04:00 Remove arity inference in type declarations (#23514) Arity inference in type declarations was introduced as a workaround for the lack of @k-binders. They were added in 4aea0a72040, so I simplified all of this by simply removing arity inference altogether. This is part of GHC Proposal #425 "Invisible binders in type declarations". - - - - - 459dee1b by Torsten Schmits at 2023-06-27T16:54:20-04:00 Relax defaulting of RuntimeRep/Levity when printing Fixes #16468 MR: !10702 Only default RuntimeRep to LiftedRep when variables are bound by the toplevel forall - - - - - 151f8f18 by Torsten Schmits at 2023-06-27T16:54:57-04:00 Remove duplicate link label in linear types docs - - - - - ecdc4353 by Rodrigo Mesquita at 2023-06-28T12:24:57-04:00 Stop configuring unused Ld command in `settings` GHC has no direct dependence on the linker. Rather, we depend upon the C compiler for linking and an object-merging program (which is typically `ld`) for production of GHCi objects and merging of C stubs into final object files. Despite this, for historical reasons we still recorded information about the linker into `settings`. Remove these entries from `settings`, `hadrian/cfg/system.config`, as well as the `configure` logic responsible for this information. Closes #23566. - - - - - bf9ec3e4 by Bryan Richter at 2023-06-28T12:25:33-04:00 Remove extraneous debug output - - - - - 7eb68dd6 by Bryan Richter at 2023-06-28T12:25:33-04:00 Work with unset vars in -e mode - - - - - 49c27936 by Bryan Richter at 2023-06-28T12:25:33-04:00 Pass positional arguments in their positions By quoting $cmd, the default "bash -i" is a single argument to run, and no file named "bash -i" actually exists to be run. - - - - - 887dc4fc by Bryan Richter at 2023-06-28T12:25:33-04:00 Handle unset value in -e context - - - - - 5ffc7d7b by Rodrigo Mesquita at 2023-06-28T21:07:36-04:00 Configure CPP into settings There is a distinction to be made between the Haskell Preprocessor and the C preprocessor. The former is used to preprocess Haskell files, while the latter is used in C preprocessing such as Cmm files. In practice, they are both the same program (usually the C compiler) but invoked with different flags. Previously we would, at configure time, configure the haskell preprocessor and save the configuration in the settings file, but, instead of doing the same for CPP, we had hardcoded in GHC that the CPP program was either `cc -E` or `cpp`. This commit fixes that asymmetry by also configuring CPP at configure time, and tries to make more explicit the difference between HsCpp and Cpp (see Note [Preprocessing invocations]). Note that we don't use the standard CPP and CPPFLAGS to configure Cpp, but instead use the non-standard --with-cpp and --with-cpp-flags. The reason is that autoconf sets CPP to "$CC -E", whereas we expect the CPP command to be configured as a standalone executable rather than a command. These are symmetrical with --with-hs-cpp and --with-hs-cpp-flags. Cleanup: Hadrian no longer needs to pass the CPP configuration for CPP to be C99 compatible through -optP, since we now configure that into settings. Closes #23422 - - - - - 5efa9ca5 by Ben Gamari at 2023-06-28T21:08:13-04:00 hadrian: Always canonicalize topDirectory Hadrian's `topDirectory` is intended to provide an absolute path to the root of the GHC tree. However, if the tree is reached via a symlink this One question here is whether the `canonicalizePath` call is expensive enough to warrant caching. In a quick microbenchmark I observed that `canonicalizePath "."` takes around 10us per call; this seems sufficiently low not to worry. Alternatively, another approach here would have been to rather move the canonicalization into `m4/fp_find_root.m4`. This would have avoided repeated canonicalization but sadly path canonicalization is a hard problem in POSIX shell. Addresses #22451. - - - - - b3e1436f by aadaa_fgtaa at 2023-06-28T21:08:53-04:00 Optimise ELF linker (#23464) - cache last elements of `relTable`, `relaTable` and `symbolTables` in `ocInit_ELF` - cache shndx table in ObjectCode - run `checkProddableBlock` only with debug rts - - - - - 30525b00 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Introduce MO_{ACQUIRE,RELEASE}_FENCE - - - - - b787e259 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Drop MO_WriteBarrier rts: Drop write_barrier - - - - - 7550b4a5 by Ben Gamari at 2023-06-28T21:09:30-04:00 rts: Drop load_store_barrier() This is no longer used. - - - - - d5f2875e by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop last instances of prim_{write,read}_barrier - - - - - 965ac2ba by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Eliminate remaining uses of load_load_barrier - - - - - 0fc5cb97 by Sven Tennie at 2023-06-28T21:09:31-04:00 compiler: Drop MO_ReadBarrier - - - - - 7a7d326c by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop load_load_barrier This is no longer used. - - - - - 9f63da66 by Sven Tennie at 2023-06-28T21:09:31-04:00 Delete write_barrier function - - - - - bb0ed354 by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Make collectFreshWeakPtrs definition a prototype x86-64/Darwin's toolchain inexplicably warns that collectFreshWeakPtrs needs to be a prototype. - - - - - ef81a1eb by Sven Tennie at 2023-06-28T21:10:08-04:00 Fix number of free double regs D1..D4 are defined for aarch64 and thus not free. - - - - - c335fb7c by Ryan Scott at 2023-06-28T21:10:44-04:00 Fix typechecking of promoted empty lists The `'[]` case in `tc_infer_hs_type` is smart enough to handle arity-0 uses of `'[]` (see the newly added `T23543` test case for an example), but the `'[]` case in `tc_hs_type` was not. We fix this by changing the `tc_hs_type` case to invoke `tc_infer_hs_type`, as prescribed in `Note [Future-proofing the type checker]`. There are some benign changes to test cases' expected output due to the new code path using `forall a. [a]` as the kind of `'[]` rather than `[k]`. Fixes #23543. - - - - - fcf310e7 by Rodrigo Mesquita at 2023-06-28T21:11:21-04:00 Configure MergeObjs supports response files rather than Ld The previous configuration script to test whether Ld supported response files was * Incorrect (see #23542) * Used, in practice, to check if the *merge objects tool* supported response files. This commit modifies the macro to run the merge objects tool (rather than Ld), using a response file, and checking the result with $NM Fixes #23542 - - - - - 78b2f3cc by Sylvain Henry at 2023-06-28T21:12:02-04:00 JS: fix JS stack printing (#23565) - - - - - 9f01d14b by Matthew Pickering at 2023-06-29T04:13:41-04:00 Add -fpolymorphic-specialisation flag (off by default at all optimisation levels) Polymorphic specialisation has led to a number of hard to diagnose incorrect runtime result bugs (see #23469, #23109, #21229, #23445) so this commit introduces a flag `-fpolymorhphic-specialisation` which allows users to turn on this experimental optimisation if they are willing to buy into things going very wrong. Ticket #23469 - - - - - b1e611d5 by Ben Gamari at 2023-06-29T04:14:17-04:00 Rip out runtime linker/compiler checks We used to choose flags to pass to the toolchain at runtime based on the platform running GHC, and in this commit we drop all of those runtime linker checks Ultimately, this represents a change in policy: We no longer adapt at runtime to the toolchain being used, but rather make final decisions about the toolchain used at /configure time/ (we have deleted Note [Run-time linker info] altogether!). This works towards the goal of having all toolchain configuration logic living in the same place, which facilities the work towards a runtime-retargetable GHC (see #19877). As of this commit, the runtime linker/compiler logic was moved to autoconf, but soon it, and the rest of the existing toolchain configuration logic, will live in the standalone ghc-toolchain program (see !9263) In particular, what used to be done at runtime is now as follows: * The flags -Wl,--no-as-needed for needed shared libs are configured into settings * The flag -fstack-check is configured into settings * The check for broken tables-next-to-code was outdated * We use the configured c compiler by default as the assembler program * We drop `asmOpts` because we already configure -Qunused-arguments flag into settings (see !10589) Fixes #23562 Co-author: Rodrigo Mesquita (@alt-romes) - - - - - 8b35e8ca by Ben Gamari at 2023-06-29T18:46:12-04:00 Define FFI_GO_CLOSURES The libffi shipped with Apple's XCode toolchain does not contain a definition of the FFI_GO_CLOSURES macro, despite containing references to said macro. Work around this by defining the macro, following the model of a similar workaround in OpenJDK [1]. [1] https://github.com/openjdk/jdk17u-dev/pull/741/files - - - - - d7ef1704 by Ben Gamari at 2023-06-29T18:46:12-04:00 base: Fix incorrect CPP guard This was guarded on `darwin_HOST_OS` instead of `defined(darwin_HOST_OS)`. - - - - - 7c7d1f66 by Ben Gamari at 2023-06-29T18:46:48-04:00 rts/Trace: Ensure that debugTrace arguments are used As debugTrace is a macro we must take care to ensure that the fact is clear to the compiler lest we see warnings. - - - - - cb92051e by Ben Gamari at 2023-06-29T18:46:48-04:00 rts: Various warnings fixes - - - - - dec81dd1 by Ben Gamari at 2023-06-29T18:46:48-04:00 hadrian: Ignore warnings in unix and semaphore-compat - - - - - d7f6448a by Matthew Pickering at 2023-06-30T12:38:43-04:00 hadrian: Fix dependencies of docs:* rule For the docs:* rule we need to actually build the package rather than just the haddocks for the dependent packages. Therefore we depend on the .conf files of the packages we are trying to build documentation for as well as the .haddock files. Fixes #23472 - - - - - cec90389 by sheaf at 2023-06-30T12:39:27-04:00 Add tests for #22106 Fixes #22106 - - - - - 083794b1 by Torsten Schmits at 2023-07-03T03:27:27-04:00 Add -fbreak-points to control breakpoint insertion Rather than statically enabling breakpoints only for the interpreter, this adds a new flag. Tracking ticket: #23057 MR: !10466 - - - - - fd8c5769 by Ben Gamari at 2023-07-03T03:28:04-04:00 rts: Ensure that pinned allocations respect block size Previously, it was possible for pinned, aligned allocation requests to allocate beyond the end of the pinned accumulator block. Specifically, we failed to account for the padding needed to achieve the requested alignment in the "large object" check. With large alignment requests, this can result in the allocator using the capability's pinned object accumulator block to service a request which is larger than `PINNED_EMPTY_SIZE`. To fix this we reorganize `allocatePinned` to consistently account for the alignment padding in all large object checks. This is a bit subtle as we must handle the case of a small allocation request filling the accumulator block, as well as large requests. Fixes #23400. - - - - - 98185d52 by Ben Gamari at 2023-07-03T03:28:05-04:00 testsuite: Add test for #23400 - - - - - 4aac0540 by Ben Gamari at 2023-07-03T03:28:42-04:00 ghc-heap: Support for BLOCKING_QUEUE closures - - - - - 03f941f4 by Ben Bellick at 2023-07-03T03:29:29-04:00 Add some structured diagnostics in Tc/Validity.hs This addresses the work of ticket #20118 Created the following constructors for TcRnMessage - TcRnInaccessibleCoAxBranch - TcRnPatersonCondFailure - - - - - 6074cc3c by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Add failing test case for #23492 - - - - - 356a2692 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Use generated src span for catch-all case of record selector functions This fixes #23492. The problem was that we used the real source span of the field declaration for the generated catch-all case in the selector function, in particular in the generated call to `recSelError`, which meant it was included in the HIE output. Using `generatedSrcSpan` instead means that it is not included. - - - - - 3efe7f39 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Introduce genLHsApp and genLHsLit helpers in GHC.Rename.Utils - - - - - dd782343 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Construct catch-all default case using helpers GHC.Rename.Utils concrete helpers instead of wrapGenSpan + HS AST constructors - - - - - 0e09c38e by Ryan Hendrickson at 2023-07-03T03:30:56-04:00 Add regression test for #23549 - - - - - 32741743 by Alexis King at 2023-07-03T03:31:36-04:00 perf tests: Increase default stack size for MultiLayerModules An unhelpfully small stack size appears to have been the real culprit behind the metric fluctuations in #19293. Debugging metric decreases triggered by !10729 helped to finally identify the problem. Metric Decrease: MultiLayerModules MultiLayerModulesTH_Make T13701 T14697 - - - - - 82ac6bf1 by Bryan Richter at 2023-07-03T03:32:15-04:00 Add missing void prototypes to rts functions See #23561. - - - - - 6078b429 by Ben Gamari at 2023-07-03T03:32:51-04:00 gitlab-ci: Refactor compilation of gen_ci Flakify and document it, making it far less sensitive to the build environment. - - - - - aa2db0ae by Ben Gamari at 2023-07-03T03:33:29-04:00 testsuite: Update documentation - - - - - 924a2362 by Gregory Gerasev at 2023-07-03T03:34:10-04:00 Better error for data deriving of type synonym/family. Closes #23522 - - - - - 4457da2a by Dave Barton at 2023-07-03T03:34:51-04:00 Fix some broken links and typos - - - - - de5830d0 by Ben Gamari at 2023-07-04T22:03:59-04:00 configure: Rip out Solaris dyld check Solaris 11 was released over a decade ago and, moreover, I doubt we have any Solaris users - - - - - 59c5fe1d by doyougnu at 2023-07-04T22:04:56-04:00 CI: add JS release and debug builds, regen CI jobs - - - - - 679bbc97 by Vladislav Zavialov at 2023-07-04T22:05:32-04:00 testsuite: Do not require CUSKs Numerous tests make use of CUSKs (complete user-supplied kinds), a legacy feature scheduled for deprecation. In order to proceed with the said deprecation, the tests have been updated to use SAKS instead (standalone kind signatures). This also allows us to remove the Haskell2010 language pragmas that were added in 115cd3c85a8 to work around the lack of CUSKs in GHC2021. - - - - - 945d3599 by Ben Gamari at 2023-07-04T22:06:08-04:00 gitlab: Drop backport-for-8.8 MR template Its usefulness has long passed. - - - - - 66c721d3 by Alan Zimmerman at 2023-07-04T22:06:44-04:00 EPA: Simplify GHC/Parser.y comb2 Use the HasLoc instance from Ast.hs to allow comb2 to work with anything with a SrcSpan This gets rid of the custom comb2A, comb2Al, comb2N functions, and removes various reLoc calls. - - - - - 2be99b7e by Matthew Pickering at 2023-07-04T22:07:21-04:00 Fix deprecation warning when deprecated identifier is from another module A stray 'Just' was being printed in the deprecation message. Fixes #23573 - - - - - 46c9bcd6 by Ben Gamari at 2023-07-04T22:07:58-04:00 rts: Don't rely on initializers for sigaction_t As noted in #23577, CentOS's ancient toolchain throws spurious missing-field-initializer warnings. - - - - - ec55035f by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Don't treat -Winline warnings as fatal Such warnings are highly dependent upon the toolchain, platform, and build configuration. It's simply too fragile to rely on these. - - - - - 3a09b789 by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Only pass -Wno-nonportable-include-path on Darwin This flag, which was introduced due to #17798, is only understood by Clang and consequently throws warnings on platforms using gcc. Sadly, there is no good way to treat such warnings as non-fatal with `-Werror` so for now we simply make this flag specific to platforms known to use Clang and case-insensitive filesystems (Darwin and Windows). See #23577. - - - - - 4af7eac2 by Mario Blažević at 2023-07-04T22:08:38-04:00 Fixed ticket #23571, TH.Ppr.pprLit hanging on large numeric literals - - - - - 2304c697 by Ben Gamari at 2023-07-04T22:09:15-04:00 compiler: Make OccSet opaque - - - - - cf735db8 by Andrei Borzenkov at 2023-07-04T22:09:51-04:00 Add Note about why we need forall in Code to be on the right - - - - - fb140f82 by Hécate Moonlight at 2023-07-04T22:10:34-04:00 Relax the constraint about the foreign function's calling convention of FinalizerPtr to capi as well as ccall. - - - - - 9ce44336 by meooow25 at 2023-07-05T11:42:37-04:00 Improve the situation with the stimes cycle Currently the Semigroup stimes cycle is resolved in GHC.Base by importing stimes implementations from a hs-boot file. Resolve the cycle using hs-boot files for required classes (Num, Integral) instead. Now stimes can be defined directly in GHC.Base, making inlining and specialization possible. This leads to some new boot files for `GHC.Num` and `GHC.Real`, the methods for those are only used to implement `stimes` so it doesn't appear that these boot files will introduce any new performance traps. Metric Decrease: T13386 T8095 Metric Increase: T13253 T13386 T18698a T18698b T19695 T8095 - - - - - 9edcb1fb by Jaro Reinders at 2023-07-05T11:43:24-04:00 Refactor Unique to be represented by Word64 In #22010 we established that Int was not always sufficient to store all the uniques we generate during compilation on 32-bit platforms. This commit addresses that problem by using Word64 instead of Int for uniques. The core of the change is in GHC.Core.Types.Unique and GHC.Core.Types.Unique.Supply. However, the representation of uniques is used in many other places, so those needed changes too. Additionally, the RTS has been extended with an atomic_inc64 operation. One major change from this commit is the introduction of the Word64Set and Word64Map data types. These are adapted versions of IntSet and IntMap from the containers package. These are planned to be upstreamed in the future. As a natural consequence of these changes, the compiler will be a bit slower and take more space on 32-bit platforms. Our CI tests indicate around a 5% residency increase. Metric Increase: CoOpt_Read CoOpt_Singletons LargeRecord ManyAlternatives ManyConstructors MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot RecordUpdPerf T10421 T10547 T12150 T12227 T12234 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T13386 T13719 T14683 T14697 T14766 T15164 T15703 T16577 T16875 T17516 T18140 T18223 T18282 T18304 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T3294 T4801 T5030 T5321FD T5321Fun T5631 T5642 T5837 T6048 T783 T8095 T9020 T9198 T9233 T9630 T9675 T9872a T9872b T9872b_defer T9872c T9872d T9961 TcPlugin_RewritePerf UniqLoop WWRec hard_hole_fits - - - - - 6b9db7d4 by Brandon Chinn at 2023-07-05T11:44:03-04:00 Fix docs for __GLASGOW_HASKELL_FULL_VERSION__ macro - - - - - 40f4ef7c by Torsten Schmits at 2023-07-05T18:06:19-04:00 Substitute free variables captured by breakpoints in SpecConstr Fixes #23267 - - - - - 2b55cb5f by sheaf at 2023-07-05T18:07:07-04:00 Reinstate untouchable variable error messages This extra bit of information was accidentally being discarded after a refactoring of the way we reported problems when unifying a type variable with another type. This patch rectifies that. - - - - - 53ed21c5 by Rodrigo Mesquita at 2023-07-05T18:07:47-04:00 configure: Drop Clang command from settings Due to 01542cb7227614a93508b97ecad5b16dddeb6486 we no longer use the `runClang` function, and no longer need to configure into settings the Clang command. We used to determine options at runtime to pass clang when it was used as an assembler, but now that we configure at configure time we no longer need to. - - - - - 6fdcf969 by Torsten Schmits at 2023-07-06T12:12:09-04:00 Filter out nontrivial substituted expressions in substTickish Fixes #23272 - - - - - 41968fd6 by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: testsuite: use req_c predicate instead of js_broken - - - - - 74a4dd2e by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: implement some file primitives (lstat,rmdir) (#22374) - Implement lstat and rmdir. - Implement base_c_s_is* functions (testing a file type) - Enable passing tests - - - - - 7e759914 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: cleanup utils (#23314) - Removed unused code - Don't export unused functions - Move toTypeList to Closure module - - - - - f617655c by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: rename VarType/Vt into JSRep - - - - - 19216ca5 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: remove custom PrimRep conversion (#23314) We use the usual conversion to PrimRep and then we convert these PrimReps to JSReps. - - - - - d3de8668 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: don't use isRuntimeRepKindedTy in JS FFI - - - - - 8d1b75cb by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Also updates ghcup-nightlies-0.0.7.yaml file Fixes #23600 - - - - - e524fa7f by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Use dynamically linked alpine bindists In theory these will work much better on alpine to allow people to build statically linked applications there. We don't need to distribute a statically linked application ourselves in order to allow that. Fixes #23602 - - - - - b9e7beb9 by Ben Gamari at 2023-07-07T11:32:22-04:00 Drop circle-ci-job.sh - - - - - 9955eead by Ben Gamari at 2023-07-07T11:32:22-04:00 testsuite: Allow preservation of unexpected output Here we introduce a new flag to the testsuite driver, --unexpected-output-dir=<dir>, which allows the user to ask the driver to preserve unexpected output from tests. The intent is for this to be used in CI to allow users to more easily fix unexpected platform-dependent output. - - - - - 48f80968 by Ben Gamari at 2023-07-07T11:32:22-04:00 gitlab-ci: Preserve unexpected output Here we enable use of the testsuite driver's `--unexpected-output-dir` flag by CI, preserving the result as an artifact for use by users. - - - - - 76983a0d by Matthew Pickering at 2023-07-07T11:32:58-04:00 driver: Fix -S with .cmm files There was an oversight in the driver which assumed that you would always produce a `.o` file when compiling a .cmm file. Fixes #23610 - - - - - 6df15e93 by Mike Pilgrem at 2023-07-07T11:33:40-04:00 Update Hadrian's stack.yaml - - - - - 1dff43cf by Ben Gamari at 2023-07-08T05:05:37-04:00 compiler: Rework ShowSome Previously the field used to filter the sub-declarations to show was rather ad-hoc and was only able to show at most one sub-declaration. - - - - - 8165404b by Ben Gamari at 2023-07-08T05:05:37-04:00 testsuite: Add test to catch changes in core libraries This adds testing infrastructure to ensure that changes in core libraries (e.g. `base` and `ghc-prim`) are caught in CI. - - - - - ec1c32e2 by Melanie Phoenix at 2023-07-08T05:06:14-04:00 Deprecate Data.List.NonEmpty.unzip - - - - - 5d2442b8 by Ben Gamari at 2023-07-08T05:06:51-04:00 Drop latent mentions of -split-objs Closes #21134. - - - - - a9bc20cb by Oleg Grenrus at 2023-07-08T05:07:31-04:00 Add warn_and_run test kind This is a compile_and_run variant which also captures the GHC's stderr. The warn_and_run name is best I can come up with, as compile_and_run is taken. This is useful specifically for testing warnings. We want to test that when warning triggers, and it's not a false positive, i.e. that the runtime behaviour is indeed "incorrect". As an example a single test is altered to use warn_and_run - - - - - c7026962 by Ben Gamari at 2023-07-08T05:08:11-04:00 configure: Don't use ld.gold on i386 ld.gold appears to produce invalid static constructor tables on i386. While ideally we would add an autoconf check to check for this brokenness, sadly such a check isn't easy to compose. Instead to summarily reject such linkers on i386. Somewhat hackily closes #23579. - - - - - 054261dd by Andrew Lelechenko at 2023-07-08T19:32:47-04:00 Add since annotations for Data.Foldable1 - - - - - 550af505 by Sylvain Henry at 2023-07-08T19:33:28-04:00 JS: support -this-unit-id for programs in the linker (#23613) - - - - - d284470a by Andrew Lelechenko at 2023-07-08T19:34:08-04:00 Bump text submodule - - - - - 8e11630e by jade at 2023-07-10T16:58:40-04:00 Add a hint to enable ExplicitNamespaces for type operator imports (Fixes/Enhances #20007) As suggested in #20007 and implemented in !8895, trying to import type operators will suggest a fix to use the 'type' keyword, without considering whether ExplicitNamespaces is enabled. This patch will query whether ExplicitNamespaces is enabled and add a hint to suggest enabling ExplicitNamespaces if it isn't enabled, alongside the suggestion of adding the 'type' keyword. - - - - - 61b1932e by sheaf at 2023-07-10T16:59:26-04:00 tyThingLocalGREs: include all DataCons for RecFlds The GREInfo for a record field should include the collection of all the data constructors of the parent TyCon that have this record field. This information was being incorrectly computed in the tyThingLocalGREs function for a DataCon, as we were not taking into account other DataCons with the same parent TyCon. Fixes #23546 - - - - - e6627cbd by Alan Zimmerman at 2023-07-10T17:00:05-04:00 EPA: Simplify GHC/Parser.y comb3 A follow up to !10743 - - - - - ee20da34 by Andrew Lelechenko at 2023-07-10T17:01:01-04:00 Document that compareByteArrays# is available since ghc-prim-0.5.2.0 - - - - - 4926af7b by Matthew Pickering at 2023-07-10T17:01:38-04:00 Revert "Bump text submodule" This reverts commit d284470a77042e6bc17bdb0ab0d740011196958a. This commit requires that we bootstrap with ghc-9.4, which we do not require until #23195 has been completed. Subsequently this has broken nighty jobs such as the rocky8 job which in turn has broken nightly releases. - - - - - d1c92bf3 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Fingerprint more code generation flags Previously our recompilation check was quite inconsistent in its coverage of non-optimisation code generation flags. Specifically, we failed to account for most flags that would affect the behavior of generated code in ways that might affect the result of a program's execution (e.g. `-feager-blackholing`, `-fstrict-dicts`) Closes #23369. - - - - - eb623149 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Record original thunk info tables on stack Here we introduce a new code generation option, `-forig-thunk-info`, which ensures that an `stg_orig_thunk_info` frame is pushed before every update frame. This can be invaluable when debugging thunk cycles and similar. See Note [Original thunk info table frames] for details. Closes #23255. - - - - - 4731f44e by Jaro Reinders at 2023-07-11T08:07:40-04:00 Fix wrong MIN_VERSION_GLASGOW_HASKELL macros I forgot to change these after rebasing. - - - - - dd38aca9 by Andreas Schwab at 2023-07-11T13:55:56+00:00 Hadrian: enable GHCi support on riscv64 - - - - - 09a5c6cc by Josh Meredith at 2023-07-12T11:25:13-04:00 JavaScript: support unicode code points > 2^16 in toJSString using String.fromCodePoint (#23628) - - - - - 29fbbd4e by Matthew Pickering at 2023-07-12T11:25:49-04:00 Remove references to make build system in mk/build.mk Fixes #23636 - - - - - 630e3026 by sheaf at 2023-07-12T11:26:43-04:00 Valid hole fits: don't panic on a Given The function GHC.Tc.Errors.validHoleFits would end up panicking when encountering a Given constraint. To fix this, it suffices to filter out the Givens before continuing. Fixes #22684 - - - - - c39f279b by Matthew Pickering at 2023-07-12T23:18:38-04:00 Use deb10 for i386 bindists deb9 is now EOL so it's time to upgrade the i386 bindist to use deb10 Fixes #23585 - - - - - bf9b9de0 by Krzysztof Gogolewski at 2023-07-12T23:19:15-04:00 Fix #23567, a specializer bug Found by Simon in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507834 The testcase isn't ideal because it doesn't detect the bug in master, unless doNotUnbox is removed as in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507692. But I have confirmed that with that modification, it fails before and passes afterwards. - - - - - 84c1a4a2 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 Comments - - - - - b2846cb5 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 updates to comments - - - - - 2af23f0e by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 changes - - - - - 6143838a by sheaf at 2023-07-13T08:02:17-04:00 Fix deprecation of record fields Commit 3f374399 inadvertently broke the deprecation/warning mechanism for record fields due to its introduction of record field namespaces. This patch ensures that, when a top-level deprecation is applied to an identifier, it applies to all the record fields as well. This is achieved by refactoring GHC.Rename.Env.lookupLocalTcNames, and GHC.Rename.Env.lookupBindGroupOcc, to not look up a fixed number of NameSpaces but to look up all NameSpaces and filter out the irrelevant ones. - - - - - 6fd8f566 by sheaf at 2023-07-13T08:02:17-04:00 Introduce greInfo, greParent These are simple helper functions that wrap the internal field names gre_info, gre_par. - - - - - 7f0a86ed by sheaf at 2023-07-13T08:02:17-04:00 Refactor lookupGRE_... functions This commit consolidates all the logic for looking up something in the Global Reader Environment into the single function lookupGRE. This allows us to declaratively specify all the different modes of looking up in the GlobalRdrEnv, and avoids manually passing around filtering functions as was the case in e.g. the function GHC.Rename.Env.lookupSubBndrOcc_helper. ------------------------- Metric Decrease: T8095 ------------------------- ------------------------- Metric Increase: T8095 ------------------------- - - - - - 5e951395 by Rodrigo Mesquita at 2023-07-13T08:02:54-04:00 configure: Drop DllWrap command We used to configure into settings a DllWrap command for windows builds and distributions, however, we no longer do, and dllwrap is effectively unused. This simplification is motivated in part by the larger toolchain-selection project (#19877, !9263) - - - - - e10556b6 by Teo Camarasu at 2023-07-14T16:28:46-04:00 base: fix haddock syntax in GHC.Profiling - - - - - 0f3fda81 by Matthew Pickering at 2023-07-14T16:29:23-04:00 Revert "CI: add JS release and debug builds, regen CI jobs" This reverts commit 59c5fe1d4b624423b1c37891710f2757bb58d6af. This commit added two duplicate jobs on all validate pipelines, so we are reverting for now whilst we work out what the best way forward is. Ticket #23618 - - - - - 54bca324 by Alan Zimmerman at 2023-07-15T03:23:26-04:00 EPA: Simplify GHC/Parser.y sLL Follow up to !10743 - - - - - c8863828 by sheaf at 2023-07-15T03:24:06-04:00 Configure: canonicalise PythonCmd on Windows This change makes PythonCmd resolve to a canonical absolute path on Windows, which prevents HLS getting confused (now that we have a build-time dependency on python). fixes #23652 - - - - - ca1e636a by Rodrigo Mesquita at 2023-07-15T03:24:42-04:00 Improve Note [Binder-swap during float-out] - - - - - cf86f3ec by Matthew Craven at 2023-07-16T01:42:09+02:00 Equality of forall-types is visibility aware This patch finally (I hope) nails the question of whether (forall a. ty) and (forall a -> ty) are `eqType`: they aren't! There is a long discussion in #22762, plus useful Notes: * Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare * Note [Comparing visiblities] in GHC.Core.TyCo.Compare * Note [ForAllCo] in GHC.Core.TyCo.Rep It also establishes a helpful new invariant for ForAllCo, and ForAllTy, when the bound variable is a CoVar:in that case the visibility must be coreTyLamForAllTyFlag. All this is well documented in revised Notes. - - - - - 7f13acbf by Vladislav Zavialov at 2023-07-16T01:56:27-04:00 List and Tuple<n>: update documentation Add the missing changelog.md entries and @since-annotations. - - - - - 2afbddb0 by Andrei Borzenkov at 2023-07-16T10:21:24+04:00 Type patterns (#22478, #18986) Improved name resolution and type checking of type patterns in constructors: 1. HsTyPat: a new dedicated data type that represents type patterns in HsConPatDetails instead of reusing HsPatSigType 2. rnHsTyPat: a new function that renames a type pattern and collects its binders into three groups: - explicitly bound type variables, excluding locally bound variables - implicitly bound type variables from kind signatures (only if ScopedTypeVariables are enabled) - named wildcards (only from kind signatures) 2a. rnHsPatSigTypeBindingVars: removed in favour of rnHsTyPat 2b. rnImplcitTvBndrs: removed because no longer needed 3. collect_pat: updated to collect type variable binders from type patterns (this means that types and terms use the same infrastructure to detect conflicting bindings, unused variables and name shadowing) 3a. CollVarTyVarBinders: a new CollectFlag constructor that enables collection of type variables 4. tcHsTyPat: a new function that typechecks type patterns, capable of handling polymorphic kinds. See Note [Type patterns: binders and unifiers] Examples of code that is now accepted: f = \(P @a) -> \(P @a) -> ... -- triggers -Wname-shadowing g :: forall a. Proxy a -> ... g (P @a) = ... -- also triggers -Wname-shadowing h (P @($(TH.varT (TH.mkName "t")))) = ... -- t is bound at splice time j (P @(a :: (x,x))) = ... -- (x,x) is no longer rejected data T where MkT :: forall (f :: forall k. k -> Type). f Int -> f Maybe -> T k :: T -> () k (MkT @f (x :: f Int) (y :: f Maybe)) = () -- f :: forall k. k -> Type Examples of code that is rejected with better error messages: f (Left @a @a _) = ... -- new message: -- • Conflicting definitions for ‘a’ -- Bound at: Test.hs:1:11 -- Test.hs:1:14 Examples of code that is now rejected: {-# OPTIONS_GHC -Werror=unused-matches #-} f (P @a) = () -- Defined but not used: type variable ‘a’ - - - - - eb1a6ab1 by sheaf at 2023-07-16T09:20:45-04:00 Don't use substTyUnchecked in newMetaTyVar There were some comments that explained that we needed to use an unchecked substitution function because of issue #12931, but that has since been fixed, so we should be able to use substTy instead now. - - - - - c7bbad9a by sheaf at 2023-07-17T02:48:19-04:00 rnImports: var shouldn't import NoFldSelectors In an import declaration such as import M ( var ) the import of the variable "var" should **not** bring into scope record fields named "var" which are defined with NoFieldSelectors. Doing so can cause spurious "unused import" warnings, as reported in ticket #23557. Fixes #23557 - - - - - 1af2e773 by sheaf at 2023-07-17T02:48:19-04:00 Suggest similar names in imports This commit adds similar name suggestions when importing. For example module A where { spelling = 'o' } module B where { import B ( speling ) } will give rise to the error message: Module ‘A’ does not export ‘speling’. Suggested fix: Perhaps use ‘spelling’ This also provides hints when users try to import record fields defined with NoFieldSelectors. - - - - - 654fdb98 by Alan Zimmerman at 2023-07-17T02:48:55-04:00 EPA: Store leading AnnSemi for decllist in al_rest This simplifies the markAnnListA implementation in ExactPrint - - - - - 22565506 by sheaf at 2023-07-17T21:12:59-04:00 base: add COMPLETE pragma to BufferCodec PatSyn This implements CLC proposal #178, rectifying an oversight in the implementation of CLC proposal #134 which could lead to spurious pattern match warnings. https://github.com/haskell/core-libraries-committee/issues/178 https://github.com/haskell/core-libraries-committee/issues/134 - - - - - 860f6269 by sheaf at 2023-07-17T21:13:00-04:00 exactprint: silence incomplete record update warnings - - - - - df706de3 by sheaf at 2023-07-17T21:13:00-04:00 Re-instate -Wincomplete-record-updates Commit e74fc066 refactored the handling of record updates to use the HsExpanded mechanism. This meant that the pattern matching inherent to a record update was considered to be "generated code", and thus we stopped emitting "incomplete record update" warnings entirely. This commit changes the "data Origin = Source | Generated" datatype, adding a field to the Generated constructor to indicate whether we still want to perform pattern-match checking. We also have to do a bit of plumbing with HsCase, to record that the HsCase arose from an HsExpansion of a RecUpd, so that the error message continues to mention record updates as opposed to a generic "incomplete pattern matches in case" error. Finally, this patch also changes the way we handle inaccessible code warnings. Commit e74fc066 was also a regression in this regard, as we were emitting "inaccessible code" warnings for case statements spuriously generated when desugaring a record update (remember: the desugaring mechanism happens before typechecking; it thus can't take into account e.g. GADT information in order to decide which constructors to include in the RHS of the desugaring of the record update). We fix this by changing the mechanism through which we disable inaccessible code warnings: we now check whether we are in generated code in GHC.Tc.Utils.TcMType.newImplication in order to determine whether to emit inaccessible code warnings. Fixes #23520 Updates haddock submodule, to avoid incomplete record update warnings - - - - - 1d05971e by sheaf at 2023-07-17T21:13:00-04:00 Propagate long-distance information in do-notation The preceding commit re-enabled pattern-match checking inside record updates. This revealed that #21360 was in fact NOT fixed by e74fc066. This commit makes sure we correctly propagate long-distance information in do blocks, e.g. in ```haskell data T = A { fld :: Int } | B f :: T -> Maybe T f r = do a at A{} <- Just r Just $ case a of { A _ -> A 9 } ``` we need to propagate the fact that "a" is headed by the constructor "A" to see that the case expression "case a of { A _ -> A 9 }" cannot fail. Fixes #21360 - - - - - bea0e323 by sheaf at 2023-07-17T21:13:00-04:00 Skip PMC for boring patterns Some patterns introduce no new information to the pattern-match checker (such as plain variable or wildcard patterns). We can thus skip doing any pattern-match checking on them when the sole purpose for doing so was introducing new long-distance information. See Note [Boring patterns] in GHC.Hs.Pat. Doing this avoids regressing in performance now that we do additional pattern-match checking inside do notation. - - - - - ddcdd88c by Rodrigo Mesquita at 2023-07-17T21:13:36-04:00 Split GHC.Platform.ArchOS from ghc-boot into ghc-platform Split off the `GHC.Platform.ArchOS` module from the `ghc-boot` package into this reinstallable standalone package which abides by the PVP, in part motivated by the ongoing work on `ghc-toolchain` towards runtime retargetability. - - - - - b55a8ea7 by Sylvain Henry at 2023-07-17T21:14:27-04:00 JS: better implementation for plusWord64 (#23597) - - - - - 889c2bbb by sheaf at 2023-07-18T06:37:32-04:00 Do primop rep-poly checks when instantiating This patch changes how we perform representation-polymorphism checking for primops (and other wired-in Ids such as coerce). When instantiating the primop, we check whether each type variable is required to instantiated to a concrete type, and if so we create a new concrete metavariable (a ConcreteTv) instead of a simple MetaTv. (A little subtlety is the need to apply the substitution obtained from instantiating to the ConcreteTvOrigins, see Note [substConcreteTvOrigin] in GHC.Tc.Utils.TcMType.) This allows us to prevent representation-polymorphism in non-argument position, as that is required for some of these primops. We can also remove the logic in tcRemainingValArgs, except for the part concerning representation-polymorphic unlifted newtypes. The function has been renamed rejectRepPolyNewtypes; all it does now is reject unsaturated occurrences of representation-polymorphic newtype constructors when the representation of its argument isn't a concrete RuntimeRep (i.e. still a PHASE 1 FixedRuntimeRep check). The Note [Eta-expanding rep-poly unlifted newtypes] in GHC.Tc.Gen.Head gives more explanation about a possible path to PHASE 2, which would be in line with the treatment for primops taken in this patch. We also update the Core Lint check to handle this new framework. This means Core Lint now checks representation-polymorphism in continuation position like needed for catch#. Fixes #21906 ------------------------- Metric Increase: LargeRecord ------------------------- - - - - - 00648e5d by Krzysztof Gogolewski at 2023-07-18T06:38:10-04:00 Core Lint: distinguish let and letrec in locations Lint messages were saying "in the body of letrec" even for non-recursive let. I've also renamed BodyOfLetRec to BodyOfLet in stg, since there's no separate letrec. - - - - - 787bae96 by Krzysztof Gogolewski at 2023-07-18T06:38:50-04:00 Use extended literals when deriving Show This implements GHC proposal https://github.com/ghc-proposals/ghc-proposals/pull/596 Also add support for Int64# and Word64#; see testcase ShowPrim. - - - - - 257f1567 by Jaro Reinders at 2023-07-18T06:39:29-04:00 Add StgFromCore and StgCodeGen linting - - - - - 34d08a20 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Strictness - - - - - c5deaa27 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Don't repeatedly construct UniqSets - - - - - b947250b by Ben Gamari at 2023-07-19T03:33:22-04:00 compiler/Types: Ensure that fromList-type operations can fuse In #20740 I noticed that mkUniqSet does not fuse. In practice, allowing it to do so makes a considerable difference in allocations due to the backend. Metric Decrease: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 6c88c2ba by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 Codegen: Implement MO_S_MulMayOflo for W16 - - - - - 5f1154e0 by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: MO_S_MulMayOflo better error message for rep > W64 It's useful to see which value made the pattern match fail. (If it ever occurs.) - - - - - e8c9a95f by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: Implement MO_S_MulMayOflo for W8 This case wasn't handled before. But, the test-primops test suite showed that it actually might appear. - - - - - a36f9dc9 by Sven Tennie at 2023-07-19T03:33:59-04:00 Add test for %mulmayoflo primop The test expects a perfect implementation with no false positives. - - - - - 38a36248 by Matthew Pickering at 2023-07-19T03:34:36-04:00 lint-ci-config: Generate jobs-metadata.json We also now save the jobs-metadata.json and jobs.yaml file as artifacts as: * It might be useful for someone who is modifying CI to copy jobs.yaml if they are having trouble regenerating locally. * jobs-metadata.json is very useful for downstream pipelines to work out the right job to download. Fixes #23654 - - - - - 1535a671 by Vladislav Zavialov at 2023-07-19T03:35:12-04:00 Initialize 9.10.1-notes.rst Create new release notes for the next GHC release (GHC 9.10) - - - - - 3bd4d5b5 by sheaf at 2023-07-19T03:35:53-04:00 Prioritise Parent when looking up class sub-binder When we look up children GlobalRdrElts of a given Parent, we sometimes would rather prioritise those GlobalRdrElts which have the right Parent, and sometimes prioritise those that have the right NameSpace: - in export lists, we should prioritise NameSpace - for class/instance binders, we should prioritise Parent See Note [childGREPriority] in GHC.Types.Name.Reader. fixes #23664 - - - - - 9c8fdda3 by Alan Zimmerman at 2023-07-19T03:36:29-04:00 EPA: Improve annotation management in getMonoBind Ensure the LHsDecl for a FunBind has the correct leading comments and trailing annotations. See the added note for details. - - - - - ff884b77 by Matthew Pickering at 2023-07-19T11:42:02+01:00 Remove unused files in .gitlab These were left over after 6078b429 - - - - - 29ef590c by Matthew Pickering at 2023-07-19T11:42:52+01:00 gen_ci: Add hie.yaml file This allows you to load `gen_ci.hs` into HLS, and now it is a huge module, that is quite useful. - - - - - 808b55cf by Matthew Pickering at 2023-07-19T12:24:41+01:00 ci: Make "fast-ci" the default validate configuration We are trying out a lighter weight validation pipeline where by default we just test on 5 platforms: * x86_64-deb10-slow-validate * windows * x86_64-fedora33-release * aarch64-darwin * aarch64-linux-deb10 In order to enable the "full" validation pipeline you can apply the `full-ci` label which will enable all the validation pipelines. All the validation jobs are still run on a marge batch. The goal is to reduce the overall CI capacity so that pipelines start faster for MRs and marge bot batches are faster. Fixes #23694 - - - - - 0b23db03 by Alan Zimmerman at 2023-07-20T05:28:47-04:00 EPA: Simplify GHC/Parser.y sL1 This is the next patch in a series simplifying location management in GHC/Parser.y This one simplifies sL1, to use the HasLoc instances introduced in !10743 (closed) - - - - - 3ece9856 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Explicitly set flags of text sections on Windows The binutils documentation (for COFF) claims, > If no flags are specified, the default flags depend upon the section > name. If the section name is not recognized, the default will be for the > section to be loaded and writable. We previously assumed that this would do the right thing for split sections (e.g. a section named `.text$foo` would be correctly inferred to be a text section). However, we have observed that this is not the case (at least under the clang toolchain used on Windows): when split-sections is enabled, text sections are treated by the assembler as data (matching the "default" behavior specified by the documentation). Avoid this by setting section flags explicitly. This should fix split sections on Windows. Fixes #22834. - - - - - db7f7240 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Set explicit section types on all platforms - - - - - b444c16f by Finley McIlwaine at 2023-07-21T07:31:28-04:00 Insert documentation into parsed signature modules Causes haddock comments in signature modules to be properly inserted into the AST (just as they are for regular modules) if the `-haddock` flag is given. Also adds a test that compares `-ddump-parsed-ast` output for a signature module to prevent further regressions. Fixes #23315 - - - - - c30cea53 by Ben Gamari at 2023-07-21T23:23:49-04:00 primops: Introduce unsafeThawByteArray# This addresses an odd asymmetry in the ByteArray# primops, which previously provided unsafeFreezeByteArray# but no corresponding thaw operation. Closes #22710 - - - - - 87f9bd47 by Ben Gamari at 2023-07-21T23:23:49-04:00 testsuite: Elaborate in interface stability README This discussion didn't make it into the original MR. - - - - - e4350b41 by Matthew Pickering at 2023-07-21T23:24:25-04:00 Allow users to override non-essential haddock options in a Flavour We now supply the non-essential options to haddock using the `extraArgs` field, which can be specified in a Flavour so that if an advanced user wants to change how documentation is generated then they can use something other than the `defaultHaddockExtraArgs`. This does have the potential to regress some packaging if a user has overridden `extraArgs` themselves, because now they also need to add the haddock options to extraArgs. This can easily be done by appending `defaultHaddockExtraArgs` to their extraArgs invocation but someone might not notice this behaviour has changed. In any case, I think passing the non-essential options in this manner is the right thing to do and matches what we do for the "ghc" builder, which by default doesn't pass any optmisation levels, and would likewise be very bad if someone didn't pass suitable `-O` levels for builds. Fixes #23625 - - - - - fc186b0c by Ilias Tsitsimpis at 2023-07-21T23:25:03-04:00 ghc-prim: Link against libatomic Commit b4d39adbb58 made 'hs_cmpxchg64()' available to all architectures. Unfortunately this made GHC to fail to build on armel, since armel needs libatomic to support atomic operations on 64-bit word sizes. Configure libraries/ghc-prim/ghc-prim.cabal to link against libatomic, the same way as we do in rts/rts.cabal. - - - - - 4f5538a8 by Matthew Pickering at 2023-07-21T23:25:39-04:00 simplifier: Correct InScopeSet in rule matching The in-scope set passedto the `exprIsLambda_maybe` call lacked all the in-scope binders. @simonpj suggests this fix where we augment the in-scope set with the free variables of expression which fixes this failure mode in quite a direct way. Fixes #23630 - - - - - 5ad8d597 by Krzysztof Gogolewski at 2023-07-21T23:26:17-04:00 Add a test for #23413 It was fixed by commit e1590ddc661d6: Add the SolverStage monad. - - - - - 7e05f6df by sheaf at 2023-07-21T23:26:56-04:00 Finish migration of diagnostics in GHC.Tc.Validity This patch finishes migrating the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It also refactors the error message datatypes for class and family instances, to common them up under a single datatype as much as possible. - - - - - 4876fddc by Matthew Pickering at 2023-07-21T23:27:33-04:00 ci: Enable some more jobs to run in a marge batch In !10907 I made the majority of jobs not run on a validate pipeline but then forgot to renable a select few jobs on the marge batch MR. - - - - - 026991d7 by Jens Petersen at 2023-07-21T23:28:13-04:00 user_guide/flags.py: python-3.12 no longer includes distutils packaging.version seems able to handle this fine - - - - - b91bbc2b by Matthew Pickering at 2023-07-21T23:28:50-04:00 ci: Mention ~full-ci label in MR template We mention that if you need a full validation pipeline then you can apply the ~full-ci label to your MR in order to test against the full validation pipeline (like we do for marge). - - - - - 42b05e9b by sheaf at 2023-07-22T12:36:00-04:00 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 - - - - - a72015d6 by sheaf at 2023-07-22T12:36:01-04:00 Mark plugins-external as broken on Windows This test is broken on Windows, so we explicitly mark it as such now that we stop skipping plugin tests on Windows. - - - - - cb9c93d7 by sheaf at 2023-07-22T12:36:01-04:00 Stop marking plugin tests as fragile on Windows Now that b2bb3e62 has landed we are in a better situation with regards to plugins on Windows, allowing us to unmark many plugin tests as fragile. Fixes #16405 - - - - - a7349217 by Krzysztof Gogolewski at 2023-07-22T12:36:37-04:00 Misc cleanup - Remove unused RDR names - Fix typos in comments - Deriving: simplify boxConTbl and remove unused litConTbl - chmod -x GHC/Exts.hs, this seems accidental - - - - - 33b6850a by Vladislav Zavialov at 2023-07-23T10:27:37-04:00 Visible forall in types of terms: Part 1 (#22326) This patch implements part 1 of GHC Proposal #281, introducing explicit `type` patterns and `type` arguments. Summary of the changes: 1. New extension flag: RequiredTypeArguments 2. New user-facing syntax: `type p` patterns (represented by EmbTyPat) `type e` expressions (represented by HsEmbTy) 3. Functions with required type arguments (visible forall) can now be defined and applied: idv :: forall a -> a -> a -- signature (relevant change: checkVdqOK in GHC/Tc/Validity.hs) idv (type a) (x :: a) = x -- definition (relevant change: tcPats in GHC/Tc/Gen/Pat.hs) x = idv (type Int) 42 -- usage (relevant change: tcInstFun in GHC/Tc/Gen/App.hs) 4. template-haskell support: TH.TypeE corresponds to HsEmbTy TH.TypeP corresponds to EmbTyPat 5. Test cases and a new User's Guide section Changes *not* included here are the t2t (term-to-type) transformation and term variable capture; those belong to part 2. - - - - - 73b5c7ce by sheaf at 2023-07-23T10:28:18-04:00 Add test for #22424 This is a simple Template Haskell test in which we refer to record selectors by their exact Names, in two different ways. Fixes #22424 - - - - - 83cbc672 by Ben Gamari at 2023-07-24T07:40:49+00:00 ghc-toolchain: Initial commit - - - - - 31dcd26c by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 ghc-toolchain: Toolchain Selection This commit integrates ghc-toolchain, the brand new way of configuring toolchains for GHC, with the Hadrian build system, with configure, and extends and improves the first iteration of ghc-toolchain. The general overview is * We introduce a program invoked `ghc-toolchain --triple=...` which, when run, produces a file with a `Target`. A `GHC.Toolchain.Target.Target` describes the properties of a target and the toolchain (executables and configured flags) to produce code for that target * Hadrian was modified to read Target files, and will both * Invoke the toolchain configured in the Target file as needed * Produce a `settings` file for GHC based on the Target file for that stage * `./configure` will invoke ghc-toolchain to generate target files, but it will also generate target files based on the flags configure itself configured (through `.in` files that are substituted) * By default, the Targets generated by configure are still (for now) the ones used by Hadrian * But we additionally validate the Target files generated by ghc-toolchain against the ones generated by configure, to get a head start on catching configuration bugs before we transition completely. * When we make that transition, we will want to drop a lot of the toolchain configuration logic from configure, but keep it otherwise. * For each compiler stage we should have 1 target file (up to a stage compiler we can't run in our machine) * We just have a HOST target file, which we use as the target for stage0 * And a TARGET target file, which we use for stage1 (and later stages, if not cross compiling) * Note there is no BUILD target file, because we only support cross compilation where BUILD=HOST * (for more details on cross-compilation see discussion on !9263) See also * Note [How we configure the bundled windows toolchain] * Note [ghc-toolchain consistency checking] * Note [ghc-toolchain overview] Ticket: #19877 MR: !9263 - - - - - a732b6d3 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Add flag to enable/disable ghc-toolchain based configurations This flag is disabled by default, and we'll use the configure-generated-toolchains by default until we remove the toolchain configuration logic from configure. - - - - - 61eea240 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Split ghc-toolchain executable to new packge In light of #23690, we split the ghc-toolchain executable out of the library package to be able to ship it in the bindist using Hadrian. Ideally, we eventually revert this commit. - - - - - 38e795ff by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Ship ghc-toolchain in the bindist Add the ghc-toolchain binary to the binary distribution we ship to users, and teach the bindist configure to use the existing ghc-toolchain. - - - - - 32cae784 by Matthew Craven at 2023-07-24T16:48:24-04:00 Kill off gen_bytearray_addr_access_ops.py The relevant primop descriptions are now generated directly by genprimopcode. This makes progress toward fixing #23490, but it is not a complete fix since there is more than one way in which cabal-reinstall (hadrian/build build-cabal) is broken. - - - - - 02e6a6ce by Matthew Pickering at 2023-07-24T16:49:00-04:00 compiler: Remove unused `containers.h` include Fixes #23712 - - - - - 822ef66b by Matthew Pickering at 2023-07-25T08:44:50-04:00 Fix pretty printing of WARNING pragmas There is still something quite unsavoury going on with WARNING pragma printing because the printing relies on the fact that for decl deprecations the SourceText of WarningTxt is empty. However, I let that lion sleep and just fixed things directly. Fixes #23465 - - - - - e7b38ede by Matthew Pickering at 2023-07-25T08:45:28-04:00 ci-images: Bump to commit which has 9.6 image The test-bootstrap job has been failing for 9.6 because we accidentally used a non-master commit. - - - - - bb408936 by Matthew Pickering at 2023-07-25T08:45:28-04:00 Update bootstrap plans for 9.6.2 and 9.4.5 - - - - - 355e1792 by Alan Zimmerman at 2023-07-26T10:17:32-04:00 EPA: Simplify GHC/Parser.y comb4/comb5 Use the HasLoc instance from Ast.hs to allow comb4/comb5 to work with anything with a SrcSpan Also get rid of some more now unnecessary reLoc calls. - - - - - 9393df83 by Gavin Zhao at 2023-07-26T10:18:16-04:00 compiler: make -ddump-asm work with wasm backend NCG Fixes #23503. Now the `-ddump-asm` flag is respected in the wasm backend NCG, so developers can directly view the generated ASM instead of needing to pass `-S` or `-keep-tmp-files` and manually find & open the assembly file. Ideally, we should be able to output the assembly files in smaller chunks like in other NCG backends. This would also make dumping assembly stats easier. However, this would require a large refactoring, so for short-term debugging purposes I think the current approach works fine. Signed-off-by: Gavin Zhao <git at gzgz.dev> - - - - - 79463036 by Krzysztof Gogolewski at 2023-07-26T10:18:54-04:00 llvm: Restore accidentally deleted code in 0fc5cb97 Fixes #23711 - - - - - 20db7e26 by Rodrigo Mesquita at 2023-07-26T10:19:33-04:00 configure: Default missing options to False when preparing ghc-toolchain Targets This commit fixes building ghc with 9.2 as the boostrap compiler. The ghc-toolchain patch assumed all _STAGE0 options were available, and forgot to account for this missing information in 9.2. Ghc 9.2 does not have in settings whether ar supports -l, hence can't report it with --info (unliked 9.4 upwards). The fix is to default the missing information (we default "ar supports -l" and other missing options to False) - - - - - fac9e84e by Naïm Favier at 2023-07-26T10:20:16-04:00 docs: Fix typo - - - - - 503fd647 by Bartłomiej Cieślar at 2023-07-26T17:23:10-04:00 This MR is an implementation of the proposal #516. It adds a warning -Wincomplete-record-selectors for usages of a record field access function (either a record selector or getField @"rec"), while trying to silence the warning whenever it can be sure that a constructor without the record field would not be invoked (which would otherwise cause the program to fail). For example: data T = T1 | T2 {x :: Bool} f a = x a -- this would throw an error g T1 = True g a = x a -- this would not throw an error h :: HasField "x" r Bool => r -> Bool h = getField @"x" j :: T -> Bool j = h -- this would throw an error because of the `HasField` -- constraint being solved See the tests DsIncompleteRecSel* and TcIncompleteRecSel for more examples of the warning. See Note [Detecting incomplete record selectors] in GHC.HsToCore.Expr for implementation details - - - - - af6fdf42 by Arnaud Spiwack at 2023-07-26T17:23:52-04:00 Fix user-facing label in MR template - - - - - 5d45b92a by Matthew Pickering at 2023-07-27T05:46:46-04:00 ci: Test bootstrapping configurations with full-ci and on marge batches There have been two incidents recently where bootstrapping has been broken by removing support for building with 9.2.*. The process for bumping the minimum required version starts with bumping the configure version and then other CI jobs such as the bootstrap jobs have to be updated. We must not silently bump the minimum required version. Now we are running a slimmed down validate pipeline it seems worthwile to test these bootstrap configurations in the full-ci pipeline. - - - - - 25d4fee7 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Remove ghc-9_2_* plans We are anticipating shortly making it necessary to use ghc-9.4 to boot the compiler. - - - - - 2f66da16 by Matthew Pickering at 2023-07-27T05:46:46-04:00 Update bootstrap plans for ghc-platform and ghc-toolchain dependencies Fixes #23735 - - - - - c8c6eab1 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Disable -selftest flag from bootstrap plans This saves on building one dependency (QuickCheck) which is unecessary for bootstrapping. - - - - - a80ca086 by Andrew Lelechenko at 2023-07-27T05:47:26-04:00 Link reference paper and package from System.Mem.{StableName,Weak} - - - - - a5319358 by David Knothe at 2023-07-28T13:13:10-04:00 Update Match Datatype EquationInfo currently contains a list of the equation's patterns together with a CoreExpr that is to be evaluated after a successful match on this equation. All the match-functions only operate on the first pattern of an equation - after successfully matching it, match is called recursively on the tail of the pattern list. We can express this more clearly and make the code a little more elegant by updating the datatype of EquationInfo as follows: data EquationInfo = EqnMatch { eqn_pat = Pat GhcTc, eqn_rest = EquationInfo } | EqnDone { eqn_rhs = MatchResult CoreExpr } An EquationInfo now explicitly exposes its first pattern which most functions operate on, and exposes the equation that remains after processing the first pattern. An EqnDone signifies an empty equation where the CoreExpr can now be evaluated. - - - - - 86ad1af9 by David Binder at 2023-07-28T13:13:53-04:00 Improve documentation for Data.Fixed - - - - - f8fa1d08 by Ben Gamari at 2023-07-28T13:14:31-04:00 ghc-prim: Use C11 atomics Previously `ghc-prim`'s atomic wrappers used the legacy `__sync_*` family of C builtins. Here we refactor these to rather use the appropriate C11 atomic equivalents, allowing us to be more explicit about the expected ordering semantics. - - - - - 0bfc8908 by Finley McIlwaine at 2023-07-28T18:46:26-04:00 Include -haddock in DynFlags fingerprint The -haddock flag determines whether or not the resulting .hi files contain haddock documentation strings. If the existing .hi files do not contain haddock documentation strings and the user requests them, we should recompile. - - - - - 40425c50 by Andreas Klebinger at 2023-07-28T18:47:02-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - e9a0fa3f by Andrew Lelechenko at 2023-07-28T18:47:42-04:00 Bump filepath submodule to 1.4.100.4 Resolves #23741 Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T12234 T12425 T13035 T13701 T13719 T16875 T18304 T18698a T18698b T21839c T9198 TcPlugin_RewritePerf hard_hole_fits Metric decrease on Windows can be probably attributed to https://github.com/haskell/filepath/pull/183 - - - - - ee93edfd by Andrew Lelechenko at 2023-07-28T18:48:21-04:00 Add since pragmas to GHC.IO.Handle.FD - - - - - d0369802 by Simon Peyton Jones at 2023-07-30T09:24:48+01:00 Make the occurrence analyser smarter about join points This MR addresses #22404. There is a big Note Note [Occurrence analysis for join points] that explains it all. Significant changes * New field occ_join_points in OccEnv * The NonRec case of occAnalBind splits into two cases: one for existing join points (which does the special magic for Note [Occurrence analysis for join points], and one for other bindings. * mkOneOcc adds in info from occ_join_points. * All "bring into scope" activity is centralised in the new function `addInScope`. * I made a local data type LocalOcc for use inside the occurrence analyser It is like OccInfo, but lacks IAmDead and IAmALoopBreaker, which in turn makes computationns over it simpler and more efficient. * I found quite a bit of allocation in GHC.Core.Rules.getRules so I optimised it a bit. More minor changes * I found I was using (Maybe Arity) a lot, so I defined a new data type JoinPointHood and used it everwhere. This touches a lot of non-occ-anal files, but it makes everything more perspicuous. * Renamed data constructor WithUsageDetails to WUD, and WithTailUsageDetails to WTUD This also fixes #21128, on the way. --------- Compiler perf ----------- I spent quite a time on performance tuning, so even though it does more than before, the occurrence analyser runs slightly faster on average. Here are the compile-time allocation changes over 0.5% CoOpt_Read(normal) ghc/alloc 766,025,520 754,561,992 -1.5% CoOpt_Singletons(normal) ghc/alloc 759,436,840 762,925,512 +0.5% LargeRecord(normal) ghc/alloc 1,814,482,440 1,799,530,456 -0.8% PmSeriesT(normal) ghc/alloc 68,159,272 67,519,720 -0.9% T10858(normal) ghc/alloc 120,805,224 118,746,968 -1.7% T11374(normal) ghc/alloc 164,901,104 164,070,624 -0.5% T11545(normal) ghc/alloc 79,851,808 78,964,704 -1.1% T12150(optasm) ghc/alloc 73,903,664 71,237,544 -3.6% GOOD T12227(normal) ghc/alloc 333,663,200 331,625,864 -0.6% T12234(optasm) ghc/alloc 52,583,224 52,340,344 -0.5% T12425(optasm) ghc/alloc 81,943,216 81,566,720 -0.5% T13056(optasm) ghc/alloc 294,517,928 289,642,512 -1.7% T13253-spj(normal) ghc/alloc 118,271,264 59,859,040 -49.4% GOOD T15164(normal) ghc/alloc 1,102,630,352 1,091,841,296 -1.0% T15304(normal) ghc/alloc 1,196,084,000 1,166,733,000 -2.5% T15630(normal) ghc/alloc 148,729,632 147,261,064 -1.0% T15703(normal) ghc/alloc 379,366,664 377,600,008 -0.5% T16875(normal) ghc/alloc 32,907,120 32,670,976 -0.7% T17516(normal) ghc/alloc 1,658,001,888 1,627,863,848 -1.8% T17836(normal) ghc/alloc 395,329,400 393,080,248 -0.6% T18140(normal) ghc/alloc 71,968,824 73,243,040 +1.8% T18223(normal) ghc/alloc 456,852,568 453,059,088 -0.8% T18282(normal) ghc/alloc 129,105,576 131,397,064 +1.8% T18304(normal) ghc/alloc 71,311,712 70,722,720 -0.8% T18698a(normal) ghc/alloc 208,795,112 210,102,904 +0.6% T18698b(normal) ghc/alloc 230,320,736 232,697,976 +1.0% BAD T19695(normal) ghc/alloc 1,483,648,128 1,504,702,976 +1.4% T20049(normal) ghc/alloc 85,612,024 85,114,376 -0.6% T21839c(normal) ghc/alloc 415,080,992 410,906,216 -1.0% GOOD T4801(normal) ghc/alloc 247,590,920 250,726,272 +1.3% T6048(optasm) ghc/alloc 95,699,416 95,080,680 -0.6% T783(normal) ghc/alloc 335,323,384 332,988,120 -0.7% T9233(normal) ghc/alloc 709,641,224 685,947,008 -3.3% GOOD T9630(normal) ghc/alloc 965,635,712 948,356,120 -1.8% T9675(optasm) ghc/alloc 444,604,152 428,987,216 -3.5% GOOD T9961(normal) ghc/alloc 303,064,592 308,798,800 +1.9% BAD WWRec(normal) ghc/alloc 503,728,832 498,102,272 -1.1% geo. mean -1.0% minimum -49.4% maximum +1.9% In fact these figures seem to vary between platforms; generally worse on i386 for some reason. The Windows numbers vary by 1% espec in benchmarks where the total allocation is low. But the geom mean stays solidly negative, which is good. The "increase/decrease" list below covers all platforms. The big win on T13253-spj comes because it has a big nest of join points, each occurring twice in the next one. The new occ-anal takes only one iteration of the simplifier to do the inlining; the old one took four. Moreover, we get much smaller code with the new one: New: Result size of Tidy Core = {terms: 429, types: 84, coercions: 0, joins: 14/14} Old: Result size of Tidy Core = {terms: 2,437, types: 304, coercions: 0, joins: 10/10} --------- Runtime perf ----------- No significant changes in nofib results, except a 1% reduction in compiler allocation. Metric Decrease: CoOpt_Read T13253-spj T9233 T9630 T9675 T12150 T21839c LargeRecord MultiComponentModulesRecomp T10421 T13701 T10421 T13701 T12425 Metric Increase: T18140 T9961 T18282 T18698a T18698b T19695 - - - - - 42aa7fbd by Julian Ospald at 2023-07-30T17:22:01-04:00 Improve documentation around IOException and ioe_filename See: * https://github.com/haskell/core-libraries-committee/issues/189 * https://github.com/haskell/unix/pull/279 * https://github.com/haskell/unix/pull/289 - - - - - 33598ecb by Sylvain Henry at 2023-08-01T14:45:54-04:00 JS: implement getMonotonicTime (fix #23687) - - - - - d2bedffd by Bartłomiej Cieślar at 2023-08-01T14:46:40-04:00 Implementation of the Deprecated Instances proposal #575 This commit implements the ability to deprecate certain instances, which causes the compiler to emit the desired deprecation message whenever they are instantiated. For example: module A where class C t where instance {-# DEPRECATED "dont use" #-} C Int where module B where import A f :: C t => t f = undefined g :: Int g = f -- "dont use" emitted here The implementation is as follows: - In the parser, we parse deprecations/warnings attached to instances: instance {-# DEPRECATED "msg" #-} Show X deriving instance {-# WARNING "msg2" #-} Eq Y (Note that non-standalone deriving instance declarations do not support this mechanism.) - We store the resulting warning message in `ClsInstDecl` (respectively, `DerivDecl`). In `GHC.Tc.TyCl.Instance.tcClsInstDecl` (respectively, `GHC.Tc.Deriv.Utils.newDerivClsInst`), we pass on that information to `ClsInst` (and eventually store it in `IfaceClsInst` too). - Finally, when we solve a constraint using such an instance, in `GHC.Tc.Instance.Class.matchInstEnv`, we emit the appropriate warning that was stored in `ClsInst`. Note that we only emit a warning when the instance is used in a different module than it is defined, which keeps the behaviour in line with the deprecation of top-level identifiers. Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - d5a65af6 by Ben Gamari at 2023-08-01T14:47:18-04:00 compiler: Style fixes - - - - - 7218c80a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Fix implicit cast This ensures that Task.h can be built with a C++ compiler. - - - - - d6d5aafc by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Fix warning in hs_try_putmvar001 - - - - - d9eddf7a by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Add AtomicModifyIORef test - - - - - f9eea4ba by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce NO_WARN macro This allows fine-grained ignoring of warnings. - - - - - 497b24ec by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Simplify atomicModifyMutVar2# implementation Previously we would perform a redundant load in the non-threaded RTS in atomicModifyMutVar2# implementation for the benefit of the non-moving GC's write barrier. Eliminate this. - - - - - 52ee082b by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce more principled fence operations - - - - - cd3c0377 by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce SET_INFO_RELAXED - - - - - 6df2352a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Style fixes - - - - - 4ef6f319 by Ben Gamari at 2023-08-01T14:47:19-04:00 codeGen/tsan: Rework handling of spilling - - - - - f9ca7e27 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More debug information - - - - - df4153ac by Ben Gamari at 2023-08-01T14:47:19-04:00 Improve TSAN documentation - - - - - fecae988 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More selective TSAN instrumentation - - - - - 465a9a0b by Alan Zimmerman at 2023-08-01T14:47:56-04:00 EPA: Provide correct annotation span for ImportDecl Use the whole declaration, rather than just the span of the 'import' keyword. Metric Decrease: T9961 T5205 Metric Increase: T13035 - - - - - ae63d0fa by Bartłomiej Cieślar at 2023-08-01T14:48:40-04:00 Add cases to T23279: HasField for deprecated record fields This commit adds additional tests from ticket #23279 to ensure that we don't regress on reporting deprecated record fields in conjunction with HasField, either when using overloaded record dot syntax or directly through `getField`. Fixes #23279 - - - - - 00fb6e6b by Andreas Klebinger at 2023-08-01T14:49:17-04:00 AArch NCG: Pure refactor Combine some alternatives. Add some line breaks for overly long lines - - - - - 8f3b3b78 by Andreas Klebinger at 2023-08-01T14:49:54-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - 74a882dc by MorrowM at 2023-08-02T06:00:03-04:00 Add a RULE to make lookup fuse See https://github.com/haskell/core-libraries-committee/issues/175 Metric Increase: T18282 - - - - - cca74dab by Ben Gamari at 2023-08-02T06:00:39-04:00 hadrian: Ensure that way-flags are passed to CC Previously the way-specific compilation flags (e.g. `-DDEBUG`, `-DTHREADED_RTS`) would not be passed to the CC invocations. This meant that C dependency files would not correctly reflect dependencies predicated on the way, resulting in the rather painful #23554. Closes #23554. - - - - - 622b483c by Jaro Reinders at 2023-08-02T06:01:20-04:00 Native 32-bit Enum Int64/Word64 instances This commits adds more performant Enum Int64 and Enum Word64 instances for 32-bit platforms, replacing the Integer-based implementation. These instances are a copy of the Enum Int and Enum Word instances with minimal changes to manipulate Int64 and Word64 instead. On i386 this yields a 1.5x performance increase and for the JavaScript back end it even yields a 5.6x speedup. Metric Decrease: T18964 - - - - - c8bd7fa4 by Sylvain Henry at 2023-08-02T06:02:03-04:00 JS: fix typos in constants (#23650) - - - - - b9d5bfe9 by Josh Meredith at 2023-08-02T06:02:40-04:00 JavaScript: update MK_TUP macros to use current tuple constructors (#23659) - - - - - 28211215 by Matthew Pickering at 2023-08-02T06:03:19-04:00 ci: Pass -Werror when building hadrian in hadrian-ghc-in-ghci job Warnings when building Hadrian can end up cluttering the output of HLS, and we've had bug reports in the past about these warnings when building Hadrian. It would be nice to turn on -Werror on at least one build of Hadrian in CI to avoid a patch introducing warnings when building Hadrian. Fixes #23638 - - - - - aca20a5d by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers By using a proper release store instead of a fence. - - - - - 453c0531 by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that array reads have necessary barriers This was the cause of #23541. - - - - - 93a0d089 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Add test for #23550 - - - - - 6a2f4a20 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Desugar non-recursive lets to non-recursive lets (take 2) This reverts commit 522bd584f71ddeda21efdf0917606ce3d81ec6cc. And takes care of the case that I missed in my previous attempt. Namely the case of an AbsBinds with no type variables and no dictionary variable. Ironically, the comment explaining why non-recursive lets were desugared to recursive lets were pointing specifically at this case as the reason. I just failed to understand that it was until Simon PJ pointed it out to me. See #23550 for more discussion. - - - - - ff81d53f by jade at 2023-08-02T06:05:20-04:00 Expand documentation of List & Data.List This commit aims to improve the documentation and examples of symbols exported from Data.List - - - - - fa4e5913 by Jade at 2023-08-02T06:06:03-04:00 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid - - - - - e2c91bff by Gergő Érdi at 2023-08-03T02:55:46+01:00 Desugar bindings in the context of their evidence Closes #23172 - - - - - 481f4a46 by Gergő Érdi at 2023-08-03T07:48:43+01:00 Add flag to `-f{no-}specialise-incoherents` to enable/disable specialisation of incoherent instances Fixes #23287 - - - - - d751c583 by Profpatsch at 2023-08-04T12:24:26-04:00 base: Improve String & IsString documentation - - - - - 01db1117 by Ben Gamari at 2023-08-04T12:25:02-04:00 rts/win32: Ensure reliability of IO manager shutdown When the Win32 threaded IO manager shuts down, `ioManagerDie` sends an `IO_MANAGER_DIE` event to the IO manager thread using the `io_manager_event` event object. Finally, it will closes the event object, and invalidate `io_manager_event`. Previously, `readIOManagerEvent` would see that `io_manager_event` is invalid and return `0`, suggesting that everything is right with the world. This meant that if `ioManagerDie` invalidated the handle before the event manager was blocked on the event we would end up in a situation where the event manager would never realize it was asked to shut down. Fix this by ensuring that `readIOManagerEvent` instead returns `IO_MANAGER_DIE` when we detect that the event object has been invalidated by `ioManagerDie`. Fixes #23691. - - - - - fdef003a by Ryan Scott at 2023-08-04T12:25:39-04:00 Look through TH splices in splitHsApps This modifies `splitHsApps` (a key function used in typechecking function applications) to look through untyped TH splices and quasiquotes. Not doing so was the cause of #21077. This builds on !7821 by making `splitHsApps` match on `HsUntypedSpliceTop`, which contains the `ThModFinalizers` that must be run as part of invoking the TH splice. See the new `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Along the way, I needed to make the type of `splitHsApps.set` slightly more general to accommodate the fact that the location attached to a quasiquote is a `SrcAnn NoEpAnns` rather than a `SrcSpanAnnA`. Fixes #21077. - - - - - e77a0b41 by Ben Gamari at 2023-08-04T12:26:15-04:00 Bump deepseq submodule to 1.5. And bump bounds (cherry picked from commit 1228d3a4a08d30eaf0138a52d1be25b38339ef0b) - - - - - cebb5819 by Ben Gamari at 2023-08-04T12:26:15-04:00 configure: Bump minimal boot GHC version to 9.4 (cherry picked from commit d3ffdaf9137705894d15ccc3feff569d64163e8e) - - - - - 83766dbf by Ben Gamari at 2023-08-04T12:26:15-04:00 template-haskell: Bump version to 2.21.0.0 Bumps exceptions submodule. (cherry picked from commit bf57fc9aea1196f97f5adb72c8b56434ca4b87cb) - - - - - 1211112a by Ben Gamari at 2023-08-04T12:26:15-04:00 base: Bump version to 4.19 Updates all boot library submodules. (cherry picked from commit 433d99a3c24a55b14ec09099395e9b9641430143) - - - - - 3ab5efd9 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Normalise versions more aggressively In backpack hashes can contain `+` characters. (cherry picked from commit 024861af51aee807d800e01e122897166a65ea93) - - - - - d52be957 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Declare bkpcabal08 as fragile Due to spurious output changes described in #23648. (cherry picked from commit c046a2382420f2be2c4a657c56f8d95f914ea47b) - - - - - e75a58d1 by Ben Gamari at 2023-08-04T12:26:15-04:00 gitlab-ci: Only mark linker_unload_native as broken in static jobs This test passes on dynamically-linked Alpine. (cherry picked from commit f356a7e8ec8ec3d6b2b30fd175598b9b80065d87) - - - - - 8b176514 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Update base-exports - - - - - 4b647936 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite/interface-stability: normalise versions This eliminates spurious changes from version bumps. - - - - - 0eb54c05 by Ben Gamari at 2023-08-04T12:26:51-04:00 linker/PEi386: Don't sign-extend symbol section number Previously we incorrectly interpreted PE section numbers as signed values. However, this isn't the case; rather, it's an unsigned 16-bit number with a few special bit-patterns (0xffff and 0xfffe). This resulted in #22941 as the linker would conclude that the sections were invalid. Fixing this required quite a bit of refactoring. Closes #22941. - - - - - fd7ce39c by Ben Gamari at 2023-08-04T12:27:28-04:00 testsuite: Mark MulMayOflo_full as broken rather than skipping To ensure that we don't accidentally fix it. See #23742. - - - - - 824092f2 by Ben Gamari at 2023-08-04T12:27:28-04:00 nativeGen/AArch64: Fix sign extension in MulMayOflo Previously the 32-bit implementations of MulMayOflo would use the a non-sensical sign-extension mode. Rewrite these to reflect what gcc 11 produces. Also similarly rework the 16- and 8-bit cases. This now passes the MulMayOflo tests in ghc/test-primops> in all four widths, including the precision tests. Fixes #23721. - - - - - 1b15dbc4 by Jan Hrček at 2023-08-04T12:28:08-04:00 Fix haddock markup in code example for coerce - - - - - 46fd8ced by Vladislav Zavialov at 2023-08-04T12:28:44-04:00 Fix (~) and (@) infix operators in TH splices (#23748) 8168b42a "Whitespace-sensitive bang patterns" allows GHC to accept the following infix operators: a ~ b = () a @ b = () But not if TH is used to generate those declarations: $([d| a ~ b = () a @ b = () |]) -- Test.hs:5:2: error: [GHC-55017] -- Illegal variable name: ‘~’ -- When splicing a TH declaration: (~_0) a_1 b_2 = GHC.Tuple.Prim.() This is easily fixed by modifying `reservedOps` in GHC.Utils.Lexeme - - - - - a1899d8f by Aaron Allen at 2023-08-04T12:29:24-04:00 [#23663] Show Flag Suggestions in GHCi Makes suggestions when using `:set` in GHCi with a misspelled flag. This mirrors how invalid flags are handled when passed to GHC directly. Logic for producing flag suggestions was moved to GHC.Driver.Sesssion so it can be shared. resolves #23663 - - - - - 03f2debd by Rodrigo Mesquita at 2023-08-04T12:30:00-04:00 Improve ghc-toolchain validation configure warning Fixes the layout of the ghc-toolchain validation warning produced by configure. - - - - - de25487d by Alan Zimmerman at 2023-08-04T12:30:36-04:00 EPA make getLocA a synonym for getHasLoc This is basically a no-op change, but allows us to make future changes that can rely on the HasLoc instances And I presume this means we can use more precise functions based on class resolution, so the Windows CI build reports Metric Decrease: T12234 T13035 - - - - - 3ac423b9 by Ben Gamari at 2023-08-04T12:31:13-04:00 ghc-platform: Add upper bound on base Hackage upload requires this. - - - - - 8ba20b21 by Matthew Craven at 2023-08-04T17:22:59-04:00 Adjust and clarify handling of primop effects Fixes #17900; fixes #20195. The existing "can_fail" and "has_side_effects" primop attributes that previously governed this were used in inconsistent and confusingly-documented ways, especially with regard to raising exceptions. This patch replaces them with a single "effect" attribute, which has four possible values: NoEffect, CanFail, ThrowsException, and ReadWriteEffect. These are described in Note [Classifying primop effects]. A substantial amount of related documentation has been re-drafted for clarity and accuracy. In the process of making this attribute format change for literally every primop, several existing mis-classifications were detected and corrected. One of these mis-classifications was tagToEnum#, which is now considered CanFail; this particular fix is known to cause a regression in performance for derived Enum instances. (See #23782.) Fixing this is left as future work. New primop attributes "cheap" and "work_free" were also added, and used in the corresponding parts of GHC.Core.Utils. In view of their actual meaning and uses, `primOpOkForSideEffects` and `exprOkForSideEffects` have been renamed to `primOpOkToDiscard` and `exprOkToDiscard`, respectively. Metric Increase: T21839c - - - - - 41bf2c09 by sheaf at 2023-08-04T17:23:42-04:00 Update inert_solved_dicts for ImplicitParams When adding an implicit parameter dictionary to the inert set, we must make sure that it replaces any previous implicit parameter dictionaries that overlap, in order to get the appropriate shadowing behaviour, as in let ?x = 1 in let ?x = 2 in ?x We were already doing this for inert_cans, but we weren't doing the same thing for inert_solved_dicts, which lead to the bug reported in #23761. The fix is thus to make sure that, when handling an implicit parameter dictionary in updInertDicts, we update **both** inert_cans and inert_solved_dicts to ensure a new implicit parameter dictionary correctly shadows old ones. Fixes #23761 - - - - - 43578d60 by Matthew Craven at 2023-08-05T01:05:36-04:00 Bump bytestring submodule to 0.11.5.1 - - - - - 91353622 by Ben Gamari at 2023-08-05T01:06:13-04:00 Initial commit of Note [Thunks, blackholes, and indirections] This Note attempts to summarize the treatment of thunks, thunk update, and indirections. This fell out of work on #23185. - - - - - 8d686854 by sheaf at 2023-08-05T01:06:54-04:00 Remove zonk in tcVTA This removes the zonk in GHC.Tc.Gen.App.tc_inst_forall_arg and its accompanying Note [Visible type application zonk]. Indeed, this zonk is no longer necessary, as we no longer maintain the invariant that types are well-kinded without zonking; only that typeKind does not crash; see Note [The Purely Kinded Type Invariant (PKTI)]. This commit removes this zonking step (as well as a secondary zonk), and replaces the aforementioned Note with the explanatory Note [Type application substitution], which justifies why the substitution performed in tc_inst_forall_arg remains valid without this zonking step. Fixes #23661 - - - - - 19dea673 by Ben Gamari at 2023-08-05T01:07:30-04:00 Bump nofib submodule Ensuring that nofib can be build using the same range of bootstrap compilers as GHC itself. - - - - - aa07402e by Luite Stegeman at 2023-08-05T23:15:55+09:00 JS: Improve compatibility with recent emsdk The JavaScript code in libraries/base/jsbits/base.js had some hardcoded offsets for fields in structs, because we expected the layout of the data structures to remain unchanged. Emsdk 3.1.42 changed the layout of the stat struct, breaking this assumption, and causing code in .hsc files accessing the stat struct to fail. This patch improves compatibility with recent emsdk by removing the assumption that data layouts stay unchanged: 1. offsets of fields in structs used by JavaScript code are now computed by the configure script, so both the .js and .hsc files will automatically use the new layout if anything changes. 2. the distrib/configure script checks that the emsdk version on a user's system is the same version that a bindist was booted with, to avoid data layout inconsistencies See #23641 - - - - - b938950d by Luite Stegeman at 2023-08-07T06:27:51-04:00 JS: Fix missing local variable declarations This fixes some missing local variable declarations that were found by running the testsuite in strict mode. Fixes #23775 - - - - - 6c0e2247 by sheaf at 2023-08-07T13:31:21-04:00 Update Haddock submodule to fix #23368 This submodule update adds the following three commits: bbf1c8ae - Check for puns 0550694e - Remove fake exports for (~), List, and Tuple<n> 5877bceb - Fix pretty-printing of Solo and MkSolo These commits fix the issues with Haddock HTML rendering reported in ticket #23368. Fixes #23368 - - - - - 5b5be3ea by Matthew Pickering at 2023-08-07T13:32:00-04:00 Revert "Bump bytestring submodule to 0.11.5.1" This reverts commit 43578d60bfc478e7277dcd892463cec305400025. Fixes #23789 - - - - - 01961be3 by Ben Gamari at 2023-08-08T02:47:14-04:00 configure: Derive library version from ghc-prim.cabal.in Since ghc-prim.cabal is now generated by Hadrian, we cannot depend upon it. Closes #23726. - - - - - 3b373838 by Ryan Scott at 2023-08-08T02:47:49-04:00 tcExpr: Push expected types for untyped TH splices inwards In !10911, I deleted a `tcExpr` case for `HsUntypedSplice` in favor of a much simpler case that simply delegates to `tcApp`. Although this passed the test suite at the time, this was actually an error, as the previous `tcExpr` case was critically pushing the expected type inwards. This actually matters for programs like the one in #23796, which GHC would not accept with type inference alone—we need full-blown type _checking_ to accept these. I have added back the previous `tcExpr` case for `HsUntypedSplice` and now explain why we have two different `HsUntypedSplice` cases (one in `tcExpr` and another in `splitHsApps`) in `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Fixes #23796. - - - - - 0ef1d8ae by sheaf at 2023-08-08T21:26:51-04:00 Compute all emitted diagnostic codes This commit introduces in GHC.Types.Error.Codes the function constructorCodes :: forall diag. (...) => Map DiagnosticCode String which computes a collection of all the diagnostic codes that correspond to a particular type. In particular, we can compute the collection of all diagnostic codes emitted by GHC using the invocation constructorCodes @GhcMessage We then make use of this functionality in the new "codes" test which checks consistency and coverage of GHC diagnostic codes. It performs three checks: - check 1: all non-outdated GhcDiagnosticCode equations are statically used. - check 2: all outdated GhcDiagnosticCode equations are statically unused. - check 3: all statically used diagnostic codes are covered by the testsuite (modulo accepted exceptions). - - - - - 4bc7b1e5 by Fraser Tweedale at 2023-08-08T21:27:32-04:00 numberToRangedRational: fix edge cases for exp ≈ (maxBound :: Int) Currently a negative exponent less than `minBound :: Int` results in Infinity, which is very surprising and obviously wrong. ``` λ> read "1e-9223372036854775808" :: Double 0.0 λ> read "1e-9223372036854775809" :: Double Infinity ``` There is a further edge case where the exponent can overflow when increased by the number of tens places in the integer part, or underflow when decreased by the number of leading zeros in the fractional part if the integer part is zero: ``` λ> read "10e9223372036854775807" :: Double 0.0 λ> read "0.01e-9223372036854775808" :: Double Infinity ``` To resolve both of these issues, perform all arithmetic and comparisons involving the exponent in type `Integer`. This approach also eliminates the need to explicitly check the exponent against `maxBound :: Int` and `minBound :: Int`, because the allowed range of the exponent (i.e. the result of `floatRange` for the target floating point type) is certainly within those bounds. This change implements CLC proposal 192: https://github.com/haskell/core-libraries-committee/issues/192 - - - - - 6eab07b2 by Alan Zimmerman at 2023-08-08T21:28:10-04:00 EPA: Remove Location from WarningTxt source This is not needed. - - - - - 1a98d673 by Sebastian Graf at 2023-08-09T16:24:29-04:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 2274abc8 by Sebastian Graf at 2023-08-09T16:24:29-04:00 More explicit strictness in GHC.Real - - - - - ce8aa54c by Sebastian Graf at 2023-08-09T16:24:30-04:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - d004a36d by Sebastian Graf at 2023-08-09T16:24:30-04:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 8c73505e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - d8d993f1 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Disable tests RepPolyWrappedVar2 and RepPolyUnsafeCoerce1 in JS backend ... because those coerce between incompatible/unknown PrimReps. - - - - - f06e87e4 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Inlining literals into boring contexts is OK - - - - - 4a6b7c87 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Clarify floating of unsafeEqualityProofs (#23754) - - - - - b0f4752e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 7e0c8b3b by Sebastian Graf at 2023-08-09T16:24:30-04:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Annoyingly, in -O0 we sometimes generate ``` foo = case "blah"# of sat { __DEFAULT -> unpackCString# sat } ``` which makes it a bit harder to spot that we can emit a standard `stg_unpack_cstring` thunk. Fixes #23270. - - - - - 357f2738 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Deactivate -fcatch-nonexhaustive-cases in ghc-bignum (#23345) - - - - - 59202c80 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. In the ghc/alloc perf test `LargeRecord`, we introduce an additional Simplifier iteration due to #17910. E.g., FloatOut produces a binding ``` lvl_s6uK [Occ=Once1] :: GHC.Types.Int [LclId] lvl_s6uK = GHC.Types.I# 2# lvl_s6uL [Occ=Once1] :: GHC.Types.Any [LclId] lvl_s6uL = case Unsafe.Coerce.unsafeEqualityProof ... of { Unsafe.Coerce.UnsafeRefl v2_i6tr -> lvl_s6uK `cast` (... v2_i6tr ...) } ``` That occurs once and hence is pre-inlined unconditionally in the next Simplifier pass. It's non-trivial to find a way around that, but not really harmful otherwise. Hence we accept a 1.2% increase on some architectures. Metric Increase: LargeRecord - - - - - 00d31188 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - bf885d7a by Matthew Craven at 2023-08-09T16:25:07-04:00 Bump bytestring submodule to 0.11.5, again Fixes #23789. The bytestring commit used here is unreleased; a release can be made when necessary. - - - - - 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - e03760db by Rodrigo Mesquita at 2024-04-26T21:28:39+01:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 20 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - − .gitlab/circle-ci-job.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - − .gitlab/gen-ci.cabal - + .gitlab/generate-ci/LICENSE - + .gitlab/generate-ci/README.mkd - + .gitlab/generate-ci/flake.lock - + .gitlab/generate-ci/flake.nix - .gitlab/gen_ci.hs → .gitlab/generate-ci/gen_ci.hs - + .gitlab/generate-ci/generate-ci.cabal - + .gitlab/generate-ci/generate-job-metadata - + .gitlab/generate-ci/generate-jobs - .gitlab/hie.yaml → .gitlab/generate-ci/hie.yaml - − .gitlab/generate_job_metadata - − .gitlab/generate_jobs - .gitlab/issue_templates/bug.md → .gitlab/issue_templates/default.md The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d820cbc2e8a7e61bded28be8d6710f73010d00a...e03760db6713068ad8ba953d2252ec12b3278c9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d820cbc2e8a7e61bded28be8d6710f73010d00a...e03760db6713068ad8ba953d2252ec12b3278c9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 20:34:20 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 26 Apr 2024 16:34:20 -0400 Subject: [Git][ghc/ghc][wip/romes/fixes-2] task: Substitute some datatypes for newtypes Message-ID: <662c0fccad6dd_2fdeaffbfb893587@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/fixes-2 at Glasgow Haskell Compiler / GHC Commits: 9d820cbc by Rodrigo Mesquita at 2023-06-23T23:05:32+01:00 task: Substitute some datatypes for newtypes * Substitutes some data type declarations for newtype declarations * Adds comment to `LlvmConfigCache`, which must decidedly not be a newtype. Fixes #23555 - - - - - 5 changed files: - compiler/GHC/CmmToAsm/AArch64/RegInfo.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Driver/LlvmConfigCache.hs - compiler/GHC/Driver/Pipeline/Phases.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/RegInfo.hs ===================================== @@ -8,7 +8,7 @@ import GHC.Cmm import GHC.Utils.Outputable -data JumpDest = DestBlockId BlockId +newtype JumpDest = DestBlockId BlockId -- Debug Instance instance Outputable JumpDest where ===================================== compiler/GHC/CmmToAsm/PPC/RegInfo.hs ===================================== @@ -27,7 +27,7 @@ import GHC.Cmm.CLabel import GHC.Types.Unique import GHC.Utils.Outputable (ppr, text, Outputable, (<>)) -data JumpDest = DestBlockId BlockId +newtype JumpDest = DestBlockId BlockId -- Debug Instance instance Outputable JumpDest where ===================================== compiler/GHC/Core/Map/Type.hs ===================================== @@ -542,7 +542,7 @@ instance Eq (DeBruijn a) => Eq (DeBruijn (Maybe a)) where -- We also need to do the same for multiplicity! Which, since multiplicities are -- encoded simply as a 'Type', amounts to have a Trie for a pair of types. Tries -- of pairs are composition. -data BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a)) +newtype BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a)) -- TODO(22292): derive instance Functor BndrMap where ===================================== compiler/GHC/Driver/LlvmConfigCache.hs ===================================== @@ -18,6 +18,8 @@ import System.IO.Unsafe -- Currently implemented with unsafe lazy IO. But it could be implemented with -- an IORef as the exposed interface is in IO. data LlvmConfigCache = LlvmConfigCache LlvmConfig +-- NB: It is crucial for this to be a datatype, not a newtype. +-- Allocations can increase across the board over 20% otherwise (see the discussion on !10708 and non-final pipelines) initLlvmConfigCache :: FilePath -> IO LlvmConfigCache initLlvmConfigCache top_dir = pure $ LlvmConfigCache (unsafePerformIO $ initLlvmConfig top_dir) ===================================== compiler/GHC/Driver/Pipeline/Phases.hs ===================================== @@ -51,4 +51,4 @@ data TPhase res where T_MergeForeign :: PipeEnv -> HscEnv -> FilePath -> [FilePath] -> TPhase FilePath -- | A wrapper around the interpretation function for phases. -data PhaseHook = PhaseHook (forall a . TPhase a -> IO a) +newtype PhaseHook = PhaseHook (forall a . TPhase a -> IO a) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d820cbc2e8a7e61bded28be8d6710f73010d00a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d820cbc2e8a7e61bded28be8d6710f73010d00a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 20:39:49 2024 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 26 Apr 2024 16:39:49 -0400 Subject: [Git][ghc/ghc][wip/romes/24554] 184 commits: Fix sharing of 'IfaceTyConInfo' during core to iface type translation Message-ID: <662c1115662d7_2fdea10a2b1093948@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/24554 at Glasgow Haskell Compiler / GHC Commits: 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - e03760db by Rodrigo Mesquita at 2024-04-26T21:28:39+01:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b38fa3ed4a777fe591e8faae6046464203a2c89...e03760db6713068ad8ba953d2252ec12b3278c9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b38fa3ed4a777fe591e8faae6046464203a2c89...e03760db6713068ad8ba953d2252ec12b3278c9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 21:07:19 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 26 Apr 2024 17:07:19 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.10] bindist: Fix xattr cleaning Message-ID: <662c17879cc83_2fdea142c4d49794d@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: ea3839f6 by Rodrigo Mesquita at 2024-04-26T17:06:49-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 (cherry picked from commit e03760db6713068ad8ba953d2252ec12b3278c9b) - - - - - 1 changed file: - distrib/configure.ac.in Changes: ===================================== distrib/configure.ac.in ===================================== @@ -114,16 +114,16 @@ if test "$HostOS" = "darwin"; then # The following is the work around suggested by @carter in #17418 during # install time. This should help us with code signing issues by removing # extended attributes from all files. - XATTR=${XATTR:-/usr/bin/xattr} + XATTR="${XATTR:-/usr/bin/xattr}" - if [ -e "${XATTR}" ]; then + if test -e "${XATTR}"; then # Instead of cleaning the attributes of the ghc-toolchain binary only, # we clean them from all files in the bin/ and lib/ directories, as it additionally future # proofs running executables from the bindist besides ghc-toolchain at configure time, and # we can avoid figuring out the path to the ghc-toolchain dynlib specifically. - /usr/bin/xattr -rc bin/ - /usr/bin/xattr -rc lib/ + "$XATTR" -rc bin/ + "$XATTR" -rc lib/ fi fi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ea3839f64bf5dfc8373734f18d766766b024c026 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ea3839f64bf5dfc8373734f18d766766b024c026 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:04:06 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:04:06 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Refactor the Binary serialisation interface Message-ID: <662c24d691d1d_2fdea1e5bcfc1056b4@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 15 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - utils/haddock Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -29,7 +29,6 @@ module GHC.Iface.Binary ( import GHC.Prelude -import GHC.Tc.Utils.Monad import GHC.Builtin.Utils ( isKnownKeyName, lookupKnownKeyName ) import GHC.Unit import GHC.Unit.Module.ModIface @@ -39,6 +38,7 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt +import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -75,7 +75,7 @@ readBinIfaceHeader -> CheckHiWay -> TraceBinIFace -> FilePath - -> IO (Fingerprint, BinHandle) + -> IO (Fingerprint, ReadBinHandle) readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do let platform = profilePlatform profile @@ -121,6 +121,8 @@ readBinIfaceHeader profile _name_cache checkHiWay traceBinIFace hi_path = do pure (src_hash, bh) -- | Read an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. readBinIface :: Profile -> NameCache @@ -135,7 +137,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getWithUserData name_cache bh - seekBin bh extFields_p + seekBinReader bh extFields_p extFields <- get bh return mod_iface @@ -146,7 +148,7 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any -- Names or FastStrings. -getWithUserData :: Binary a => NameCache -> BinHandle -> IO a +getWithUserData :: Binary a => NameCache -> ReadBinHandle -> IO a getWithUserData name_cache bh = do bh <- getTables name_cache bh get bh @@ -154,24 +156,30 @@ getWithUserData name_cache bh = do -- | Setup a BinHandle to read something written using putWithTables -- -- Reading names has the side effect of adding them into the given NameCache. -getTables :: NameCache -> BinHandle -> IO BinHandle +getTables :: NameCache -> ReadBinHandle -> IO ReadBinHandle getTables name_cache bh = do - -- Read the dictionary - -- The next word in the file is a pointer to where the dictionary is - -- (probably at the end of the file) - dict <- Binary.forwardGet bh (getDictionary bh) + fsReaderTable <- initFastStringReaderTable + nameReaderTable <- initNameReaderTable name_cache + - -- Initialise the user-data field of bh - let bh_fs = setUserData bh $ newReadState (error "getSymtabName") - (getDictFastString dict) + -- The order of these deserialisation matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + fsTable <- Binary.forwardGet bh (getTable fsReaderTable bh) + let + fsReader = mkReaderFromTable fsReaderTable fsTable + bhFs = addReaderToUserData (mkSomeBinaryReader fsReader) bh - symtab <- Binary.forwardGet bh_fs (getSymbolTable bh_fs name_cache) + nameTable <- Binary.forwardGet bh (getTable nameReaderTable bhFs) + let + nameReader = mkReaderFromTable nameReaderTable nameTable + bhName = addReaderToUserData (mkSomeBinaryReader nameReader) bhFs - -- It is only now that we know how to get a Name - return $ setUserData bh $ newReadState (getSymtabName name_cache dict symtab) - (getDictFastString dict) + pure bhName --- | Write an interface file +-- | Write an interface file. +-- +-- See Note [Deduplication during iface binary serialisation] for details. writeBinIface :: Profile -> TraceBinIFace -> FilePath -> ModIface -> IO () writeBinIface profile traceBinIface hi_path mod_iface = do bh <- openBinMem initBinMemSize @@ -184,14 +192,14 @@ writeBinIface profile traceBinIface hi_path mod_iface = do put_ bh tag put_ bh (mi_src_hash mod_iface) - extFields_p_p <- tellBin bh + extFields_p_p <- tellBinWriter bh put_ bh extFields_p_p putWithUserData traceBinIface bh mod_iface - extFields_p <- tellBin bh + extFields_p <- tellBinWriter bh putAt bh extFields_p_p extFields_p - seekBin bh extFields_p + seekBinWriter bh extFields_p put_ bh (mi_ext_fields mod_iface) -- And send the result to the file @@ -201,7 +209,7 @@ writeBinIface profile traceBinIface hi_path mod_iface = do -- is necessary if you want to serialise Names or FastStrings. -- It also writes a symbol table and the dictionary. -- This segment should be read using `getWithUserData`. -putWithUserData :: Binary a => TraceBinIFace -> BinHandle -> a -> IO () +putWithUserData :: Binary a => TraceBinIFace -> WriteBinHandle -> a -> IO () putWithUserData traceBinIface bh payload = do (name_count, fs_count, _b) <- putWithTables bh (\bh' -> put bh' payload) @@ -225,59 +233,263 @@ putWithUserData traceBinIface bh payload = do -- -- It returns (number of names, number of FastStrings, payload write result) -- -putWithTables :: BinHandle -> (BinHandle -> IO b) -> IO (Int,Int,b) -putWithTables bh put_payload = do - -- initialize state for the name table and the FastString table. - symtab_next <- newFastMutInt 0 - symtab_map <- newIORef emptyUFM - let bin_symtab = BinSymbolTable - { bin_symtab_next = symtab_next - , bin_symtab_map = symtab_map - } +-- See Note [Order of deduplication tables during iface binary serialisation] +putWithTables :: WriteBinHandle -> (WriteBinHandle -> IO b) -> IO (Int, Int, b) +putWithTables bh' put_payload = do + -- Initialise deduplicating tables. + (fast_wt, fsWriter) <- initFastStringWriterTable + (name_wt, nameWriter) <- initNameWriterTable + + -- Initialise the 'WriterUserData'. + let writerUserData = mkWriterUserData + [ mkSomeBinaryWriter @FastString fsWriter + , mkSomeBinaryWriter @Name nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) + ] + let bh = setWriterUserData bh' writerUserData + + (fs_count : name_count : _, r) <- + -- The order of these entries matters! + -- + -- See Note [Order of deduplication tables during iface binary serialisation] for details. + putAllTables bh [fast_wt, name_wt] $ do + put_payload bh + + return (name_count, fs_count, r) + where + putAllTables _ [] act = do + a <- act + pure ([], a) + putAllTables bh (x : xs) act = do + (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + putAllTables bh xs act + pure (r : res, a) - (bh_fs, bin_dict, put_dict) <- initFSTable bh - - (fs_count,(name_count,r)) <- forwardPut bh (const put_dict) $ do +-- | Initial ram buffer to allocate for writing interface files +initBinMemSize :: Int +initBinMemSize = 1024 * 1024 - -- NB. write the dictionary after the symbol table, because - -- writing the symbol table may create more dictionary entries. - let put_symtab = do - name_count <- readFastMutInt symtab_next - symtab_map <- readIORef symtab_map - putSymbolTable bh_fs name_count symtab_map - pure name_count +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 +binaryInterfaceMagic platform + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 - forwardPut bh_fs (const put_symtab) $ do - -- BinHandle with FastString and Name writing support - let ud_fs = getUserData bh_fs - let ud_name = ud_fs - { ud_put_nonbinding_name = putName bin_dict bin_symtab - , ud_put_binding_name = putName bin_dict bin_symtab - } - let bh_name = setUserData bh ud_name +{- +Note [Deduplication during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we serialise a 'ModIface', many symbols are redundant. +For example, there can be many duplicated 'FastString's and 'Name's. +To save space, we deduplicate duplicated symbols, such as 'FastString' and 'Name', +by maintaining a table of already seen symbols. - put_payload bh_name +Besides saving a lot of disk space, this additionally enables us to automatically share +these symbols when we read the 'ModIface' from disk, without additional mechanisms such as 'FastStringTable'. - return (name_count, fs_count, r) +The general idea is, when serialising a value of type 'Name', we first have to create a deduplication +table (see 'putWithTables.initNameWriterTable' for example). Then, we create a 'BinaryWriter' function +which we add to the 'WriterUserData'. When this 'BinaryWriter' is used to serialise a value of type 'Name', +it looks up whether we have seen this value before. If so, we write an index to disk. +If we haven't seen the value before, we add it to the deduplication table and produce a new index. +Both the 'ReaderUserData' and 'WriterUserData' can contain many 'BinaryReader's and 'BinaryWriter's +respectively, which can each individually be tweaked to use a deduplication table, or to serialise +the value without deduplication. +After the payload (e.g., the 'ModIface') has been serialised to disk, we serialise the deduplication tables +to disk. This happens in 'putAllTables', where we serialise all tables that we use during 'ModIface' +serialisation. See 'initNameWriterTable' and 'putSymbolTable' for an implementation example. +This uses the 'real' serialisation function, e.g., 'serialiseName'. +However, these tables need to be deserialised before we can read the 'ModIface' from disk. +Thus, we write before the 'ModIface' a forward pointer to the deduplication table, so we can +read this table before deserialising the 'ModIface'. --- | Initial ram buffer to allocate for writing interface files -initBinMemSize :: Int -initBinMemSize = 1024 * 1024 +To add a deduplication table for a type, let us assume 'IfaceTyCon', you need to do the following: -binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 -binaryInterfaceMagic platform - | target32Bit platform = FixedLengthEncoding 0x1face - | otherwise = FixedLengthEncoding 0x1face64 +* The 'Binary' instance 'IfaceTyCon' needs to dynamically look up the serialiser function instead of + serialising the value of 'IfaceTyCon'. It needs to look up the serialiser in the 'ReaderUserData' and + 'WriterUserData' respectively. + This allows us to change the serialisation of 'IfaceTyCon' at run-time. + We can still serialise 'IfaceTyCon' to disk directly, or use a deduplication table to reduce the size of + the .hi file. + + For example: + + @ + instance Binary IfaceTyCon where + put_ bh ty = case findUserDataWriter (Proxy @IfaceTyCon) bh of + tbl -> putEntry tbl bh ty + get bh = case findUserDataReader (Proxy @IfaceTyCon) bh of + tbl -> getEntry tbl bh + @ + + We include the signatures of 'findUserDataWriter' and 'findUserDataReader' to make this code example + easier to understand: + + @ + findUserDataReader :: Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a + findUserDataWriter :: Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a + @ + + where 'BinaryReader' and 'BinaryWriter' correspond to the 'Binary' class methods + 'get' and 'put_' respectively, thus: + + @ + newtype BinaryReader s = BinaryReader { getEntry :: ReadBinHandle -> IO s } + + newtype BinaryWriter s = BinaryWriter { putEntry :: WriteBinHandle -> s -> IO () } + @ + + 'findUserData*' looks up the serialisation function for 'IfaceTyCon', which we then subsequently + use to serialise said 'IfaceTyCon'. If no such serialiser can be found, 'findUserData*' + crashes at run-time. + +* Whenever a value of 'IfaceTyCon' needs to be serialised, there are two serialisation functions involved: + + * The literal serialiser that puts/gets the value to/from disk: + Writes or reads a value of type 'IfaceTyCon' from the 'Write/ReadBinHandle'. + This serialiser is primarily used to write the values stored in the deduplication table. + It is also used to read the values from disk. + + * The deduplicating serialiser: + Replaces the serialised value of 'IfaceTyCon' with an offset that is stored in the + deduplication table. + This serialiser is used while serialising the payload. + + We need to add the deduplicating serialiser to the 'ReaderUserData' and 'WriterUserData' + respectively, so that 'findUserData*' can find them. + + For example, adding a serialiser for writing 'IfaceTyCon's: + + @ + let bh0 :: WriteBinHandle = ... + putIfaceTyCon = ... -- Serialises 'IfaceTyCon' to disk + bh = addWriterToUserData (mkSomeBinaryWriter putIfaceTyCon) bh0 + @ + + Naturally, you have to do something similar for reading values of 'IfaceTyCon'. + + The provided code example implements the previous behaviour: + serialise all values of type 'IfaceTyCon' directly. No deduplication is happening. + + Now, instead of literally putting the value, we can introduce a deduplication table! + Instead of specifying 'putIfaceTyCon', which writes a value of 'IfaceTyCon' directly to disk, + we provide a function that looks up values in a table and provides an index of each value + we have already seen. + If the particular 'IfaceTyCon' we want to serialise isn't already in the de-dup table, + we allocate a new index and extend the table. + + See the definition of 'initNameWriterTable' and 'initNameReaderTable' for example deduplication tables. + +* Storing the deduplication table. + + After the deduplicating the elements in the payload (e.g., 'ModIface'), we now have a deduplication + table full with all the values. + We serialise this table to disk using the real serialiser (e.g., 'putIfaceTyCon'). + + When serialisation is complete, we write out the de-dup table in 'putAllTables', + serialising each 'IfaceTyCon' in the table. Of course, doing so might in turn serialise + another de-dup'd thing (e.g. a FastString), thereby extending its respective de-dup table. + +Note [Order of deduplication tables during iface binary serialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Serialisation of 'ModIface' uses tables to deduplicate symbols that occur often. +See Note [Deduplication during iface binary serialisation]. + +After 'ModIface' has been written to disk, we write the deduplication tables. +Writing a table may add additional entries to *other* deduplication tables, thus +we need to make sure that the symbol table we serialise only depends on +deduplication tables that haven't been written to disk yet. + +For example, assume we maintain deduplication tables for 'FastString' and 'Name'. +The symbol 'Name' depends on 'FastString', so serialising a 'Name' may add a 'FastString' +to the 'FastString' deduplication table. +Thus, 'Name' table needs to be serialised to disk before the 'FastString' table. + +When we read the 'ModIface' from disk, we consequentially need to read the 'FastString' +deduplication table from disk, before we can deserialise the 'Name' deduplication table. +Therefore, before we serialise the tables, we write forward pointers that allow us to jump ahead +to the table we need to deserialise first. +What deduplication tables exist and the order of serialisation is currently statically specified +in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. +The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility +functions such as 'forwardGet'. + +Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): + +┌──────────────┐ +│ Headers │ +├──────────────┤ +│ Ptr FS ├────────┐ +├──────────────┤ │ +│ Ptr Name ├─────┐ │ +├──────────────┤ │ │ +│ │ │ │ +│ ModIface │ │ │ +│ Payload │ │ │ +│ │ │ │ +├──────────────┤ │ │ +│ │ │ │ +│ Name Table │◄────┘ │ +│ │ │ +├──────────────┤ │ +│ │ │ +│ FS Table │◄───────┘ +│ │ +└──────────────┘ + +-} -- ----------------------------------------------------------------------------- -- The symbol table -- -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,Name) -> IO () + +initNameReaderTable :: NameCache -> IO (ReaderTable Name) +initNameReaderTable cache = do + return $ + ReaderTable + { getTable = \bh -> getSymbolTable bh cache + , mkReaderFromTable = \tbl -> mkReader (getSymtabName tbl) + } + +data BinSymbolTable = BinSymbolTable { + bin_symtab_next :: !FastMutInt, -- The next index to use + bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) + -- indexed by Name + } + +initNameWriterTable :: IO (WriterTable, BinaryWriter Name) +initNameWriterTable = do + symtab_next <- newFastMutInt 0 + symtab_map <- newIORef emptyUFM + let bin_symtab = + BinSymbolTable + { bin_symtab_next = symtab_next + , bin_symtab_map = symtab_map + } + + let put_symtab bh = do + name_count <- readFastMutInt symtab_next + symtab_map <- readIORef symtab_map + putSymbolTable bh name_count symtab_map + pure name_count + + return + ( WriterTable + { putTable = put_symtab + } + , mkWriter $ putName bin_symtab + ) + + +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,Name) -> IO () putSymbolTable bh name_count symtab = do put_ bh name_count let names = elems (array (0,name_count-1) (nonDetEltsUFM symtab)) @@ -286,7 +498,7 @@ putSymbolTable bh name_count symtab = do mapM_ (\n -> serialiseName bh n symtab) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh :: IO Int -- create an array of Names for the symbols and add them to the NameCache @@ -307,7 +519,7 @@ getSymbolTable bh name_cache = do arr <- unsafeFreeze mut_arr return (cache, arr) -serialiseName :: BinHandle -> Name -> UniqFM key (Int,Name) -> IO () +serialiseName :: WriteBinHandle -> Name -> UniqFM key (Int,Name) -> IO () serialiseName bh name _ = do let mod = assertPpr (isExternalName name) (ppr name) (nameModule name) put_ bh (moduleUnit mod, moduleName mod, nameOccName name) @@ -331,8 +543,8 @@ serialiseName bh name _ = do -- See Note [Symbol table representation of names] -putName :: FSTable -> BinSymbolTable -> BinHandle -> Name -> IO () -putName _dict BinSymbolTable{ +putName :: BinSymbolTable -> WriteBinHandle -> Name -> IO () +putName BinSymbolTable{ bin_symtab_map = symtab_map_ref, bin_symtab_next = symtab_next } bh name @@ -356,10 +568,9 @@ putName _dict BinSymbolTable{ put_ bh (fromIntegral off :: Word32) -- See Note [Symbol table representation of names] -getSymtabName :: NameCache - -> Dictionary -> SymbolTable - -> BinHandle -> IO Name -getSymtabName _name_cache _dict symtab bh = do +getSymtabName :: SymbolTable Name + -> ReadBinHandle -> IO Name +getSymtabName symtab bh = do i :: Word32 <- get bh case i .&. 0xC0000000 of 0x00000000 -> return $! symtab ! fromIntegral i @@ -376,10 +587,3 @@ getSymtabName _name_cache _dict symtab bh = do Just n -> n _ -> pprPanic "getSymtabName:unknown name tag" (ppr i) - -data BinSymbolTable = BinSymbolTable { - bin_symtab_next :: !FastMutInt, -- The next index to use - bin_symtab_map :: !(IORef (UniqFM Name (Int,Name))) - -- indexed by Name - } - ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -67,7 +67,7 @@ hieMagicLen = length hieMagic ghcVersion :: ByteString ghcVersion = BSC.pack cProjectVersion -putBinLine :: BinHandle -> ByteString -> IO () +putBinLine :: WriteBinHandle -> ByteString -> IO () putBinLine bh xs = do mapM_ (putByte bh) $ BS.unpack xs putByte bh 10 -- newline char @@ -85,11 +85,11 @@ writeHieFile hie_file_path hiefile = do putBinLine bh0 $ ghcVersion -- remember where the dictionary pointer will go - dict_p_p <- tellBin bh0 + dict_p_p <- tellBinWriter bh0 put_ bh0 dict_p_p -- remember where the symbol table pointer will go - symtab_p_p <- tellBin bh0 + symtab_p_p <- tellBinWriter bh0 put_ bh0 symtab_p_p -- Make some initial state @@ -105,15 +105,16 @@ writeHieFile hie_file_path hiefile = do hie_dict_map = dict_map_ref } -- put the main thing - let bh = setUserData bh0 $ newWriteState (putName hie_symtab) - (putName hie_symtab) - (putFastString hie_dict) + let bh = setWriterUserData bh0 + $ newWriteState (putName hie_symtab) + (putName hie_symtab) + (putFastString hie_dict) put_ bh hiefile -- write the symtab pointer at the front of the file - symtab_p <- tellBin bh + symtab_p <- tellBinWriter bh putAt bh symtab_p_p symtab_p - seekBin bh symtab_p + seekBinWriter bh symtab_p -- write the symbol table itself symtab_next' <- readFastMutInt symtab_next @@ -121,9 +122,9 @@ writeHieFile hie_file_path hiefile = do putSymbolTable bh symtab_next' symtab_map' -- write the dictionary pointer at the front of the file - dict_p <- tellBin bh + dict_p <- tellBinWriter bh putAt bh dict_p_p dict_p - seekBin bh dict_p + seekBinWriter bh dict_p -- write the dictionary itself dict_next <- readFastMutInt dict_next_ref @@ -181,7 +182,7 @@ readHieFile name_cache file = do hieFile <- readHieFileContents bh0 name_cache return $ HieFileResult hieVersion ghcVersion hieFile -readBinLine :: BinHandle -> IO ByteString +readBinLine :: ReadBinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] where loop acc = do @@ -190,7 +191,7 @@ readBinLine bh = BS.pack . reverse <$> loop [] then return acc else loop (char : acc) -readHieFileHeader :: FilePath -> BinHandle -> IO HieHeader +readHieFileHeader :: FilePath -> ReadBinHandle -> IO HieHeader readHieFileHeader file bh0 = do -- Read the header magic <- replicateM hieMagicLen (get bh0) @@ -213,15 +214,16 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO HieFile +readHieFileContents :: ReadBinHandle -> NameCache -> IO HieFile readHieFileContents bh0 name_cache = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data bh1 <- do - let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") - (getDictFastString dict) + let bh1 = setReaderUserData bh0 + $ newReadState (error "getSymtabName") + (getDictFastString dict) symtab <- get_symbol_table bh1 - let bh1' = setUserData bh1 + let bh1' = setReaderUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) return bh1' @@ -231,21 +233,21 @@ readHieFileContents bh0 name_cache = do where get_dictionary bin_handle = do dict_p <- get bin_handle - data_p <- tellBin bin_handle - seekBin bin_handle dict_p + data_p <- tellBinReader bin_handle + seekBinReader bin_handle dict_p dict <- getDictionary bin_handle - seekBin bin_handle data_p + seekBinReader bin_handle data_p return dict get_symbol_table bh1 = do symtab_p <- get bh1 - data_p' <- tellBin bh1 - seekBin bh1 symtab_p + data_p' <- tellBinReader bh1 + seekBinReader bh1 symtab_p symtab <- getSymbolTable bh1 name_cache - seekBin bh1 data_p' + seekBinReader bh1 data_p' return symtab -putFastString :: HieDictionary -> BinHandle -> FastString -> IO () +putFastString :: HieDictionary -> WriteBinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, hie_dict_map = out_r} bh f = do @@ -259,13 +261,13 @@ putFastString HieDictionary { hie_dict_next = j_r, writeFastMutInt j_r (j + 1) writeIORef out_r $! addToUFM_Directly out unique (j, f) -putSymbolTable :: BinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () +putSymbolTable :: WriteBinHandle -> Int -> UniqFM Name (Int,HieName) -> IO () putSymbolTable bh next_off symtab = do put_ bh next_off let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO SymbolTable +getSymbolTable :: ReadBinHandle -> NameCache -> IO (SymbolTable Name) getSymbolTable bh name_cache = do sz <- get bh mut_arr <- A.newArray_ (0, sz-1) :: IO (A.IOArray Int Name) @@ -275,12 +277,12 @@ getSymbolTable bh name_cache = do A.writeArray mut_arr i name A.unsafeFreeze mut_arr -getSymTabName :: SymbolTable -> BinHandle -> IO Name +getSymTabName :: SymbolTable Name -> ReadBinHandle -> IO Name getSymTabName st bh = do i :: Word32 <- get bh return $ st A.! (fromIntegral i) -putName :: HieSymbolTable -> BinHandle -> Name -> IO () +putName :: HieSymbolTable -> WriteBinHandle -> Name -> IO () putName (HieSymbolTable next ref) bh name = do symmap <- readIORef ref case lookupUFM symmap name of @@ -333,7 +335,7 @@ fromHieName nc hie_name = do -- ** Reading and writing `HieName`'s -putHieName :: BinHandle -> HieName -> IO () +putHieName :: WriteBinHandle -> HieName -> IO () putHieName bh (ExternalName mod occ span) = do putByte bh 0 put_ bh (mod, occ, BinSrcSpan span) @@ -344,7 +346,7 @@ putHieName bh (KnownKeyName uniq) = do putByte bh 2 put_ bh $ unpkUnique uniq -getHieName :: BinHandle -> IO HieName +getHieName :: ReadBinHandle -> IO HieName getHieName bh = do t <- getByte bh case t of ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -33,16 +33,16 @@ instance Binary ExtensibleFields where -- for a payload pointer after each name: header_entries <- forM (Map.toList fs) $ \(name, dat) -> do put_ bh name - field_p_p <- tellBin bh + field_p_p <- tellBinWriter bh put_ bh field_p_p return (field_p_p, dat) -- Now put the payloads and use the reserved space -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do - field_p <- tellBin bh + field_p <- tellBinWriter bh putAt bh field_p_p field_p - seekBin bh field_p + seekBinWriter bh field_p put_ bh dat get bh = do @@ -54,7 +54,7 @@ instance Binary ExtensibleFields where -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBin bh field_p + seekBinReader bh field_p dat <- get bh return (name, dat) @@ -72,7 +72,7 @@ emptyExtensibleFields = ExtensibleFields Map.empty readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) readField name = readFieldWith name get -readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith :: FieldName -> (ReadBinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> Map.lookup name (getExtensibleFields fields) @@ -82,7 +82,7 @@ readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields writeField name x = writeFieldWith name (`put_` x) -writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith :: FieldName -> (WriteBinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields writeFieldWith name write fields = do bh <- openBinMem (1024 * 1024) write bh ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -1032,7 +1032,7 @@ addFingerprints hsc_env iface0 -- change if the fingerprint for anything it refers to (transitively) -- changes. mk_put_name :: OccEnv (OccName,Fingerprint) - -> BinHandle -> Name -> IO () + -> WriteBinHandle -> Name -> IO () mk_put_name local_env bh name | isWiredInName name = putNameLiterally bh name -- wired-in names don't have fingerprints ===================================== compiler/GHC/Iface/Recomp/Binary.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Utils.Binary import GHC.Types.Name import GHC.Utils.Panic.Plain -fingerprintBinMem :: BinHandle -> IO Fingerprint +fingerprintBinMem :: WriteBinHandle -> IO Fingerprint fingerprintBinMem bh = withBinBuffer bh f where f bs = @@ -26,7 +26,7 @@ fingerprintBinMem bh = withBinBuffer bh f in fp `seq` return fp computeFingerprint :: (Binary a) - => (BinHandle -> Name -> IO ()) + => (WriteBinHandle -> Name -> IO ()) -> a -> IO Fingerprint computeFingerprint put_nonbinding_name a = do @@ -35,11 +35,11 @@ computeFingerprint put_nonbinding_name a = do fingerprintBinMem bh where set_user_data bh = - setUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS + setWriterUserData bh $ newWriteState put_nonbinding_name putNameLiterally putFS -- | Used when we want to fingerprint a structure without depending on the -- fingerprints of external Names that it refers to. -putNameLiterally :: BinHandle -> Name -> IO () +putNameLiterally :: WriteBinHandle -> Name -> IO () putNameLiterally bh name = assert (isExternalName name) $ do put_ bh $! nameModule name put_ bh $! nameOccName name ===================================== compiler/GHC/Iface/Recomp/Flags.hs ===================================== @@ -31,7 +31,7 @@ import System.FilePath (normalise) -- NB: The 'Module' parameter is the 'Module' recorded by the *interface* -- file, not the actual 'Module' according to our 'DynFlags'. fingerprintDynFlags :: HscEnv -> Module - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintDynFlags hsc_env this_mod nameio = @@ -88,7 +88,7 @@ fingerprintDynFlags hsc_env this_mod nameio = -- object files as they can. -- See Note [Ignoring some flag changes] fingerprintOptFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintOptFlags DynFlags{..} nameio = let @@ -106,7 +106,7 @@ fingerprintOptFlags DynFlags{..} nameio = -- file compiled for HPC when not actually using HPC. -- See Note [Ignoring some flag changes] fingerprintHpcFlags :: DynFlags - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -> IO Fingerprint fingerprintHpcFlags dflags at DynFlags{..} nameio = let ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -94,6 +94,7 @@ import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Proxy infixl 3 &&& @@ -118,15 +119,15 @@ type IfaceTopBndr = Name -- We don't serialise the namespace onto the disk though; rather we -- drop it when serialising and add it back in when deserialising. -getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr +getIfaceTopBndr :: ReadBinHandle -> IO IfaceTopBndr getIfaceTopBndr bh = get bh -putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO () +putIfaceTopBndr :: WriteBinHandle -> IfaceTopBndr -> IO () putIfaceTopBndr bh name = - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> + case findUserDataWriter (Proxy @BindingName) bh of + tbl -> --pprTrace "putIfaceTopBndr" (ppr name) $ - put_binding_name bh name + putEntry tbl bh (BindingName name) data IfaceDecl @@ -2444,13 +2445,13 @@ instance Binary IfGuidance where c <- get bh return (IfWhen a b c) -putUnfoldingCache :: BinHandle -> IfUnfoldingCache -> IO () +putUnfoldingCache :: WriteBinHandle -> IfUnfoldingCache -> IO () putUnfoldingCache bh (UnfoldingCache { uf_is_value = hnf, uf_is_conlike = conlike , uf_is_work_free = wf, uf_expandable = exp }) = do let b = zeroBits .<<|. hnf .<<|. conlike .<<|. wf .<<|. exp putByte bh b -getUnfoldingCache :: BinHandle -> IO IfUnfoldingCache +getUnfoldingCache :: ReadBinHandle -> IO IfUnfoldingCache getUnfoldingCache bh = do b <- getByte bh let hnf = testBit b 3 ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -9,7 +9,6 @@ This module defines interface types and binders {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} - module GHC.Iface.Type ( IfExtName, IfLclName, @@ -90,10 +89,10 @@ import GHC.Utils.Misc import GHC.Utils.Panic import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar ) -import Data.Maybe( isJust ) -import qualified Data.Semigroup as Semi import Control.DeepSeq import Control.Monad ((<$!>)) +import qualified Data.Semigroup as Semi +import Data.Maybe( isJust ) {- ************************************************************************ @@ -2045,11 +2044,12 @@ instance Outputable IfaceCoercion where ppr = pprIfaceCoercion instance Binary IfaceTyCon where - put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i + put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i - get bh = do n <- get bh - i <- get bh - return (IfaceTyCon n i) + get bh = do + n <- get bh + i <- get bh + return (IfaceTyCon n i) instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -66,6 +66,9 @@ import GHC.Prelude import Control.Monad import Data.Array +import qualified Data.ByteString as B +import qualified Data.ByteString.Unsafe as B +import Data.Char (isSpace) import Data.Int import Data.IntSet (IntSet) import qualified Data.IntSet as IS @@ -75,10 +78,7 @@ import Data.Map (Map) import qualified Data.Map as M import Data.Word import Data.Semigroup -import qualified Data.ByteString as B -import qualified Data.ByteString.Unsafe as B -import Data.Char (isSpace) -import System.IO +import System.IO import GHC.Settings.Constants (hiVersion) @@ -168,7 +168,7 @@ wasmHeader = unsafePerformIO $ B.unsafePackAddressLen 4 "\0asm"# data Object = Object { objModuleName :: !ModuleName -- ^ name of the module - , objHandle :: !BinHandle + , objHandle :: !ReadBinHandle -- ^ BinHandle that can be used to read the ObjBlocks , objPayloadOffset :: !(Bin ObjBlock) -- ^ Offset of the payload (units) @@ -253,7 +253,7 @@ instance Outputable ExportedFun where -- | Write an ObjBlock, except for the top level symbols which are stored in the -- index -putObjBlock :: BinHandle -> ObjBlock -> IO () +putObjBlock :: WriteBinHandle -> ObjBlock -> IO () putObjBlock bh (ObjBlock _syms b c d e f g) = do put_ bh b put_ bh c @@ -264,7 +264,7 @@ putObjBlock bh (ObjBlock _syms b c d e f g) = do -- | Read an ObjBlock and associate it to the given symbols (that must have been -- read from the index) -getObjBlock :: [FastString] -> BinHandle -> IO ObjBlock +getObjBlock :: [FastString] -> ReadBinHandle -> IO ObjBlock getObjBlock syms bh = do b <- get bh c <- get bh @@ -299,7 +299,7 @@ data IndexEntry = IndexEntry -- | Given a handle to a Binary payload, add the module, 'mod_name', its -- dependencies, 'deps', and its linkable units to the payload. putObject - :: BinHandle + :: WriteBinHandle -> ModuleName -- ^ module -> BlockInfo -- ^ block infos -> [ObjBlock] -- ^ linkable units and their symbols @@ -313,15 +313,16 @@ putObject bh mod_name deps os = do -- object in an archive. put_ bh (moduleNameString mod_name) - (bh_fs, _bin_dict, put_dict) <- initFSTable bh + (fs_tbl, fs_writer) <- initFastStringWriterTable + let bh_fs = addWriterToUserData (mkSomeBinaryWriter fs_writer) bh - forwardPut_ bh (const put_dict) $ do + forwardPut_ bh (const (putTable fs_tbl bh_fs)) $ do put_ bh_fs deps -- forward put the index forwardPut_ bh_fs (put_ bh_fs) $ do idx <- forM os $ \o -> do - p <- tellBin bh_fs + p <- tellBinWriter bh_fs -- write units without their symbols putObjBlock bh_fs o -- return symbols and offset to store in the index @@ -329,7 +330,7 @@ putObject bh mod_name deps os = do pure idx -- | Parse object header -getObjectHeader :: BinHandle -> IO (Either String ModuleName) +getObjectHeader :: ReadBinHandle -> IO (Either String ModuleName) getObjectHeader bh = do magic <- getByteString bh (B.length hsHeader) case magic == hsHeader of @@ -344,15 +345,15 @@ getObjectHeader bh = do -- | Parse object body. Must be called after a successful getObjectHeader -getObjectBody :: BinHandle -> ModuleName -> IO Object +getObjectBody :: ReadBinHandle -> ModuleName -> IO Object getObjectBody bh0 mod_name = do -- Read the string table dict <- forwardGet bh0 (getDictionary bh0) - let bh = setUserData bh0 $ noUserData { ud_get_fs = getDictFastString dict } + let bh = setReaderUserData bh0 $ newReadState (panic "No name allowed") (getDictFastString dict) block_info <- get bh idx <- forwardGet bh (get bh) - payload_pos <- tellBin bh + payload_pos <- tellBinReader bh pure $ Object { objModuleName = mod_name @@ -363,7 +364,7 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO (Maybe Object) +getObject :: ReadBinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case Left _err -> pure Nothing @@ -392,7 +393,7 @@ getObjectBlocks obj bids = mapMaybeM read_entry (zip (objIndex obj) [0..]) bh = objHandle obj read_entry (IndexEntry syms offset,i) | IS.member i bids = do - seekBin bh offset + seekBinReader bh offset Just <$> getObjBlock syms bh | otherwise = pure Nothing @@ -408,12 +409,12 @@ readObjectBlocks file bids = do -- Helper functions -------------------------------------------------------------------------------- -putEnum :: Enum a => BinHandle -> a -> IO () +putEnum :: Enum a => WriteBinHandle -> a -> IO () putEnum bh x | n > 65535 = error ("putEnum: out of range: " ++ show n) | otherwise = put_ bh n where n = fromIntegral $ fromEnum x :: Word16 -getEnum :: Enum a => BinHandle -> IO a +getEnum :: Enum a => ReadBinHandle -> IO a getEnum bh = toEnum . fromIntegral <$> (get bh :: IO Word16) -- | Helper to convert Int to Int32 @@ -778,7 +779,7 @@ writeJSObject opts contents output_fn = do -- | Read a JS object from BinHandle -parseJSObject :: BinHandle -> IO (JSOptions, B.ByteString) +parseJSObject :: ReadBinHandle -> IO (JSOptions, B.ByteString) parseJSObject bh = do magic <- getByteString bh (B.length jsHeader) case magic == jsHeader of ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -1010,7 +1010,7 @@ data TupleSort = BoxedTuple | UnboxedTuple | ConstraintTuple - deriving( Eq, Data ) + deriving( Eq, Data, Ord ) instance Outputable TupleSort where ppr ts = text $ ===================================== compiler/GHC/Types/FieldLabel.hs ===================================== @@ -140,9 +140,7 @@ instance Binary Name => Binary FieldLabel where put_ bh (FieldLabel aa ab ac) = do put_ bh aa put_ bh ab - case getUserData bh of - UserData{ ud_put_binding_name = put_binding_name } -> - put_binding_name bh ac + put_ bh ac get bh = do aa <- get bh ab <- get bh ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -663,12 +663,12 @@ instance Data Name where -- distinction. instance Binary Name where put_ bh name = - case getUserData bh of - UserData{ ud_put_nonbinding_name = put_name } -> put_name bh name + case findUserDataWriter Proxy bh of + tbl -> putEntry tbl bh name get bh = - case getUserData bh of - UserData { ud_get_name = get_name } -> get_name bh + case findUserDataReader Proxy bh of + tbl -> getEntry tbl bh {- ************************************************************************ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Utils.Binary ( {-type-} Bin, {-class-} Binary(..), - {-type-} BinHandle, + {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, BinData(..), dataHandle, handleData, @@ -30,8 +30,10 @@ module GHC.Utils.Binary openBinMem, -- closeBin, - seekBin, - tellBin, + seekBinWriter, + seekBinReader, + tellBinReader, + tellBinWriter, castBin, withBinBuffer, @@ -66,15 +68,28 @@ module GHC.Utils.Binary lazyPutMaybe, -- * User data - UserData(..), getUserData, setUserData, - newReadState, newWriteState, noUserData, - + ReaderUserData, getReaderUserData, setReaderUserData, noReaderUserData, + WriterUserData, getWriterUserData, setWriterUserData, noWriterUserData, + mkWriterUserData, mkReaderUserData, + newReadState, newWriteState, + addReaderToUserData, addWriterToUserData, + findUserDataReader, findUserDataWriter, + -- * Binary Readers & Writers + BinaryReader(..), BinaryWriter(..), + mkWriter, mkReader, + SomeBinaryReader, SomeBinaryWriter, + mkSomeBinaryReader, mkSomeBinaryWriter, + -- * Tables + ReaderTable(..), + WriterTable(..), -- * String table ("dictionary") + initFastStringReaderTable, initFastStringWriterTable, putDictionary, getDictionary, putFS, - FSTable, initFSTable, getDictFastString, putDictFastString, - + FSTable(..), getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), + -- * Newtypes for types that have canonically more than one valid encoding + BindingName(..), ) where import GHC.Prelude @@ -87,31 +102,37 @@ import GHC.Utils.Panic.Plain import GHC.Types.Unique.FM import GHC.Data.FastMutInt import GHC.Utils.Fingerprint +import GHC.Utils.Misc (HasCallStack) import GHC.Types.SrcLoc import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import GHC.Utils.Outputable( JoinPointHood(..) ) import Control.DeepSeq +import Control.Monad ( when, (<$!>), unless, forM_, void ) import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe import Data.ByteString (ByteString) +import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS import Data.IORef import Data.Char ( ord, chr ) import Data.List.NonEmpty ( NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Data.Proxy import Data.Set ( Set ) import qualified Data.Set as Set import Data.Time import Data.List (unfoldr) -import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType ) +import qualified Type.Reflection as Refl import GHC.Real ( Ratio(..) ) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap @@ -119,6 +140,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import Unsafe.Coerce (unsafeCoerce) + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -150,49 +173,91 @@ instance Binary BinData where copyBytes dest orig sz return (BinData sz dat) -dataHandle :: BinData -> IO BinHandle +dataHandle :: BinData -> IO ReadBinHandle dataHandle (BinData size bin) = do ixr <- newFastMutInt 0 - szr <- newFastMutInt size - binr <- newIORef bin - return (BinMem noUserData ixr szr binr) + return (ReadBinMem noReaderUserData ixr size bin) -handleData :: BinHandle -> IO BinData -handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +handleData :: WriteBinHandle -> IO BinData +handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- -data BinHandle - = BinMem { -- binary data stored in an unboxed array - bh_usr :: UserData, -- sigh, need parameterized modules :-) - _off_r :: !FastMutInt, -- the current offset - _sz_r :: !FastMutInt, -- size of the array (cached) - _arr_r :: !(IORef BinArray) -- the array (bounds: (0,size-1)) +-- | A write-only handle that can be used to serialise binary data into a buffer. +-- +-- The buffer is an unboxed binary array. +data WriteBinHandle + = WriteBinMem { + wbm_userData :: WriterUserData, + -- ^ User data for writing binary outputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + wbm_off_r :: !FastMutInt, -- ^ the current offset + wbm_sz_r :: !FastMutInt, -- ^ size of the array (cached) + wbm_arr_r :: !(IORef BinArray) -- ^ the array (bounds: (0,size-1)) } - -- XXX: should really store a "high water mark" for dumping out - -- the binary data to a file. -getUserData :: BinHandle -> UserData -getUserData bh = bh_usr bh +-- | A read-only handle that can be used to deserialise binary data from a buffer. +-- +-- The buffer is an unboxed binary array. +data ReadBinHandle + = ReadBinMem { + rbm_userData :: ReaderUserData, + -- ^ User data for reading binary inputs. + -- Allows users to overwrite certain 'Binary' instances. + -- This is helpful when a non-canonical 'Binary' instance is required, + -- such as in the case of 'Name'. + rbm_off_r :: !FastMutInt, -- ^ the current offset + rbm_sz_r :: !Int, -- ^ size of the array (cached) + rbm_arr_r :: !BinArray -- ^ the array (bounds: (0,size-1)) + } + +getReaderUserData :: ReadBinHandle -> ReaderUserData +getReaderUserData bh = rbm_userData bh + +getWriterUserData :: WriteBinHandle -> WriterUserData +getWriterUserData bh = wbm_userData bh -setUserData :: BinHandle -> UserData -> BinHandle -setUserData bh us = bh { bh_usr = us } +setWriterUserData :: WriteBinHandle -> WriterUserData -> WriteBinHandle +setWriterUserData bh us = bh { wbm_userData = us } + +setReaderUserData :: ReadBinHandle -> ReaderUserData -> ReadBinHandle +setReaderUserData bh us = bh { rbm_userData = us } + +-- | Add 'SomeBinaryReader' as a known binary decoder. +-- If a 'BinaryReader' for the associated type already exists in 'ReaderUserData', +-- it is overwritten. +addReaderToUserData :: SomeBinaryReader -> ReadBinHandle -> ReadBinHandle +addReaderToUserData cache@(SomeBinaryReader typRep _) bh = bh + { rbm_userData = (rbm_userData bh) + { ud_reader_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_reader_data (rbm_userData bh)) + } + } + +-- | Add 'SomeBinaryWriter' as a known binary encoder. +-- If a 'BinaryWriter' for the associated type already exists in 'WriterUserData', +-- it is overwritten. +addWriterToUserData :: SomeBinaryWriter -> WriteBinHandle -> WriteBinHandle +addWriterToUserData cache@(SomeBinaryWriter typRep _) bh = bh + { wbm_userData = (wbm_userData bh) + { ud_writer_data = Map.insert (Refl.SomeTypeRep typRep) cache (ud_writer_data (wbm_userData bh)) + } + } -- | Get access to the underlying buffer. -withBinBuffer :: BinHandle -> (ByteString -> IO a) -> IO a -withBinBuffer (BinMem _ ix_r _ arr_r) action = do - arr <- readIORef arr_r +withBinBuffer :: WriteBinHandle -> (ByteString -> IO a) -> IO a +withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do ix <- readFastMutInt ix_r + arr <- readIORef arr_r action $ BS.fromForeignPtr arr 0 ix -unsafeUnpackBinBuffer :: ByteString -> IO BinHandle +unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle unsafeUnpackBinBuffer (BS.BS arr len) = do - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt len - return (BinMem noUserData ix_r sz_r arr_r) + return (ReadBinMem noReaderUserData ix_r len arr) --------------------------------------------------------------- -- Bin @@ -211,23 +276,23 @@ castBin (BinPtr i) = BinPtr i -- | Do not rely on instance sizes for general types, -- we use variable length encoding for many of them. class Binary a where - put_ :: BinHandle -> a -> IO () - put :: BinHandle -> a -> IO (Bin a) - get :: BinHandle -> IO a + put_ :: WriteBinHandle -> a -> IO () + put :: WriteBinHandle -> a -> IO (Bin a) + get :: ReadBinHandle -> IO a -- define one of put_, put. Use of put_ is recommended because it -- is more likely that tail-calls can kick in, and we rarely need the -- position return value. put_ bh a = do _ <- put bh a; return () - put bh a = do p <- tellBin bh; put_ bh a; return p + put bh a = do p <- tellBinWriter bh; put_ bh a; return p -putAt :: Binary a => BinHandle -> Bin a -> a -> IO () -putAt bh p x = do seekBin bh p; put_ bh x; return () +putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () +putAt bh p x = do seekBinWriter bh p; put_ bh x; return () -getAt :: Binary a => BinHandle -> Bin a -> IO a -getAt bh p = do seekBin bh p; get bh +getAt :: Binary a => ReadBinHandle -> Bin a -> IO a +getAt bh p = do seekBinReader bh p; get bh -openBinMem :: Int -> IO BinHandle +openBinMem :: Int -> IO WriteBinHandle openBinMem size | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do @@ -235,45 +300,60 @@ openBinMem size arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt size - return (BinMem noUserData ix_r sz_r arr_r) + return WriteBinMem + { wbm_userData = noWriterUserData + , wbm_off_r = ix_r + , wbm_sz_r = sz_r + , wbm_arr_r = arr_r + } + +tellBinWriter :: WriteBinHandle -> IO (Bin a) +tellBinWriter (WriteBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -tellBin :: BinHandle -> IO (Bin a) -tellBin (BinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) +tellBinReader :: ReadBinHandle -> IO (Bin a) +tellBinReader (ReadBinMem _ r _ _) = do ix <- readFastMutInt r; return (BinPtr ix) -seekBin :: BinHandle -> Bin a -> IO () -seekBin h@(BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinWriter :: WriteBinHandle -> Bin a -> IO () +seekBinWriter h@(WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p --- | 'seekBinNoExpand' moves the index pointer to the location pointed to +-- | 'seekBinNoExpandWriter' moves the index pointer to the location pointed to -- by 'Bin a'. -- This operation may 'panic', if the pointer location is out of bounds of the -- buffer of 'BinHandle'. -seekBinNoExpand :: BinHandle -> Bin a -> IO () -seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do +seekBinNoExpandWriter :: WriteBinHandle -> Bin a -> IO () +seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do sz <- readFastMutInt sz_r if (p > sz) - then panic "seekBinNoExpand: seek out of range" + then panic "seekBinNoExpandWriter: seek out of range" else writeFastMutInt ix_r p -writeBinMem :: BinHandle -> FilePath -> IO () -writeBinMem (BinMem _ ix_r _ arr_r) fn = do +-- | SeekBin but without calling expandBin +seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do + if (p > sz_r) + then panic "seekBinReader: seek out of range" + else writeFastMutInt ix_r p + +writeBinMem :: WriteBinHandle -> FilePath -> IO () +writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode arr <- readIORef arr_r ix <- readFastMutInt ix_r unsafeWithForeignPtr arr $ \p -> hPutBuf h p ix hClose h -readBinMem :: FilePath -> IO BinHandle +readBinMem :: FilePath -> IO ReadBinHandle readBinMem filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h let filesize = fromIntegral filesize' readBinMem_ filesize h -readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle) +readBinMemN :: Int -> FilePath -> IO (Maybe ReadBinHandle) readBinMemN size filename = do withBinaryFile filename ReadMode $ \h -> do filesize' <- hFileSize h @@ -282,20 +362,23 @@ readBinMemN size filename = do then pure Nothing else Just <$> readBinMem_ size h -readBinMem_ :: Int -> Handle -> IO BinHandle +readBinMem_ :: Int -> Handle -> IO ReadBinHandle readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes") - arr_r <- newIORef arr ix_r <- newFastMutInt 0 - sz_r <- newFastMutInt filesize - return (BinMem noUserData ix_r sz_r arr_r) + return ReadBinMem + { rbm_userData = noReaderUserData + , rbm_off_r = ix_r + , rbm_sz_r = filesize + , rbm_arr_r = arr + } -- expand the size of the array to include a specified offset -expandBin :: BinHandle -> Int -> IO () -expandBin (BinMem _ _ sz_r arr_r) !off = do +expandBin :: WriteBinHandle -> Int -> IO () +expandBin (WriteBinMem _ _ sz_r arr_r) !off = do !sz <- readFastMutInt sz_r let !sz' = getSize sz arr <- readIORef arr_r @@ -316,7 +399,7 @@ expandBin (BinMem _ _ sz_r arr_r) !off = do foldGet :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -332,7 +415,7 @@ foldGet n bh init_b f = go 0 init_b foldGet' :: Binary a => Word -- n elements - -> BinHandle + -> ReadBinHandle -> b -- initial accumulator -> (Word -> a -> b -> IO b) -> IO b @@ -353,8 +436,8 @@ foldGet' n bh init_b f = go 0 init_b -- | Takes a size and action writing up to @size@ bytes. -- After the action has run advance the index to the buffer -- by size bytes. -putPrim :: BinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () -putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do +putPrim :: WriteBinHandle -> Int -> (Ptr Word8 -> IO ()) -> IO () +putPrim h@(WriteBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r sz <- readFastMutInt sz_r when (ix + size > sz) $ @@ -375,39 +458,37 @@ putPrim h@(BinMem _ ix_r sz_r arr_r) size f = do -- written <- withForeignPtr arr $ \op -> f (op `plusPtr` ix) -- writeFastMutInt ix_r (ix + written) -getPrim :: BinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a -getPrim (BinMem _ ix_r sz_r arr_r) size f = do +getPrim :: ReadBinHandle -> Int -> (Ptr Word8 -> IO a) -> IO a +getPrim (ReadBinMem _ ix_r sz_r arr_r) size f = do ix <- readFastMutInt ix_r - sz <- readFastMutInt sz_r - when (ix + size > sz) $ + when (ix + size > sz_r) $ ioError (mkIOError eofErrorType "Data.Binary.getPrim" Nothing Nothing) - arr <- readIORef arr_r - w <- unsafeWithForeignPtr arr $ \p -> f (p `plusPtr` ix) + w <- unsafeWithForeignPtr arr_r $ \p -> f (p `plusPtr` ix) -- This is safe WRT #17760 as we we guarantee that the above line doesn't -- diverge writeFastMutInt ix_r (ix + size) return w -putWord8 :: BinHandle -> Word8 -> IO () +putWord8 :: WriteBinHandle -> Word8 -> IO () putWord8 h !w = putPrim h 1 (\op -> poke op w) -getWord8 :: BinHandle -> IO Word8 +getWord8 :: ReadBinHandle -> IO Word8 getWord8 h = getPrim h 1 peek -putWord16 :: BinHandle -> Word16 -> IO () +putWord16 :: WriteBinHandle -> Word16 -> IO () putWord16 h w = putPrim h 2 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) ) -getWord16 :: BinHandle -> IO Word16 +getWord16 :: ReadBinHandle -> IO Word16 getWord16 h = getPrim h 2 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 return $! w0 `shiftL` 8 .|. w1 ) -putWord32 :: BinHandle -> Word32 -> IO () +putWord32 :: WriteBinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 24)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) @@ -415,7 +496,7 @@ putWord32 h w = putPrim h 4 (\op -> do pokeElemOff op 3 (fromIntegral (w .&. 0xFF)) ) -getWord32 :: BinHandle -> IO Word32 +getWord32 :: ReadBinHandle -> IO Word32 getWord32 h = getPrim h 4 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -428,7 +509,7 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) -putWord64 :: BinHandle -> Word64 -> IO () +putWord64 :: WriteBinHandle -> Word64 -> IO () putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) @@ -440,7 +521,7 @@ putWord64 h w = putPrim h 8 (\op -> do pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) ) -getWord64 :: BinHandle -> IO Word64 +getWord64 :: ReadBinHandle -> IO Word64 getWord64 h = getPrim h 8 (\op -> do w0 <- fromIntegral <$> peekElemOff op 0 w1 <- fromIntegral <$> peekElemOff op 1 @@ -461,10 +542,10 @@ getWord64 h = getPrim h 8 (\op -> do w7 ) -putByte :: BinHandle -> Word8 -> IO () +putByte :: WriteBinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w -getByte :: BinHandle -> IO Word8 +getByte :: ReadBinHandle -> IO Word8 getByte h = getWord8 h -- ----------------------------------------------------------------------------- @@ -487,15 +568,15 @@ getByte h = getWord8 h -- for now. -- Unsigned numbers -{-# SPECIALISE putULEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putULEB128 :: BinHandle -> Int16 -> IO () #-} -putULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> a -> IO () +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putULEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putULEB128 :: forall a. (Integral a, FiniteBits a) => WriteBinHandle -> a -> IO () putULEB128 bh w = #if defined(DEBUG) (if w < 0 then panic "putULEB128: Signed number" else id) $ @@ -512,15 +593,15 @@ putULEB128 bh w = putByte bh byte go (w `unsafeShiftR` 7) -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getULEB128 :: BinHandle -> IO Int16 #-} -getULEB128 :: forall a. (Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getULEB128 :: ReadBinHandle -> IO Int16 #-} +getULEB128 :: forall a. (Integral a, FiniteBits a) => ReadBinHandle -> IO a getULEB128 bh = go 0 0 where @@ -536,15 +617,15 @@ getULEB128 bh = return $! val -- Signed numbers -{-# SPECIALISE putSLEB128 :: BinHandle -> Word -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Word16 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int64 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int32 -> IO () #-} -{-# SPECIALISE putSLEB128 :: BinHandle -> Int16 -> IO () #-} -putSLEB128 :: forall a. (Integral a, Bits a) => BinHandle -> a -> IO () +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Word16 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int64 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int32 -> IO () #-} +{-# SPECIALISE putSLEB128 :: WriteBinHandle -> Int16 -> IO () #-} +putSLEB128 :: forall a. (Integral a, Bits a) => WriteBinHandle -> a -> IO () putSLEB128 bh initial = go initial where go :: a -> IO () @@ -564,15 +645,15 @@ putSLEB128 bh initial = go initial unless done $ go val' -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Word16 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int64 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int32 #-} -{-# SPECIALISE getSLEB128 :: BinHandle -> IO Int16 #-} -getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => BinHandle -> IO a +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Word16 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int64 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int32 #-} +{-# SPECIALISE getSLEB128 :: ReadBinHandle -> IO Int16 #-} +getSLEB128 :: forall a. (Show a, Integral a, FiniteBits a) => ReadBinHandle -> IO a getSLEB128 bh = do (val,shift,signed) <- go 0 0 if signed && (shift < finiteBitSize val ) @@ -983,63 +1064,63 @@ instance Binary (Bin a) where -- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B -- by using a forward reference -forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPut :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) forwardPut bh put_A put_B = do -- write placeholder pointer to A - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- write B r_b <- put_B -- update A's pointer - a <- tellBin bh + a <- tellBinWriter bh putAt bh pre_a a - seekBinNoExpand bh a + seekBinNoExpandWriter bh a -- write A r_a <- put_A r_b pure (r_a,r_b) -forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO () +forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: BinHandle -> IO a -> IO a +forwardGet :: ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr -- store current position - p_a <- tellBin bh + p_a <- tellBinReader bh -- go read the forward value, then seek back - seekBinNoExpand bh p + seekBinReader bh p r <- get_A - seekBinNoExpand bh p_a + seekBinReader bh p_a pure r -- ----------------------------------------------------------------------------- -- Lazy reading/writing -lazyPut :: Binary a => BinHandle -> a -> IO () +lazyPut :: Binary a => WriteBinHandle -> a -> IO () lazyPut bh a = do -- output the obj with a ptr to skip over it: - pre_a <- tellBin bh + pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr put_ bh a -- dump the object - q <- tellBin bh -- q = ptr to after object + q <- tellBinWriter bh -- q = ptr to after object putAt bh pre_a q -- fill in slot before a with ptr to q - seekBin bh q -- finally carry on writing at q + seekBinWriter bh q -- finally carry on writing at q -lazyGet :: Binary a => BinHandle -> IO a +lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet bh = do p <- get bh -- a BinPtr - p_a <- tellBin bh + p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh off_r variable in the child thread, for thread -- safety. off_r <- newFastMutInt 0 - getAt bh { _off_r = off_r } p_a - seekBin bh p -- skip over the object for now + getAt bh { rbm_off_r = off_r } p_a + seekBinReader bh p -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1047,14 +1128,14 @@ lazyGet bh = do -- -- This way we can check for the presence of a value without deserializing the -- value itself. -lazyPutMaybe :: Binary a => BinHandle -> Maybe a -> IO () +lazyPutMaybe :: Binary a => WriteBinHandle -> Maybe a -> IO () lazyPutMaybe bh Nothing = putWord8 bh 0 lazyPutMaybe bh (Just x) = do putWord8 bh 1 lazyPut bh x -- | Deserialize a value serialized by 'lazyPutMaybe'. -lazyGetMaybe :: Binary a => BinHandle -> IO (Maybe a) +lazyGetMaybe :: Binary a => ReadBinHandle -> IO (Maybe a) lazyGetMaybe bh = do h <- getWord8 bh case h of @@ -1065,7 +1146,9 @@ lazyGetMaybe bh = do -- UserData -- ----------------------------------------------------------------------------- --- | Information we keep around during interface file +-- Note [Binary UserData] +-- ~~~~~~~~~~~~~~~~~~~~~~ +-- Information we keep around during interface file -- serialization/deserialization. Namely we keep the functions for serializing -- and deserializing 'Name's and 'FastString's. We do this because we actually -- use serialization in two distinct settings, @@ -1084,73 +1167,230 @@ lazyGetMaybe bh = do -- non-binding Name is serialized as the fingerprint of the thing they -- represent. See Note [Fingerprinting IfaceDecls] for further discussion. -- -data UserData = - UserData { - -- for *deserialising* only: - ud_get_name :: BinHandle -> IO Name, - ud_get_fs :: BinHandle -> IO FastString, - - -- for *serialising* only: - ud_put_nonbinding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a non-binding 'Name' (e.g. a reference to another - -- binding). - ud_put_binding_name :: BinHandle -> Name -> IO (), - -- ^ serialize a binding 'Name' (e.g. the name of an IfaceDecl) - ud_put_fs :: BinHandle -> FastString -> IO () + +-- | Newtype to serialise binding names differently to non-binding 'Name'. +-- See Note [Binary UserData] +newtype BindingName = BindingName { getBindingName :: Name } + deriving ( Eq ) + +-- | Existential for 'BinaryWriter' with a type witness. +data SomeBinaryWriter = forall a . SomeBinaryWriter (Refl.TypeRep a) (BinaryWriter a) + +-- | Existential for 'BinaryReader' with a type witness. +data SomeBinaryReader = forall a . SomeBinaryReader (Refl.TypeRep a) (BinaryReader a) + +-- | UserData required to serialise symbols for interface files. +-- +-- See Note [Binary UserData] +data WriterUserData = + WriterUserData { + ud_writer_data :: Map Refl.SomeTypeRep SomeBinaryWriter + -- ^ A mapping from a type witness to the 'Writer' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryWriter)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryWriter + } + +-- | UserData required to deserialise symbols for interface files. +-- +-- See Note [Binary UserData] +data ReaderUserData = + ReaderUserData { + ud_reader_data :: Map Refl.SomeTypeRep SomeBinaryReader + -- ^ A mapping from a type witness to the 'Reader' for the associated type. + -- This is a 'Map' because microbenchmarks indicated this is more efficient + -- than other representations for less than ten elements. + -- + -- Considered representations: + -- + -- * [(TypeRep, SomeBinaryReader)] + -- * bytehash (on hackage) + -- * Map TypeRep SomeBinaryReader } -newReadState :: (BinHandle -> IO Name) -- ^ how to deserialize 'Name's - -> (BinHandle -> IO FastString) - -> UserData -newReadState get_name get_fs - = UserData { ud_get_name = get_name, - ud_get_fs = get_fs, - ud_put_nonbinding_name = undef "put_nonbinding_name", - ud_put_binding_name = undef "put_binding_name", - ud_put_fs = undef "put_fs" - } - -newWriteState :: (BinHandle -> Name -> IO ()) +mkWriterUserData :: [SomeBinaryWriter] -> WriterUserData +mkWriterUserData caches = noWriterUserData + { ud_writer_data = Map.fromList $ map (\cache@(SomeBinaryWriter typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkReaderUserData :: [SomeBinaryReader] -> ReaderUserData +mkReaderUserData caches = noReaderUserData + { ud_reader_data = Map.fromList $ map (\cache@(SomeBinaryReader typRep _) -> (Refl.SomeTypeRep typRep, cache)) caches + } + +mkSomeBinaryWriter :: forall a . Refl.Typeable a => BinaryWriter a -> SomeBinaryWriter +mkSomeBinaryWriter cb = SomeBinaryWriter (Refl.typeRep @a) cb + +mkSomeBinaryReader :: forall a . Refl.Typeable a => BinaryReader a -> SomeBinaryReader +mkSomeBinaryReader cb = SomeBinaryReader (Refl.typeRep @a) cb + +newtype BinaryReader s = BinaryReader + { getEntry :: ReadBinHandle -> IO s + } deriving (Functor) + +newtype BinaryWriter s = BinaryWriter + { putEntry :: WriteBinHandle -> s -> IO () + } + +mkWriter :: (WriteBinHandle -> s -> IO ()) -> BinaryWriter s +mkWriter f = BinaryWriter + { putEntry = f + } + +mkReader :: (ReadBinHandle -> IO s) -> BinaryReader s +mkReader f = BinaryReader + { getEntry = f + } + +-- | Find the 'BinaryReader' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryReader' has been configured before, this function will panic. +findUserDataReader :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> ReadBinHandle -> BinaryReader a +findUserDataReader query bh = + case Map.lookup (Refl.someTypeRep query) (ud_reader_data $ getReaderUserData bh) of + Nothing -> panic $ "Failed to find BinaryReader for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + unsafeCoerce @(BinaryReader x) @(BinaryReader a) reader + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryReader _ (reader :: BinaryReader x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryReader x) @(BinaryReader a) reader + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + +-- | Find the 'BinaryWriter' for the 'Binary' instance for the type identified by 'Proxy a'. +-- +-- If no 'BinaryWriter' has been configured before, this function will panic. +findUserDataWriter :: forall a . (HasCallStack, Refl.Typeable a) => Proxy a -> WriteBinHandle -> BinaryWriter a +findUserDataWriter query bh = + case Map.lookup (Refl.someTypeRep query) (ud_writer_data $ getWriterUserData bh) of + Nothing -> panic $ "Failed to find BinaryWriter for the key: " ++ show (Refl.someTypeRep query) + Just (SomeBinaryWriter _ (writer :: BinaryWriter x)) -> + unsafeCoerce @(BinaryWriter x) @(BinaryWriter a) writer + -- This 'unsafeCoerce' could be written safely like this: + -- + -- @ + -- Just (SomeBinaryWriter tyRep (writer :: BinaryWriter x)) -> + -- case testEquality (typeRep @a) tyRep of + -- Just Refl -> coerce @(BinaryWriter x) @(BinaryWriter a) writer + -- Nothing -> panic $ "Invariant violated" + -- @ + -- + -- But it comes at a slight performance cost and this function is used in + -- binary serialisation hot loops, thus, we prefer the small performance boost over + -- the additional type safety. + + +noReaderUserData :: ReaderUserData +noReaderUserData = ReaderUserData + { ud_reader_data = Map.empty + } + +noWriterUserData :: WriterUserData +noWriterUserData = WriterUserData + { ud_writer_data = Map.empty + } + +newReadState :: (ReadBinHandle -> IO Name) -- ^ how to deserialize 'Name's + -> (ReadBinHandle -> IO FastString) + -> ReaderUserData +newReadState get_name get_fs = + mkReaderUserData + [ mkSomeBinaryReader $ mkReader get_name + , mkSomeBinaryReader $ mkReader @BindingName (coerce get_name) + , mkSomeBinaryReader $ mkReader get_fs + ] + +newWriteState :: (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize non-binding 'Name's - -> (BinHandle -> Name -> IO ()) + -> (WriteBinHandle -> Name -> IO ()) -- ^ how to serialize binding 'Name's - -> (BinHandle -> FastString -> IO ()) - -> UserData -newWriteState put_nonbinding_name put_binding_name put_fs - = UserData { ud_get_name = undef "get_name", - ud_get_fs = undef "get_fs", - ud_put_nonbinding_name = put_nonbinding_name, - ud_put_binding_name = put_binding_name, - ud_put_fs = put_fs - } - -noUserData :: UserData -noUserData = UserData - { ud_get_name = undef "get_name" - , ud_get_fs = undef "get_fs" - , ud_put_nonbinding_name = undef "put_nonbinding_name" - , ud_put_binding_name = undef "put_binding_name" - , ud_put_fs = undef "put_fs" + -> (WriteBinHandle -> FastString -> IO ()) + -> WriterUserData +newWriteState put_non_binding_name put_binding_name put_fs = + mkWriterUserData + [ mkSomeBinaryWriter $ mkWriter (\bh name -> put_binding_name bh (getBindingName name)) + , mkSomeBinaryWriter $ mkWriter put_non_binding_name + , mkSomeBinaryWriter $ mkWriter put_fs + ] + +-- ---------------------------------------------------------------------------- +-- Types for lookup and deduplication tables. +-- ---------------------------------------------------------------------------- + +-- | A 'ReaderTable' describes how to deserialise a table from disk, +-- and how to create a 'BinaryReader' that looks up values in the deduplication table. +data ReaderTable a = ReaderTable + { getTable :: ReadBinHandle -> IO (SymbolTable a) + -- ^ Deserialise a list of elements into a 'SymbolTable'. + , mkReaderFromTable :: SymbolTable a -> BinaryReader a + -- ^ Given the table from 'getTable', create a 'BinaryReader' + -- that reads values only from the 'SymbolTable'. } -undef :: String -> a -undef s = panic ("Binary.UserData: no " ++ s) +-- | A 'WriterTable' is an interface any deduplication table can implement to +-- describe how the table can be written to disk. +newtype WriterTable = WriterTable + { putTable :: WriteBinHandle -> IO Int + -- ^ Serialise a table to disk. Returns the number of written elements. + } --------------------------------------------------------- -- The Dictionary --------------------------------------------------------- -type Dictionary = Array Int FastString -- The dictionary - -- Should be 0-indexed +-- | A 'SymbolTable' of 'FastString's. +type Dictionary = SymbolTable FastString + +initFastStringReaderTable :: IO (ReaderTable FastString) +initFastStringReaderTable = do + return $ + ReaderTable + { getTable = getDictionary + , mkReaderFromTable = \tbl -> mkReader (getDictFastString tbl) + } + +initFastStringWriterTable :: IO (WriterTable, BinaryWriter FastString) +initFastStringWriterTable = do + dict_next_ref <- newFastMutInt 0 + dict_map_ref <- newIORef emptyUFM + let bin_dict = + FSTable + { fs_tab_next = dict_next_ref + , fs_tab_map = dict_map_ref + } + let put_dict bh = do + fs_count <- readFastMutInt dict_next_ref + dict_map <- readIORef dict_map_ref + putDictionary bh fs_count dict_map + pure fs_count -putDictionary :: BinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () + return + ( WriterTable + { putTable = put_dict + } + , mkWriter $ putDictFastString bin_dict + ) + +putDictionary :: WriteBinHandle -> Int -> UniqFM FastString (Int,FastString) -> IO () putDictionary bh sz dict = do put_ bh sz mapM_ (putFS bh) (elems (array (0,sz-1) (nonDetEltsUFM dict))) -- It's OK to use nonDetEltsUFM here because the elements have indices -- that array uses to create order -getDictionary :: BinHandle -> IO Dictionary +getDictionary :: ReadBinHandle -> IO Dictionary getDictionary bh = do sz <- get bh :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int FastString) @@ -1159,34 +1399,12 @@ getDictionary bh = do writeArray mut_arr i fs unsafeFreeze mut_arr -getDictFastString :: Dictionary -> BinHandle -> IO FastString +getDictFastString :: Dictionary -> ReadBinHandle -> IO FastString getDictFastString dict bh = do j <- get bh return $! (dict ! fromIntegral (j :: Word32)) - -initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int) -initFSTable bh = do - dict_next_ref <- newFastMutInt 0 - dict_map_ref <- newIORef emptyUFM - let bin_dict = FSTable - { fs_tab_next = dict_next_ref - , fs_tab_map = dict_map_ref - } - let put_dict = do - fs_count <- readFastMutInt dict_next_ref - dict_map <- readIORef dict_map_ref - putDictionary bh fs_count dict_map - pure fs_count - - -- BinHandle with FastString writing support - let ud = getUserData bh - let ud_fs = ud { ud_put_fs = putDictFastString bin_dict } - let bh_fs = setUserData bh ud_fs - - return (bh_fs,bin_dict,put_dict) - -putDictFastString :: FSTable -> BinHandle -> FastString -> IO () +putDictFastString :: FSTable -> WriteBinHandle -> FastString -> IO () putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh allocateFastString :: FSTable -> FastString -> IO Word32 @@ -1215,43 +1433,42 @@ data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use -- The Symbol Table --------------------------------------------------------- --- On disk, the symbol table is an array of IfExtName, when --- reading it in we turn it into a SymbolTable. - -type SymbolTable = Array Int Name +-- | Symbols that are read from disk. +-- The 'SymbolTable' index starts on '0'. +type SymbolTable a = Array Int a --------------------------------------------------------- -- Reading and writing FastStrings --------------------------------------------------------- -putFS :: BinHandle -> FastString -> IO () +putFS :: WriteBinHandle -> FastString -> IO () putFS bh fs = putBS bh $ bytesFS fs -getFS :: BinHandle -> IO FastString +getFS :: ReadBinHandle -> IO FastString getFS bh = do l <- get bh :: IO Int getPrim bh l (\src -> pure $! mkFastStringBytes src l ) -- | Put a ByteString without its length (can't be read back without knowing the -- length!) -putByteString :: BinHandle -> ByteString -> IO () +putByteString :: WriteBinHandle -> ByteString -> IO () putByteString bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -- | Get a ByteString whose length is known -getByteString :: BinHandle -> Int -> IO ByteString +getByteString :: ReadBinHandle -> Int -> IO ByteString getByteString bh l = BS.create l $ \dest -> do getPrim bh l (\src -> copyBytes dest src l) -putBS :: BinHandle -> ByteString -> IO () +putBS :: WriteBinHandle -> ByteString -> IO () putBS bh bs = BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do put_ bh l putPrim bh l (\op -> copyBytes op (castPtr ptr) l) -getBS :: BinHandle -> IO ByteString +getBS :: ReadBinHandle -> IO ByteString getBS bh = do l <- get bh :: IO Int BS.create l $ \dest -> do @@ -1263,12 +1480,12 @@ instance Binary ByteString where instance Binary FastString where put_ bh f = - case getUserData bh of - UserData { ud_put_fs = put_fs } -> put_fs bh f + case findUserDataWriter (Proxy :: Proxy FastString) bh of + tbl -> putEntry tbl bh f get bh = - case getUserData bh of - UserData { ud_get_fs = get_fs } -> get_fs bh + case findUserDataReader (Proxy :: Proxy FastString) bh of + tbl -> getEntry tbl bh deriving instance Binary NonDetFastString deriving instance Binary LexicalFastString ===================================== compiler/GHC/Utils/Binary/Typeable.hs ===================================== @@ -35,7 +35,7 @@ instance Binary TyCon where get bh = mkTyCon <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh -getSomeTypeRep :: BinHandle -> IO SomeTypeRep +getSomeTypeRep :: ReadBinHandle -> IO SomeTypeRep getSomeTypeRep bh = do tag <- get bh :: IO Word8 case tag of @@ -167,7 +167,7 @@ instance Binary TypeLitSort where 2 -> pure TypeLitChar _ -> fail "Binary.putTypeLitSort: invalid tag" -putTypeRep :: BinHandle -> TypeRep a -> IO () +putTypeRep :: WriteBinHandle -> TypeRep a -> IO () putTypeRep bh rep -- Handle Type specially since it's so common | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = put_ bh (0 :: Word8) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 358307f6fa52daa2c2411a4975c87b30932af3dc +Subproject commit ccad8012338201e41580e159f0bd79afa349eb39 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94da936507c685aa8101a714e7619b4d428d0187...bac572986e19a1e8f2e7c91b368c18ddfeba92e5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94da936507c685aa8101a714e7619b4d428d0187...bac572986e19a1e8f2e7c91b368c18ddfeba92e5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:04:55 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:04:55 -0400 Subject: [Git][ghc/ghc][master] Fix missing escaping-kind check in tcPatSynSig Message-ID: <662c250723ac6_2fdea211aa24112446@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 8 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Tc.Gen.HsType ( tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsType, tcInferLHsTypeKind, tcInferLHsTypeUnsaturated, - tcCheckLHsTypeInContext, + tcCheckLHsTypeInContext, tcCheckLHsType, tcHsContext, tcLHsPredType, kindGeneralizeAll, @@ -496,7 +496,7 @@ tc_lhs_sig_type skol_info full_hs_ty@(L loc (HsSig { sig_bndrs = hs_outer_bndrs {- Note [Escaping kind in type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider kind-checking the signature for `foo` (#19495): +Consider kind-checking the signature for `foo` (#19495, #24686): type family T (r :: RuntimeRep) :: TYPE r foo :: forall (r :: RuntimeRep). T r @@ -508,7 +508,8 @@ because we allow signatures like `foo :: Int#`.) Suppose we are at level L currently. We do this * pushLevelAndSolveEqualitiesX: moves to level L+1 - * newExpectedKind: allocates delta{L+1} + * newExpectedKind: allocates delta{L+1}. Note carefully that + this call is /outside/ the tcOuterTKBndrs call. * tcOuterTKBndrs: pushes the level again to L+2, binds skolem r{L+2} * kind-check the body (T r) :: TYPE delta{L+1} @@ -607,9 +608,9 @@ tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs ; skol_info <- mkSkolemInfo skol_info_anon ; (tclvl, wanted, (outer_bndrs, ty)) <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $ - tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind (expectedKindInCtxt ctxt) - ; tc_check_lhs_type (mkMode tyki) body kind } + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tc_check_lhs_type (mkMode tyki) body kind } ; outer_bndrs <- scopedSortOuter outer_bndrs ; let outer_tv_bndrs = outerTyVarBndrs outer_bndrs ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -36,7 +36,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad -import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep ) +import GHC.Tc.Utils.TcMType ( checkTypeHasFixedRuntimeRep, newOpenTypeKind ) import GHC.Tc.Zonk.Type import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType @@ -386,14 +386,16 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty)))) <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $ -- See Note [Report unsolved equalities in tcPatSynSig] - tcOuterTKBndrs skol_info hs_outer_bndrs $ - tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ - do { req <- tcHsContext hs_req - ; prov <- tcHsContext hs_prov - ; body_ty <- tcHsOpenType hs_body_ty - -- A (literal) pattern can be unlifted; - -- e.g. pattern Zero <- 0# (#12094) - ; return (req, prov, body_ty) } + do { res_kind <- newOpenTypeKind + -- "open" because a (literal) pattern can be unlifted; + -- e.g. pattern Zero <- 0# (#12094) + -- See Note [Escaping kind in type signatures] in GHC.Tc.Gen.HsType + ; tcOuterTKBndrs skol_info hs_outer_bndrs $ + tcExplicitTKBndrs skol_info ex_hs_tvbndrs $ + do { req <- tcHsContext hs_req + ; prov <- tcHsContext hs_prov + ; body_ty <- tcCheckLHsType hs_body_ty res_kind + ; return (req, prov, body_ty) } } ; let implicit_tvs :: [TcTyVar] univ_bndrs :: [TcInvisTVBinder] ===================================== testsuite/tests/polykinds/T24686.hs ===================================== @@ -0,0 +1,28 @@ +{-# LANGUAGE ViewPatterns, PatternSynonyms #-} +module T24686 where + +import GHC.Exts +import GHC.Stack + +{- + on GHC 9.4 / 9.6 / 9.8 this panics with + : error: + panic! (the 'impossible' happened) + GHC version 9.4.8: + typeKind + forall {r :: RuntimeRep} (a :: TYPE r). a + [r_aNu, a_aNy] + a_aNy :: TYPE r_aNu + Call stack: + CallStack (from HasCallStack): + callStackDoc, called at compiler/GHC/Utils/Panic.hs:182:37 in ghc:GHC.Utils.Panic + pprPanic, called at compiler/GHC/Core/Type.hs:3059:18 in ghc:GHC.Core.Type + + This regression test exists to make sure the fix introduced between 9.8 and 9.11 does not get removed + again. +-} + +pattern Bug :: forall. HasCallStack => forall {r :: RuntimeRep} (a :: TYPE r). a +pattern Bug <- (undefined -> _unused) + where + Bug = undefined ===================================== testsuite/tests/polykinds/T24686.stderr ===================================== @@ -0,0 +1,7 @@ + +T24686.hs:25:80: error: [GHC-25897] + Couldn't match kind ‘r’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE r’ + ‘r’ is a rigid type variable bound by + the type signature for ‘Bug’ + at T24686.hs:25:48 ===================================== testsuite/tests/polykinds/T24686a.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneKindSignatures #-} +module T24686a where + +import GHC.Exts + +-- This one crashed GHC too: see #24686 + +type T :: forall a (b:: TYPE a). b +data T ===================================== testsuite/tests/polykinds/T24686a.stderr ===================================== @@ -0,0 +1,8 @@ + +T24686a.hs:8:34: error: [GHC-25897] + • Couldn't match kind ‘a’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘b’ has kind ‘TYPE a’ + ‘a’ is a rigid type variable bound by + a standalone kind signature for ‘T’ + at T24686a.hs:8:18 + • In a standalone kind signature for ‘T’: forall a (b :: TYPE a). b ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -245,3 +245,5 @@ test('T22742', normal, compile_fail, ['']) test('T22793', normal, compile_fail, ['']) test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) +test('T24686', normal, compile_fail, ['']) +test('T24686a', normal, compile_fail, ['']) ===================================== testsuite/tests/rep-poly/RepPolyPatSynRes.stderr ===================================== @@ -1,4 +1,7 @@ -RepPolyPatSynRes.hs:13:1: error: [GHC-18478] - The pattern synonym scrutinee does not have a fixed runtime representation: - • a :: TYPE rep +RepPolyPatSynRes.hs:13:59: error: [GHC-25897] + Couldn't match kind ‘rep’ with ‘LiftedRep’ + Expected kind ‘*’, but ‘a’ has kind ‘TYPE rep’ + ‘rep’ is a rigid type variable bound by + the type signature for ‘Pat’ + at RepPolyPatSynRes.hs:13:23-25 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d6394dde448341fc222bf7b2aecac04c751d48d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d6394dde448341fc222bf7b2aecac04c751d48d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:05:54 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:05:54 -0400 Subject: [Git][ghc/ghc][master] EPA: check-exact: check that the roundtrip reproduces the source Message-ID: <662c254211a1a_2fdea22f92781170db@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - 2 changed files: - testsuite/tests/printer/PprExportWarn.hs - utils/check-exact/Main.hs Changes: ===================================== testsuite/tests/printer/PprExportWarn.hs ===================================== @@ -6,12 +6,12 @@ module PprExportWarning ( reallyreallyreallyreallyreallyreallyreallyreallylongname, {-# DEPRECATED "Just because" #-} Bar(Bar1, Bar2), {-# WARNING "Just because" #-} name, - {-# DEPRECATED ["Reason", - "Another reason"] #-} + {-# DEPRECATED ["Reason", + "Another reason"] #-} Baz, {-# DEPRECATED [ ] #-} module GHC, {-# WARNING "Dummy Pattern" #-} pattern Dummy, - Foo'(..), + Foo'(..), reallyreallyreallyreallyreallyreallyreallyreallylongname', Bar'(Bar1, Bar2), name', Baz', module Data.List, pattern Dummy' ) where ===================================== utils/check-exact/Main.hs ===================================== @@ -319,8 +319,10 @@ testOneFile _ libdir fileName mchanger = do expectedSource <- readFile newFileExpected changedSource <- readFile newFileChanged return (expectedSource == changedSource, expectedSource, changedSource) - Nothing -> return (True, "", "") - + Nothing -> do + expectedSource <- readFile fileName + changedSource <- readFile newFile + return (expectedSource == changedSource, expectedSource, changedSource) (p',_) <- parseOneFile libdir newFile let newAstStr :: String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/981c2c2c5017cb7ae47babff4d2163324d7cbde6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/981c2c2c5017cb7ae47babff4d2163324d7cbde6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:06:34 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:06:34 -0400 Subject: [Git][ghc/ghc][master] Document that setEnv is not thread-safe Message-ID: <662c256ab8e4a_2fdea1faa5e01201ab@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 2 changed files: - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment.hs ===================================== @@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv" -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 setEnv :: String -> String -> IO () setEnv key_ value_ @@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt -- Throws `Control.Exception.IOException` if @name@ is the empty string or -- contains an equals sign. -- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. +-- -- @since base-4.7.0.0 unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) ===================================== libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc ===================================== @@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values -- and mimics the function signature of 'System.Posix.Env.setEnv' from the -- @unix@ package. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. setEnv :: String {- ^ variable name -} -> String {- ^ variable value -} -> @@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv" -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of -- blank environment variables. May throw an exception if the underlying -- platform doesn't support unsetting of environment variables. +-- +-- Beware that this function must not be executed concurrently +-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread +-- reading environment variables at the same time with another one modifying them +-- can result in a segfault, see +-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html) +-- for discussion. unsetEnv :: String -> IO () #if defined(mingw32_HOST_OS) unsetEnv key = withCWString key $ \k -> do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a86167471a7a471fb75ae9ba6c641bd1e74bc16d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a86167471a7a471fb75ae9ba6c641bd1e74bc16d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:07:04 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:07:04 -0400 Subject: [Git][ghc/ghc][master] CI: Work around frequent Signal 9 errors Message-ID: <662c2588c1fc7_2fdea2516d1c122179@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -297,6 +297,12 @@ lint-ci-config: GIT_SUBMODULE_STRATEGY: none before_script: - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + # Note [Nix-in-Docker] + # ~~~~~~~~~~~~~~~~~~~~ + # FIXME: This is a workaround for a Nix-in-Docker issue. See + # https://gitlab.haskell.org/ghc/head.hackage/-/issues/38#note_560487 for + # discussion. + - nix-shell -p gnused --run "sed -i -e 's/nixbld//' /etc/nix/nix.conf" script: - nix run .gitlab/generate-ci#generate-jobs # 1 if .gitlab/generate_jobs changed the output of the generated config @@ -1106,6 +1112,8 @@ project-version: GIT_SUBMODULE_STRATEGY: "none" before_script: - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + # FIXME: See Note [Nix-in-Docker] + - nix-shell -p gnused --run "sed -i -e 's/nixbld//' /etc/nix/nix.conf" - nix-channel --update - cat version.sh # Calculate the project version View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e41de83285ddc2e527d46e2fbad54f990465e8a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e41de83285ddc2e527d46e2fbad54f990465e8a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:19:13 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 26 Apr 2024 18:19:13 -0400 Subject: [Git][ghc/ghc][wip/T24726] 9 commits: Refactor the Binary serialisation interface Message-ID: <662c2861c013c_2fdea274cac812403@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24726 at Glasgow Haskell Compiler / GHC Commits: fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - f1861000 by Simon Peyton Jones at 2024-04-26T23:19:05+01:00 Track in-scope variables in ruleCheckProgram This small patch fixes #24726, by tracking in-scope variables properly in -drule-check. Not hard to do! - - - - - eaa2b476 by Simon Peyton Jones at 2024-04-26T23:19:05+01:00 Add a couple more HasCallStack constraints in SimpleOpt Just for debugging, no effect on normal code - - - - - 8a8e6bbb by Simon Peyton Jones at 2024-04-26T23:19:05+01:00 Add comments to Prep.hs This documentation patch fixes a TODO left over from !12364 - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/printer/PprExportWarn.hs - testsuite/tests/rep-poly/RepPolyPatSynRes.stderr - + testsuite/tests/simplCore/should_compile/T24726.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68820dd43b3162ebbc8fedf66a527b56070bb14c...8a8e6bbb656339524a5ec23be06df7ff243833d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68820dd43b3162ebbc8fedf66a527b56070bb14c...8a8e6bbb656339524a5ec23be06df7ff243833d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 26 22:36:47 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 26 Apr 2024 18:36:47 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Refactor the Binary serialisation interface Message-ID: <662c2c7f511f8_2fdea29dfa9c132469@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - 7cde461f by Naïm Favier at 2024-04-26T18:36:39-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - libraries/base/changelog.md - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment.hs - libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - + testsuite/tests/polykinds/T24686.hs - + testsuite/tests/polykinds/T24686.stderr - + testsuite/tests/polykinds/T24686a.hs - + testsuite/tests/polykinds/T24686a.stderr - testsuite/tests/polykinds/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9028ad549e217f55055ab635faf51be729dd41f3...7cde461f4732c963c4fb448d95f700a9307a042c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9028ad549e217f55055ab635faf51be729dd41f3...7cde461f4732c963c4fb448d95f700a9307a042c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 16:05:40 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 27 Apr 2024 12:05:40 -0400 Subject: [Git][ghc/ghc] Pushed new tag ghc-9.10.1-rc1 Message-ID: <662d2254dc50d_2c70e41d2e3e886931@gitlab.mail> Ben Gamari pushed new tag ghc-9.10.1-rc1 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/ghc-9.10.1-rc1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 17:13:47 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 27 Apr 2024 13:13:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghcup Message-ID: <662d324bb673a_2c70e425292a089356@gitlab.mail> Ben Gamari pushed new branch wip/ghcup at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghcup You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 17:14:13 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 27 Apr 2024 13:14:13 -0400 Subject: [Git][ghc/ghc][wip/ghcup] ghcup-metadata: Drop output_name field Message-ID: <662d3265a56ba_2c70e425691e88954a@gitlab.mail> Ben Gamari pushed to branch wip/ghcup at Glasgow Haskell Compiler / GHC Commits: fe1ea0d2 by Ben Gamari at 2024-04-27T13:14:07-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 1 changed file: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe1ea0d213a0e8cd8540ff35bc7778e27b8f5ad7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe1ea0d213a0e8cd8540ff35bc7778e27b8f5ad7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 19:12:36 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 27 Apr 2024 15:12:36 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: ghc-internal: add MonadFix instance for (,) Message-ID: <662d4e24a61b9_2c70e432d20b4958f8@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 742a3475 by Naïm Favier at 2024-04-27T15:12:27-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - b507fad4 by Rodrigo Mesquita at 2024-04-27T15:12:27-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 7 changed files: - distrib/configure.ac.in - libraries/base/changelog.md - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 Changes: ===================================== distrib/configure.ac.in ===================================== @@ -114,16 +114,16 @@ if test "$HostOS" = "darwin"; then # The following is the work around suggested by @carter in #17418 during # install time. This should help us with code signing issues by removing # extended attributes from all files. - XATTR=${XATTR:-/usr/bin/xattr} + XATTR="${XATTR:-/usr/bin/xattr}" - if [ -e "${XATTR}" ]; then + if test -e "${XATTR}"; then # Instead of cleaning the attributes of the ghc-toolchain binary only, # we clean them from all files in the bin/ and lib/ directories, as it additionally future # proofs running executables from the bindist besides ghc-toolchain at configure time, and # we can avoid figuring out the path to the ghc-toolchain dynlib specifically. - /usr/bin/xattr -rc bin/ - /usr/bin/xattr -rc lib/ + "$XATTR" -rc bin/ + "$XATTR" -rc lib/ fi fi ===================================== libraries/base/changelog.md ===================================== @@ -1,6 +1,7 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.21.0.0 *TBA* + * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs ===================================== @@ -30,13 +30,13 @@ module GHC.Internal.Control.Monad.Fix ( import GHC.Internal.Data.Either import GHC.Internal.Data.Function ( fix ) import GHC.Internal.Data.Maybe -import GHC.Internal.Data.Monoid ( Dual(..), Sum(..), Product(..) +import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..) , First(..), Last(..), Alt(..), Ap(..) ) import GHC.Internal.Data.Ord ( Down(..) ) +import GHC.Internal.Data.Tuple ( Solo(..), snd ) import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) ) import GHC.Internal.Generics import GHC.Internal.List ( head, drop ) -import GHC.Tuple (Solo (..)) import GHC.Internal.Control.Monad.ST.Imp import GHC.Internal.System.IO @@ -72,6 +72,11 @@ instance MonadFix Solo where mfix f = let a = f (unSolo a) in a where unSolo (MkSolo x) = x +-- | @since base-4.21 +instance Monoid a => MonadFix ((,) a) where + -- See the CLC proposal thread for discussion and proofs of the laws: https://github.com/haskell/core-libraries-committee/issues/238 + mfix f = let a = f (snd a) in a + -- | @since base-2.01 instance MonadFix Maybe where mfix f = let a = f (unJust a) in a ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -14418,6 +14418,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -11647,6 +11647,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cde461f4732c963c4fb448d95f700a9307a042c...b507fad4031b79358957c6630a883ec3fe255cbf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cde461f4732c963c4fb448d95f700a9307a042c...b507fad4031b79358957c6630a883ec3fe255cbf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 21:53:16 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 27 Apr 2024 17:53:16 -0400 Subject: [Git][ghc/ghc][master] ghc-internal: add MonadFix instance for (,) Message-ID: <662d73ccb19fd_2c70e446d34281073b4@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 6 changed files: - libraries/base/changelog.md - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 Changes: ===================================== libraries/base/changelog.md ===================================== @@ -1,6 +1,7 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.21.0.0 *TBA* + * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) ## 4.20.0.0 *TBA* ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs ===================================== @@ -30,13 +30,13 @@ module GHC.Internal.Control.Monad.Fix ( import GHC.Internal.Data.Either import GHC.Internal.Data.Function ( fix ) import GHC.Internal.Data.Maybe -import GHC.Internal.Data.Monoid ( Dual(..), Sum(..), Product(..) +import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..) , First(..), Last(..), Alt(..), Ap(..) ) import GHC.Internal.Data.Ord ( Down(..) ) +import GHC.Internal.Data.Tuple ( Solo(..), snd ) import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) ) import GHC.Internal.Generics import GHC.Internal.List ( head, drop ) -import GHC.Tuple (Solo (..)) import GHC.Internal.Control.Monad.ST.Imp import GHC.Internal.System.IO @@ -72,6 +72,11 @@ instance MonadFix Solo where mfix f = let a = f (unSolo a) in a where unSolo (MkSolo x) = x +-- | @since base-4.21 +instance Monoid a => MonadFix ((,) a) where + -- See the CLC proposal thread for discussion and proofs of the laws: https://github.com/haskell/core-libraries-committee/issues/238 + mfix f = let a = f (snd a) in a + -- | @since base-2.01 instance MonadFix Maybe where mfix f = let a = f (unJust a) in a ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -14418,6 +14418,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -11647,6 +11647,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a6d5f9da898ea69604503aeb713132d87028beae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a6d5f9da898ea69604503aeb713132d87028beae You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 27 21:53:59 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 27 Apr 2024 17:53:59 -0400 Subject: [Git][ghc/ghc][master] bindist: Fix xattr cleaning Message-ID: <662d73f734f24_2c70e44854c841121d6@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 1 changed file: - distrib/configure.ac.in Changes: ===================================== distrib/configure.ac.in ===================================== @@ -114,16 +114,16 @@ if test "$HostOS" = "darwin"; then # The following is the work around suggested by @carter in #17418 during # install time. This should help us with code signing issues by removing # extended attributes from all files. - XATTR=${XATTR:-/usr/bin/xattr} + XATTR="${XATTR:-/usr/bin/xattr}" - if [ -e "${XATTR}" ]; then + if test -e "${XATTR}"; then # Instead of cleaning the attributes of the ghc-toolchain binary only, # we clean them from all files in the bin/ and lib/ directories, as it additionally future # proofs running executables from the bindist besides ghc-toolchain at configure time, and # we can avoid figuring out the path to the ghc-toolchain dynlib specifically. - /usr/bin/xattr -rc bin/ - /usr/bin/xattr -rc lib/ + "$XATTR" -rc bin/ + "$XATTR" -rc lib/ fi fi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64feadcddb6b9bcb45312fb872ec6842df68788a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64feadcddb6b9bcb45312fb872ec6842df68788a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 08:32:30 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Sun, 28 Apr 2024 04:32:30 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] WIP Message-ID: <662e099eccd36_3c2687d1bce4525b6@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: 1ac6d7a2 by Jade at 2024-04-28T10:37:27+02:00 WIP - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs ===================================== @@ -1645,8 +1645,14 @@ Further improved using a four-way merge, with an additional performance increase https://gitlab.haskell.org/ghc/ghc/issues/24280 -} -sort = sortBy compare -sortBy cmp ns +{-# INLINEABLE sort #-} -- allows specialization for the ord instance +sort = actualSort (>) + +{-# INLINEABLE sortBy #-} +sortBy cmp = actualSort (\x y -> cmp x y == GT) + +actualSort :: (a -> a -> Bool) -> [a] -> [a] +actualSort gt ns | [] <- ns = [] | [a] <- ns = [a] | [a,b] <- ns = merge [a] [b] @@ -1654,8 +1660,6 @@ sortBy cmp ns | [a,b,c,d] <- ns = merge4 [a] [b] [c] [d] | otherwise = merge_all (sequences ns) where - x `gt` y = x `cmp` y == GT - sequences (a:b:xs) | a `gt` b = descending b [a] xs | otherwise = ascending b (a:) xs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ac6d7a2c60118e25373cd78413ec887c212d2a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ac6d7a2c60118e25373cd78413ec887c212d2a7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 12:08:54 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Sun, 28 Apr 2024 08:08:54 -0400 Subject: [Git][ghc/ghc][wip/document-system-io] 154 commits: configure: Use LDFLAGS when trying linkers Message-ID: <662e3c56389ff_3c268725e37b875624@gitlab.mail> Jade pushed to branch wip/document-system-io at Glasgow Haskell Compiler / GHC Commits: 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 01b79ac7 by Jade at 2024-04-28T10:44:05+02:00 Documentation: Improve documentation for symbols exported from System.IO - - - - - 88faaea4 by Jade at 2024-04-28T14:13:43+02:00 WIP - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fb70cedda4dccf222dcb57c541bffe38a15e5f8d...88faaea43152ba2a324d5f9e8a2798b9f736a78d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fb70cedda4dccf222dcb57c541bffe38a15e5f8d...88faaea43152ba2a324d5f9e8a2798b9f736a78d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 12:40:58 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 28 Apr 2024 08:40:58 -0400 Subject: [Git][ghc/ghc][wip/az/T24708-epa-match-pats-comments] 17 commits: driver: force merge objects when building dynamic objects Message-ID: <662e43da43076_3c268729d92f078539@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T24708-epa-match-pats-comments at Glasgow Haskell Compiler / GHC Commits: d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - ac1d70ea by Alan Zimmerman at 2024-04-28T13:40:31+01:00 EPA: Preserve comments in Match Pats Preserves comments for code like expandProcess outCHAs -- comment locationDescr = blah Closes #24708 - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Builtin/Types.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Binary/Typeable.hs - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Builder.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Gmp.hs - libraries/ghc-bignum/gmp/gmp-tarballs - − libraries/ghc-bignum/gmp/gmpsrc.patch - − libraries/ghc-bignum/gmp/ln The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab9a6564365adfdc4334584d36a795b912ba392c...ac1d70ea47e9f346e0b91d02dace6351177e88d8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab9a6564365adfdc4334584d36a795b912ba392c...ac1d70ea47e9f346e0b91d02dace6351177e88d8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 15:20:28 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 28 Apr 2024 11:20:28 -0400 Subject: [Git][ghc/ghc][wip/az/T24708-epa-match-pats-comments] EPA: Preserve comments in Match Pats Message-ID: <662e693c488cb_3c26873c49ea897272@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T24708-epa-match-pats-comments at Glasgow Haskell Compiler / GHC Commits: d80b89c3 by Alan Zimmerman at 2024-04-28T16:19:50+01:00 EPA: Preserve comments in Match Pats Preserves comments for code like expandProcess outCHAs -- comment locationDescr = blah Closes #24708 Closes #24715 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1228,14 +1228,17 @@ checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do - p <- checkAPat loc e - return (L l p) + let (loc', l') = transferCommentsOnlyA loc l + p <- checkAPat loc' e + return (L l' p) checkPat loc e _ _ = do details <- fromParseContext <$> askParseContext patFail (locA loc) (PsErrInPat (unLoc e) details) @@ -1432,20 +1435,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1464,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,12 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d80b89c34194938ec47af8dcada31cdac2595331 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d80b89c34194938ec47af8dcada31cdac2595331 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 16:19:16 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 28 Apr 2024 12:19:16 -0400 Subject: [Git][ghc/ghc][wip/az/T24708-epa-match-pats-comments] EPA: Preserve comments in Match Pats Message-ID: <662e77043231b_3c268743466481013d3@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T24708-epa-match-pats-comments at Glasgow Haskell Compiler / GHC Commits: 647ff977 by Alan Zimmerman at 2024-04-28T17:17:39+01:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/647ff977908c89efeb3755a0521bc995629f8964 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/647ff977908c89efeb3755a0521bc995629f8964 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 19:02:32 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 28 Apr 2024 15:02:32 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: ghc-internal: add MonadFix instance for (,) Message-ID: <662e9d4879ad8_13c1a1f1c764743d1@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - f4ba5776 by Alan Zimmerman at 2024-04-28T15:02:14-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 19 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - distrib/configure.ac.in - docs/users_guide/bugs.rst - libraries/base/changelog.md - libraries/base/tests/char001.hs - libraries/base/tests/char001.stdout - libraries/base/tests/lex001.hs - libraries/base/tests/lex001.stdout - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== distrib/configure.ac.in ===================================== @@ -114,16 +114,16 @@ if test "$HostOS" = "darwin"; then # The following is the work around suggested by @carter in #17418 during # install time. This should help us with code signing issues by removing # extended attributes from all files. - XATTR=${XATTR:-/usr/bin/xattr} + XATTR="${XATTR:-/usr/bin/xattr}" - if [ -e "${XATTR}" ]; then + if test -e "${XATTR}"; then # Instead of cleaning the attributes of the ghc-toolchain binary only, # we clean them from all files in the bin/ and lib/ directories, as it additionally future # proofs running executables from the bindist besides ghc-toolchain at configure time, and # we can avoid figuring out the path to the ghc-toolchain dynlib specifically. - /usr/bin/xattr -rc bin/ - /usr/bin/xattr -rc lib/ + "$XATTR" -rc bin/ + "$XATTR" -rc lib/ fi fi ===================================== docs/users_guide/bugs.rst ===================================== @@ -445,15 +445,15 @@ In ``Prelude`` support ``Read``\ ing integers GHC's implementation of the ``Read`` class for integral types - accepts hexadecimal and octal literals (the code in the Haskell 98 + accepts hexadecimal, octal and binary literals (the code in the Haskell 98 report doesn't). So, for example, :: read "0xf00" :: Int works in GHC. - A possible reason for this is that ``readLitChar`` accepts hex and - octal escapes, so it seems inconsistent not to do so for integers + This is to maintain consistency with the language's syntax. Haskell98 + accepts hexadecimal and octal formats, and GHC2021 accepts binary formats too. ``isAlpha`` ===================================== libraries/base/changelog.md ===================================== @@ -1,7 +1,9 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.21.0.0 *TBA* + * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) + * Make `read` accept binary integer notation ([CLC proposal #177](https://github.com/haskell/core-libraries-committee/issues/177)) ## 4.20.0.0 *TBA* * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) ===================================== libraries/base/tests/char001.hs ===================================== @@ -1,7 +1,8 @@ -- !!! Testing the behaviour of Char.lexLitChar a little.. --- [March 2003] We now allow \X and \O as escapes although the --- spec only permits \x and \o. Seems more consistent. +-- [March 2003] We now allow \X and \O as escapes although the +-- spec only permits \x and \o. Seems more consistent. +-- [January 2024] Binary character literals, something like '\b100' are not permitted. module Main where @@ -33,9 +34,15 @@ octs = do lex' "'\\o14b'" lex' "'\\0a4bg'" +-- Binaries are NOT supported. '\b' stands for backspace. +bins = do + lex' "'\\b'" + lex' "'\\b00'" + main = do hexes octs + bins ===================================== libraries/base/tests/char001.stdout ===================================== @@ -16,3 +16,5 @@ lex '\O000024' = [("'\\O000024'","")] lex '\024b' = [] lex '\o14b' = [] lex '\0a4bg' = [] +lex '\b' = [("'\\b'","")] +lex '\b00' = [] ===================================== libraries/base/tests/lex001.hs ===================================== @@ -27,7 +27,23 @@ testStrings "035e-3x", "35e+3y", "83.3e-22", - "083.3e-22" + "083.3e-22", + + "0b001", + "0b100", + "0b110", + "0B001", + "0B100", + "0B110", + + "78_91", + "678_346", + "0x23d_fa4", + "0X23d_fa4", + "0o01_253", + "0O304_367", + "0b0101_0110", + "0B11_010_0110" ] main = mapM test testStrings ===================================== libraries/base/tests/lex001.stdout ===================================== @@ -82,3 +82,58 @@ [("083.3e-22","")] [(Number (MkDecimal [0,8,3] (Just [3]) (Just (-22))),"")] +"0b001" +[("0b001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0b100" +[("0b100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0b110" +[("0b110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"0B001" +[("0B001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0B100" +[("0B100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0B110" +[("0B110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"78_91" +[("78","_91")] +[(Number (MkDecimal [7,8] Nothing Nothing),"_91")] + +"678_346" +[("678","_346")] +[(Number (MkDecimal [6,7,8] Nothing Nothing),"_346")] + +"0x23d_fa4" +[("0x23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0X23d_fa4" +[("0X23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0o01_253" +[("0o01","_253")] +[(Number (MkNumber 8 [0,1]),"_253")] + +"0O304_367" +[("0O304","_367")] +[(Number (MkNumber 8 [3,0,4]),"_367")] + +"0b0101_0110" +[("0b0101","_0110")] +[(Number (MkNumber 2 [0,1,0,1]),"_0110")] + +"0B11_010_0110" +[("0B11","_010_0110")] +[(Number (MkNumber 2 [1,1]),"_010_0110")] ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs ===================================== @@ -30,13 +30,13 @@ module GHC.Internal.Control.Monad.Fix ( import GHC.Internal.Data.Either import GHC.Internal.Data.Function ( fix ) import GHC.Internal.Data.Maybe -import GHC.Internal.Data.Monoid ( Dual(..), Sum(..), Product(..) +import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..) , First(..), Last(..), Alt(..), Ap(..) ) import GHC.Internal.Data.Ord ( Down(..) ) +import GHC.Internal.Data.Tuple ( Solo(..), snd ) import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) ) import GHC.Internal.Generics import GHC.Internal.List ( head, drop ) -import GHC.Tuple (Solo (..)) import GHC.Internal.Control.Monad.ST.Imp import GHC.Internal.System.IO @@ -72,6 +72,11 @@ instance MonadFix Solo where mfix f = let a = f (unSolo a) in a where unSolo (MkSolo x) = x +-- | @since base-4.21 +instance Monoid a => MonadFix ((,) a) where + -- See the CLC proposal thread for discussion and proofs of the laws: https://github.com/haskell/core-libraries-committee/issues/238 + mfix f = let a = f (snd a) in a + -- | @since base-2.01 instance MonadFix Maybe where mfix f = let a = f (unJust a) in a ===================================== libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs ===================================== @@ -300,6 +300,17 @@ lexCharE = n <- lexInteger base guard (n <= toInteger (ord maxBound)) return (chr (fromInteger n)) + where + -- Slightly different variant of lexBaseChar that denies binary format. + -- Binary formats are not allowed for character/string literal. + lexBaseChar = do + c <- get + case c of + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexCntrlChar = do _ <- char '^' @@ -415,27 +426,28 @@ type Digits = [Int] lexNumber :: ReadP Lexeme lexNumber - = lexHexOct <++ -- First try for hex or octal 0x, 0o etc + = lexHexOctBin <++ -- First try for hex, octal or binary 0x, 0o, 0b etc -- If that fails, try for a decimal number lexDecNumber -- Start with ordinary digits -lexHexOct :: ReadP Lexeme -lexHexOct +lexHexOctBin :: ReadP Lexeme +lexHexOctBin = do _ <- char '0' base <- lexBaseChar digits <- lexDigits base return (Number (MkNumber base digits)) - -lexBaseChar :: ReadP Int --- Lex a single character indicating the base; fail if not there -lexBaseChar = do - c <- get - case c of - 'o' -> return 8 - 'O' -> return 8 - 'x' -> return 16 - 'X' -> return 16 - _ -> pfail + where + -- Lex a single character indicating the base; fail if not there + lexBaseChar = do + c <- get + case c of + 'b' -> return 2 + 'B' -> return 2 + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexDecNumber :: ReadP Lexeme lexDecNumber = ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -14418,6 +14418,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -11647,6 +11647,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b507fad4031b79358957c6630a883ec3fe255cbf...f4ba5776ae76e1862d55a68cb31610a20d48c192 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b507fad4031b79358957c6630a883ec3fe255cbf...f4ba5776ae76e1862d55a68cb31610a20d48c192 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 19:31:39 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 28 Apr 2024 15:31:39 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/T24714-GADT-sig-only-span Message-ID: <662ea41b5877e_13c1a11326a1c781aa@gitlab.mail> Alan Zimmerman pushed new branch wip/az/T24714-GADT-sig-only-span at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/T24714-GADT-sig-only-span You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 28 21:52:59 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 28 Apr 2024 17:52:59 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] EPA: Preserve comments in Match Pats Message-ID: <662ec53bbd3d4_13c1a123482ec10369d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7d7b24dc by Alan Zimmerman at 2024-04-28T17:52:53-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d7b24dc416e45899641d14b321dfedefa7a2ca7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d7b24dc416e45899641d14b321dfedefa7a2ca7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 01:13:25 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 28 Apr 2024 21:13:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] EPA: Preserve comments in Match Pats Message-ID: <662ef435804a3_13c1a13ac7a581140b8@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5abacac6 by Alan Zimmerman at 2024-04-28T21:13:16-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5abacac654d0ea3e8051442a75b2da9a0263516a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5abacac654d0ea3e8051442a75b2da9a0263516a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 05:10:37 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Mon, 29 Apr 2024 01:10:37 -0400 Subject: [Git][ghc/ghc][wip/expansions-appdo] 112 commits: EPA: Fix FamDecl range Message-ID: <662f2bcd4350f_365531167db5c68995@gitlab.mail> Apoorv Ingle pushed to branch wip/expansions-appdo at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - ec70b417 by Apoorv Ingle at 2024-04-22T13:26:19-05:00 make applicative do work with expansions, possibly badly Fixes: #24406 enable the flow renaming do_or_lc to doFlavour and debugging error contexts testcases - - - - - 89f88784 by Apoorv Ingle at 2024-04-22T13:26:33-05:00 make sure app do expression statements location is mapped correctly - - - - - fd30cb87 by Apoorv Ingle at 2024-04-22T13:26:33-05:00 add flavour into OrigStmt to guide better error messages about qualified do. - - - - - b5b79eb9 by Apoorv Ingle at 2024-04-22T13:26:33-05:00 add stmt and do flav info in OrigPat to improve error messages - - - - - 65ae9818 by Apoorv Ingle at 2024-04-22T13:26:33-05:00 accepting some test cases ado003 and ado002 also fix for #16135 - - - - - 2c7b46c5 by Apoorv Ingle at 2024-04-22T13:26:33-05:00 make applicative breakpoint work - - - - - 1039589a by Apoorv Ingle at 2024-04-22T13:26:34-05:00 make join unlocated - - - - - 03bd96b4 by Apoorv Ingle at 2024-04-22T13:26:34-05:00 fix rebase conflicts - - - - - afc00d76 by Apoorv Ingle at 2024-04-29T00:07:17-05:00 in GHC.Tc.Gen.Do.mk_apps pull out the XExpr annotation outside the op application - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f76e8cfdb0cb7780828257fab5990a404325dbee...afc00d76bbb0ba5713aff883a00d4cfb8258305d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f76e8cfdb0cb7780828257fab5990a404325dbee...afc00d76bbb0ba5713aff883a00d4cfb8258305d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 05:14:26 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Mon, 29 Apr 2024 01:14:26 -0400 Subject: [Git][ghc/ghc][wip/expansions-appdo] in GHC.Tc.Gen.Do.mk_apps pull out the XExpr annotation outside the op application Message-ID: <662f2cb2d03ed_3655311807b08698f5@gitlab.mail> Apoorv Ingle pushed to branch wip/expansions-appdo at Glasgow Haskell Compiler / GHC Commits: 7e4ed6b0 by Apoorv Ingle at 2024-04-29T00:14:10-05:00 in GHC.Tc.Gen.Do.mk_apps pull out the XExpr annotation outside the op application - - - - - 3 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Gen/Do.hs - compiler/GHC/Tc/Gen/Match.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -846,7 +846,7 @@ instance Outputable HsThingRn where where ppr_builder prefix x = ifPprDebug (braces (text prefix <+> parens (ppr x))) (ppr x) instance Outputable XXExprGhcRn where - ppr (ExpandedThingRn o e) = ifPprDebug (braces $ vcat [ppr o, ppr e]) (ppr o) + ppr (ExpandedThingRn o e) = ifPprDebug (braces $ vcat [ppr o, text ";;" , ppr e]) (ppr o) ppr (PopErrCtxt e) = ifPprDebug (braces (text "" <+> ppr e)) (ppr e) instance Outputable XXExprGhcTc where ===================================== compiler/GHC/Tc/Gen/Do.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Tc.Gen.Do (expandDoStmts) where import GHC.Prelude -import GHC.Rename.Utils ( wrapGenSpan, genHsExpApps, genHsApp, genHsLet, genLHsApp, +import GHC.Rename.Utils ( wrapGenSpan, genHsExpApps, genHsApp, genHsLet, genHsLamDoExp, genHsCaseAltDoExp, genWildPat ) import GHC.Tc.Utils.Monad import GHC.Tc.Gen.Pat @@ -53,14 +53,14 @@ import Data.List ((\\)) -- so that they can be typechecked. -- See Note [Expanding HsDo with XXExprGhcRn] below for `HsDo` specific commentary -- and Note [Handling overloaded and rebindable constructs] for high level commentary -expandDoStmts :: HsDoFlavour -> [ExprLStmt GhcRn] -> TcM (LHsExpr GhcRn) +expandDoStmts :: HsDoFlavour -> [ExprLStmt GhcRn] -> TcM (HsExpr GhcRn) expandDoStmts doFlav stmts = do expanded_expr <- expand_do_stmts doFlav stmts case expanded_expr of - L _ (XExpr (PopErrCtxt e)) -> return e + L _ (XExpr (PopErrCtxt e)) -> return $ unLoc e -- The first expanded stmt doesn't need a pop as -- it would otherwise pop the "In the expression do ... " from -- the error context - _ -> return expanded_expr + _ -> return $ unLoc expanded_expr -- | The main work horse for expanding do block statements into applications of binds and thens -- See Note [Expanding HsDo with XXExprGhcRn] @@ -213,7 +213,8 @@ expand_do_stmts doFlavour ((L _ (ApplicativeStmt _ args mb_join)): lstmts) = -- wrap the expanded expression with a `join` if needed ; let final_expr = case mb_join of - Just (SyntaxExprRn join_op) -> genLHsApp join_op (wrapGenSpan $ unLoc expand_ado_expr) + Just (SyntaxExprRn join_op) + -> genLHsApp join_op expand_ado_expr _ -> expand_ado_expr ; traceTc "expand_do_stmts AppStmt" (vcat [ text "args:" <+> ppr args , text "lstmts:" <+> ppr lstmts @@ -229,14 +230,16 @@ expand_do_stmts doFlavour ((L _ (ApplicativeStmt _ args mb_join)): lstmts) = , arg_expr = (L rhs_loc rhs) , is_body_stmt = is_body_stmt }) = - do traceTc "do_arg" (text "OneArg" <+> ppr (L rhs_loc rhs)) + do let xx_stmt = mkExpandedStmtAt rhs_loc stmt doFlavour rhs + traceTc "do_arg" (text "OneArg" <+> ppr xx_stmt) return ((pat, mb_fail_op) - , mkExpandedStmtAt rhs_loc stmt doFlavour rhs) + , xx_stmt) where stmt = if is_body_stmt then (L rhs_loc (BodyStmt NoExtField (L rhs_loc rhs) NoSyntaxExprRn NoSyntaxExprRn)) else (L rhs_loc (BindStmt xbsn pat (L rhs_loc rhs))) do_arg (ApplicativeArgMany _ stmts ret@(L ret_loc _) pat ctxt) = do { expr <- expand_do_stmts ctxt $ stmts ++ [L ret_loc $ mkLastStmt ret] + ; traceTc "do_arg" (text "ManyArg" <+> ppr expr) ; return ((pat, Nothing) , expr) } @@ -251,7 +254,7 @@ expand_do_stmts doFlavour ((L _ (ApplicativeStmt _ args mb_join)): lstmts) = case op of SyntaxExprRn op -> case r_expr of L loc (XExpr (ExpandedThingRn (OrigStmt (L l s) flav) e)) - -> L loc $ XExpr (ExpandedThingRn (OrigStmt (L l s) flav) + -> wrapGenSpan $ XExpr (ExpandedThingRn (OrigStmt (L l s) flav) (genHsExpApps op [ l_expr , L loc e ])) _ -> wrapGenSpan $ genHsExpApps op [ l_expr, r_expr ] ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -82,7 +82,6 @@ import Control.Arrow ( second ) import qualified Data.List.NonEmpty as NE import Data.Maybe (mapMaybe) - {- ************************************************************************ * * @@ -352,13 +351,15 @@ tcDoStmts ListComp (L l stmts) res_ty ; return $ mkHsWrapCo co (HsDo list_ty ListComp (L l stmts')) } tcDoStmts doExpr@(DoExpr _) ss@(L _ stmts) res_ty - = do { expanded_expr <- expandDoStmts doExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty + = do { traceTc "tcDoStmts" $ text "original:" <+> ppr ss + ; expanded_expr <- expandDoStmts doExpr stmts -- Do expansion on the fly + ; traceTc "tcDoStmts" $ text "expansion:" <+> ppr expanded_expr + ; mkExpandedExprTc (HsDo noExtField doExpr ss) <$> tcExpr expanded_expr res_ty } tcDoStmts mDoExpr@(MDoExpr _) ss@(L _ stmts) res_ty = do { expanded_expr <- expandDoStmts mDoExpr stmts -- Do expansion on the fly - ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> tcExpr (unLoc expanded_expr) res_ty } + ; mkExpandedExprTc (HsDo noExtField mDoExpr ss) <$> tcExpr expanded_expr res_ty } tcDoStmts MonadComp (L l stmts) res_ty = do { stmts' <- tcStmts (HsDoStmt MonadComp) tcMcStmt stmts res_ty View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e4ed6b0dfff14f5860921480bed5643ea0514e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e4ed6b0dfff14f5860921480bed5643ea0514e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 05:32:03 2024 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Mon, 29 Apr 2024 01:32:03 -0400 Subject: [Git][ghc/ghc][wip/expansions-appdo] 53 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662f30d345526_3655311a77e9c709b7@gitlab.mail> Apoorv Ingle pushed to branch wip/expansions-appdo at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 11faf56f by Apoorv Ingle at 2024-04-29T00:17:22-05:00 make applicative do work with expansions, possibly badly Fixes: #24406 enable the flow renaming do_or_lc to doFlavour and debugging error contexts testcases - - - - - dc42d2cd by Apoorv Ingle at 2024-04-29T00:17:22-05:00 make sure app do expression statements location is mapped correctly - - - - - d33bfda7 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 add flavour into OrigStmt to guide better error messages about qualified do. - - - - - 27de2281 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 add stmt and do flav info in OrigPat to improve error messages - - - - - fbf2bfa6 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 accepting some test cases ado003 and ado002 also fix for #16135 - - - - - bda3f098 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 make applicative breakpoint work - - - - - a3781239 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 make join unlocated - - - - - d7357924 by Apoorv Ingle at 2024-04-29T00:17:23-05:00 fix rebase conflicts - - - - - 9b65133a by Apoorv Ingle at 2024-04-29T00:31:30-05:00 in GHC.Tc.Gen.Do.mk_apps pull out the XExpr annotation outside the op application - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7e4ed6b0dfff14f5860921480bed5643ea0514e9...9b65133af16a6c4b6333be2e586065e765e38438 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7e4ed6b0dfff14f5860921480bed5643ea0514e9...9b65133af16a6c4b6333be2e586065e765e38438 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 10:04:31 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 06:04:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] EPA: Preserve comments in Match Pats Message-ID: <662f70afc3849_26138416fc6078283@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c4bc82f5 by Alan Zimmerman at 2024-04-29T06:04:19-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4bc82f5cc357a2bd7f6341c3bd35b5fb867337d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4bc82f5cc357a2bd7f6341c3bd35b5fb867337d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 10:51:49 2024 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Mon, 29 Apr 2024 06:51:49 -0400 Subject: [Git][ghc/ghc][wip/hugepages] 5670 commits: rts: Introduce --eventlog-flush-interval flag Message-ID: <662f7bc5f26b_2613846f7e0887417@gitlab.mail> Teo Camarasu pushed to branch wip/hugepages at Glasgow Haskell Compiler / GHC Commits: 98dd09af by Ben Gamari at 2021-02-27T07:58:57-05:00 rts: Introduce --eventlog-flush-interval flag This introduces a flag, --eventlog-flush-interval, which can be used to set an upper bound on the amount of time for which an eventlog event will remain enqueued. This can be useful in real-time monitoring settings. - - - - - 966a768e by Matthew Pickering at 2021-02-27T07:59:33-05:00 Remove the -xt heap profiling option It should be left to tooling to perform the filtering to remove these specific closure types from the profile if desired. Fixes #16795 - - - - - 60bf4d7c by Andreas Klebinger at 2021-02-27T08:00:08-05:00 Fix typechecking time bug for large rationals (#15646) When desugaring large overloaded literals we now avoid computing the `Rational` value. Instead prefering to store the significant and exponent as given where reasonable and possible. See Note [FractionalLit representation] for details. - - - - - df6d42d0 by Zubin Duggal at 2021-02-27T08:00:46-05:00 Don't catch async exceptions when evaluating Template Haskell - - - - - 902ece87 by Zubin Duggal at 2021-02-27T08:00:46-05:00 switch to using forkIO to detect async exceptions - - - - - 629dd56d by Zubin Duggal at 2021-02-27T08:00:46-05:00 Remove unnecessary killThread - - - - - c703cb39 by Zubin Duggal at 2021-02-27T08:00:46-05:00 Explain uninterruptibleMask - - - - - 5b752b1d by Sylvain Henry at 2021-02-27T08:01:25-05:00 touchy: use a valid cabal-version - - - - - bcaa36c4 by Sylvain Henry at 2021-02-27T08:01:25-05:00 Fix Windows build with autoconf >=2.70 (#19189) - - - - - 31ee48dc by Sylvain Henry at 2021-02-27T08:02:03-05:00 CI: reduce xz compression for non release/nightly jobs Reduce XZ compression level for regular jobs (it is bumped to 9 for releases and nightly jobs). In my experiments I've got the following bindist size in the given time for each compression level (with the quick flavour): XZ_OPT Time Size -9 4m06s 112 MB -8 4m00s 114 MB -7 3m50s 116 MB -6 (default) 3m40s 118 MB -5 2m47s 123 MB -4 1m57s 134 MB -3 1m03s 129 MB -2 49.73s 136 MB -1 37.72s 142 MB -0 34.40s 156 MB - - - - - 7d8f7d96 by Sebastian Graf at 2021-02-27T08:02:39-05:00 Include time.h in conc059_c (#19431) The test probably could have used `usleep` from `unistd.h` instead, but this seemed like the simplest solution. Fixes #19431. - - - - - 157fe938 by Ben Gamari at 2021-02-27T08:03:15-05:00 gitlab-ci: Fix TEST_ARGS/RUNTEST_ARGS inconsistency Finally fixes #19025. - - - - - 5680f8d4 by Ben Gamari at 2021-02-27T19:05:18-05:00 TcS: oneShot-ify Following the example of Note [The one-shot state monad trick]. c.f. #18202. Metric Decrease: T17836 T3064 T5321FD T9872a T9872b T9872c T9872d - - - - - 30500a4f by Ben Gamari at 2021-02-27T19:05:18-05:00 GHC.Tc.Solver.Rewrite: oneShot-ify Following the example of Note [The one-shot state monad trick]. c.f. #18202. - - - - - 382cd3b0 by Ben Gamari at 2021-02-27T19:05:18-05:00 Rewrite.split: Fix reboxing As noted in #19102, we would previously ended up reboxing the tuple result of `split`'s worker and then immediately take apart the boxed tuple to again unpack it into an unboxed result. Fixes #19102. - - - - - b8d40af1 by Krzysztof Gogolewski at 2021-02-27T19:05:54-05:00 Fix assertion error with linear types, #19400 The previous code using TyCoMapper could promote the same metavar twice. Use a set instead. - - - - - a3473323 by Ben Gamari at 2021-02-28T05:37:13-05:00 users guide: Update mathjax CDN URL Fixes #19423. [skip ci] - - - - - 0f2891f0 by Sylvain Henry at 2021-02-28T05:37:52-05:00 configure: avoid empty lines in AC_CONFIG_FILES Should fix failures on Windows: configure.ac:1511: error: ` ' is already registered with AC_CONFIG_FILES. - - - - - 980151aa by Alan Zimmerman at 2021-02-28T05:38:29-05:00 Add some utility functions to GHC.Types.SrcLoc pprUserSpan, isZeroWidthSpan, pprLocated, combineRealSrcSpans - - - - - 856929a5 by Sebastian Graf at 2021-02-28T05:39:05-05:00 Widen acceptance window of T12545 (#19414) This test flip-flops by +-1% in arbitrary changes in CI. While playing around with `-dunique-increment`, I could reproduce variations of 3% in compiler allocations, so I set the acceptance window accordingly. Fixes #19414. - - - - - 035d983d by Matthew Pickering at 2021-02-28T05:39:41-05:00 Fix two places where TcGblEnv was retained Found with ghc-debug on the ManyConstructors test - - - - - c3ff35bb by Sebastian Graf at 2021-02-28T06:10:38-05:00 Mark divModInt and friends as INLINE (#19267) So that we don't get a silly worker `$wdivModInt` and risk inlining `divModInt#` into `divModInt` or `$wdivModInt`, making both unlikely to inline at call sites. Fixes #19267. There's a spurious metric decrease (was an *increase*) in T12545. That seems entirely due to shifts in Unique distribution (+5% more `IntMap.$winsert` calls). The inappropriateness of the acceptance window is tracked in #19414. Metric Decrease: T12545 Metric Increase: T12545 - - - - - df2eca94 by Sebastian Graf at 2021-02-28T06:10:39-05:00 CPR analysis: Use CPR of scrutinee for Case Binder CPR (#19232) For years we have lived in a supposedly sweet spot that gave case binders the CPR property, unconditionally. Which is an optimistic hack that is now described in `Historical Note [Optimistic case binder CPR]`. In #19232 the concern was raised that this might do more harm than good and that might be better off simply by taking the CPR property of the scrutinee for the CPR type of the case binder. And indeed that's what we do now. Since `Note [CPR in a DataAlt case alternative]` is now only about field binders, I renamed and garbage collected it into `Note [Optimistic field binder CPR]`. NoFib approves: ``` NoFib Results -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- anna +0.1% +0.1% nucleic2 -1.2% -0.6% sched 0.0% +0.9% transform -0.0% -0.1% -------------------------------------------------------------------------------- Min -1.2% -0.6% Max +0.1% +0.9% Geometric Mean -0.0% +0.0% ``` Fixes #19232. - - - - - 0a85502b by Daniel Gröber at 2021-02-28T06:10:40-05:00 CODEOWNERS: Use sections to allow multiple matching entries The CODEOWNERS documentation has this to say on the current matching behaviour: > The path definition order is significant: the last pattern matching a > given path is used to find the code owners. Take this as an example: /rts/ bgamari [...] /rts/win32/ Phyx (I'm omitting the '@' so as to not notification spam everyone) This means a change in a file under win23 would only have Phyx but not bgamari as approver. I don't think that's the behaviour we want. Using "sections" we can get additive behaviour instead, from the docs: > Additionally, the usual guidance that only the last pattern matching the > file is applied is expanded such that the last pattern matching for each > section is applied. [RTS] /rts/ bgamari [...] [WinIO] /rts/win32/ Phyx So now since those entries are in different sections both would be added to the approvers list. The sections feature was introduced in Gitlab 13.2, see "Version history" on [1] we're currently running 18.8 on gitlab.haskell.org, see [2]. [1]: https://docs.gitlab.com/13.8/ee/user/project/code_owners.html#code-owners-sections [2]: https://gitlab.haskell.org/help - - - - - d262edad by Daniel Gröber at 2021-02-28T06:10:40-05:00 CODEOWNERS: Add @DanielG as maintainer for RTS heap profiling code - - - - - 72c0e078 by Sylvain Henry at 2021-02-28T06:10:42-05:00 Make known names simple ConApps (#19386) While fixing #17336 we noticed that code like this: = if | tc == intTyConName -> ... | tc == int8TyConName -> ... | tc == int16TyConName -> ... | tc == int32TyConName -> ... | tc == int64TyConName -> ... | tc == wordTyConName -> ... | tc == word8TyConName -> ... | tc == word16TyConName -> ... | tc == word32TyConName -> ... | tc == word64TyConName -> ... | tc == naturalTyConName -> ... was not transformed into a single case expression on the Name's unique as I would have expected but as a linear search. Bindings for known names are not simple constructor applications because of their strict `n_occ :: !OccName` field that needs to allocate a `FastString`: this field needs to be forced before using the `n_unique` field. This patch partially reverses ccaf7b66fc79e464b4e26f4ae62cb92ef7ba4b0f by making `n_occ` lazy and by ensuring that helper functions used to declare known names are fully inlined. The code above is then optimised as expected. Baseline Test Metric value New value Change --------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 822810880.0 822104032.0 -0.1% ManyConstructors(normal) ghc/alloc 4551734924.0 4480621808.0 -1.6% MultiLayerModules(normal) ghc/alloc 6029108292.0 6016024464.0 -0.2% Naperian(optasm) ghc/alloc 57396600.0 56826184.0 -1.0% PmSeriesG(normal) ghc/alloc 55666656.0 54521840.0 -2.1% PmSeriesS(normal) ghc/alloc 70204344.0 69047328.0 -1.6% PmSeriesT(normal) ghc/alloc 102273172.0 101070016.0 -1.2% PmSeriesV(normal) ghc/alloc 69157156.0 68002176.0 -1.7% T10421(normal) ghc/alloc 129875476.0 128881544.0 -0.8% T10421a(normal) ghc/alloc 92031552.0 90982800.0 -1.1% T10547(normal) ghc/alloc 34399800.0 33016760.0 -4.0% GOOD T10858(normal) ghc/alloc 208316964.0 207318616.0 -0.5% T11195(normal) ghc/alloc 304100548.0 302797040.0 -0.4% T11276(normal) ghc/alloc 140586764.0 139469832.0 -0.8% T11303b(normal) ghc/alloc 52118960.0 51120248.0 -1.9% T11374(normal) ghc/alloc 241325868.0 240692752.0 -0.3% T11822(normal) ghc/alloc 150612036.0 149582736.0 -0.7% T12150(optasm) ghc/alloc 92738452.0 91897224.0 -0.9% T12227(normal) ghc/alloc 494236296.0 493086728.0 -0.2% T12234(optasm) ghc/alloc 66786816.0 65966096.0 -1.2% T12425(optasm) ghc/alloc 112396704.0 111471016.0 -0.8% T12545(normal) ghc/alloc 1832733768.0 1828021072.0 -0.3% T12707(normal) ghc/alloc 1054991144.0 1053359696.0 -0.2% T13035(normal) ghc/alloc 116173180.0 115112072.0 -0.9% T13056(optasm) ghc/alloc 391749192.0 390687864.0 -0.3% T13253(normal) ghc/alloc 382785700.0 381550592.0 -0.3% T13253-spj(normal) ghc/alloc 168806064.0 167987192.0 -0.5% T13379(normal) ghc/alloc 403890296.0 402447920.0 -0.4% T13701(normal) ghc/alloc 2542828108.0 2534392736.0 -0.3% T13719(normal) ghc/alloc 4666717708.0 4659489416.0 -0.2% T14052(ghci) ghc/alloc 2181268580.0 2175320640.0 -0.3% T14683(normal) ghc/alloc 3094166824.0 3094524216.0 +0.0% T14697(normal) ghc/alloc 376323432.0 374024184.0 -0.6% T15164(normal) ghc/alloc 1896324828.0 1893236528.0 -0.2% T15630(normal) ghc/alloc 198932800.0 197783656.0 -0.6% T16190(normal) ghc/alloc 288186840.0 287250024.0 -0.3% T16577(normal) ghc/alloc 8324100940.0 8321580600.0 -0.0% T17096(normal) ghc/alloc 318264420.0 316961792.0 -0.4% T17516(normal) ghc/alloc 1332680768.0 1331635504.0 -0.1% T17836(normal) ghc/alloc 1296308168.0 1291098504.0 -0.4% T17836b(normal) ghc/alloc 62008340.0 60745256.0 -2.0% T17977(normal) ghc/alloc 52954564.0 51890248.0 -2.0% T17977b(normal) ghc/alloc 47824016.0 46683936.0 -2.4% T18140(normal) ghc/alloc 117408932.0 116353672.0 -0.9% T18223(normal) ghc/alloc 5603767896.0 5602037104.0 -0.0% T18282(normal) ghc/alloc 166456808.0 165396320.0 -0.6% T18304(normal) ghc/alloc 103694052.0 103513136.0 -0.2% T18478(normal) ghc/alloc 816819336.0 814459560.0 -0.3% T18698a(normal) ghc/alloc 438652404.0 437041784.0 -0.4% T18698b(normal) ghc/alloc 529448324.0 527666608.0 -0.3% T18923(normal) ghc/alloc 78360824.0 77315560.0 -1.3% T1969(normal) ghc/alloc 854223208.0 851303488.0 -0.3% T3064(normal) ghc/alloc 200655808.0 199368872.0 -0.6% T3294(normal) ghc/alloc 1791121792.0 1790033888.0 -0.1% T4801(normal) ghc/alloc 343749816.0 341760680.0 -0.6% T5030(normal) ghc/alloc 377520872.0 376492360.0 -0.3% T5321FD(normal) ghc/alloc 312680408.0 311618536.0 -0.3% T5321Fun(normal) ghc/alloc 355635656.0 354536264.0 -0.3% T5631(normal) ghc/alloc 629667068.0 629562192.0 -0.0% T5642(normal) ghc/alloc 540913864.0 539569952.0 -0.2% T5837(normal) ghc/alloc 43183652.0 42177928.0 -2.3% T6048(optasm) ghc/alloc 96395616.0 95397032.0 -1.0% T783(normal) ghc/alloc 427778908.0 426307760.0 -0.3% T9020(optasm) ghc/alloc 279523960.0 277010040.0 -0.9% T9233(normal) ghc/alloc 966717488.0 964594096.0 -0.2% T9630(normal) ghc/alloc 1585228636.0 1581428672.0 -0.2% T9675(optasm) ghc/alloc 594817892.0 591703040.0 -0.5% T9872a(normal) ghc/alloc 2216955420.0 2215648024.0 -0.1% T9872b(normal) ghc/alloc 2747814924.0 2746515472.0 -0.0% T9872c(normal) ghc/alloc 2271878772.0 2270554344.0 -0.1% T9872d(normal) ghc/alloc 623661168.0 621434064.0 -0.4% T9961(normal) ghc/alloc 409059124.0 406811120.0 -0.5% WWRec(normal) ghc/alloc 940563924.0 938008112.0 -0.3% hie002(normal) ghc/alloc 9801941116.0 9787675736.0 -0.1% parsing001(normal) ghc/alloc 494756632.0 493828512.0 -0.2% Metric Decrease: T10547 T13035 T12425 - - - - - 2454bb10 by Sebastian Graf at 2021-02-28T06:10:42-05:00 Make `Ord Literal` deterministic (#19438) Previously, non-determinism arising from a use of `uniqCompareFS` in `cmpLit` potentially crept into `CoreMap`, which we expect to behave deterministically. So we simply use `lexicalCompareFS` now. Fixes #19438. - - - - - 915daf51 by Sebastian Graf at 2021-02-28T06:10:42-05:00 Reduce code bloat in `Ord Literal` instance (#19443) Reduce code bloat by replacing a call to `(==)` (which is defined in terms of `compare`) and to `compare` by a single call to `compare`, utilising the `Semigroup Ordering` instance. The compiler was eliminate the code bloat before, so this is a rather cosmetical improvement. Fixes #19443. - - - - - 2628d61f by Ben Gamari at 2021-03-01T10:11:39-05:00 rts/eventlog: Ensure that all capability buffers are flushed The previous approach performed the flush in yieldCapability. However, as pointed out in #19435, this is wrong as it idle capabilities will not go through this codepath. The fix is simple: undo the optimisation, flushing in `flushEventLog` by calling `flushAllCapsEventsBufs` after acquiring all capabilities. Fixes #19435. - - - - - e18c430d by Ben Gamari at 2021-03-01T10:11:39-05:00 rts/eventlog: Flush MainCapability buffer in non-threaded RTS Previously flushEventLog failed to flush anything but the global event buffer in the non-threaded RTS. Fixes #19436. - - - - - f512f9e2 by Ben Gamari at 2021-03-01T10:11:39-05:00 testsuite: Accept allocations change in T10421 Metric Decrease: T10421 - - - - - 8c425bd8 by Sebastian Graf at 2021-03-01T17:29:44-05:00 Widen acceptance window of `MultiLayerModules` (#19293) [skip ci] As #19293 realises, this one keeps on flip flopping by 2.5% depending on how many modules there are within the GHC package. We should revert this once we figured out how to fix what's going on. - - - - - 7730713b by Simon Peyton Jones at 2021-03-01T17:30:21-05:00 Unify result type earlier to improve error messages Ticket #19364 helpfully points out that we do not currently take advantage of pushing the result type of an application into the arguments. This makes error messages notably less good. The fix is rather easy: move the result-type unification step earlier. It's even a bit more efficient; in the the checking case we now do one less zonk. See Note [Unify with expected type before typechecking arguments] in GHC.Tc.Gen.App This change generally improves error messages, but it made one worse: typecheck/should_fail/T16204c. That led me to the realisation that a good error can be replaced by a less-good one, which provoked me to change GHC.Tc.Solver.Interact.inertsCanDischarge. It's explained in the new Note [Combining equalities] One other refactoring: I discovered that KindEqOrigin didn't need a Maybe in its type -- a nice simplification. - - - - - 3b79e8b8 by Krzysztof Gogolewski at 2021-03-01T17:31:01-05:00 Infer multiplicity in case expressions This is a first step towards #18738. - - - - - 6429943b by Simon Peyton Jones at 2021-03-01T17:31:36-05:00 Fix terrible occurrence-analysis bug Ticket #19360 showed up a terrible bug in the occurrence analyser, in a situation like this Rec { f = g ; g = ..f... {-# RULE g .. = ...f... #-} } Then f was postInlineUnconditionally, but not in the RULE (which is simplified first), so we had a RULE mentioning a variable that was not in scope. This led me to review (again) the subtle loop-breaker stuff in the occurrence analyser. The actual changes are few, and are largely simplifications. I did a /lot/ of comment re-organising though. There was an unexpected amount of fallout. * Validation failed when compiling the stage2 compiler with profiling on. That turned to tickle a second latent bug in the same OccAnal code (at least I think it was always there), which led me to simplify still further; see Note [inl_fvs] in GHC.Core.Opt.OccurAnal. * But that in turn let me to some strange behaviour in CSE when ticks are in the picture, which I duly fixed. See Note [Dealing with ticks] in GHC.Core.Opt.CSE. * Then I got an ASSERT failure in CoreToStg, which again seems to be a latent bug. See Note [Ticks in applications] in GHC.CoreToStg * I also made one unforced change: I now simplify the RHS of a RULE in the same way as the RHS of a stable unfolding. This can allow a trivial binding to disappear sooner than otherwise, and I don't think it has any downsides. The change is in GHC.Core.Opt.Simplify.simplRules. - - - - - ce85cffc by Alan Zimmerman at 2021-03-01T17:32:12-05:00 Wrap LHsContext in Maybe in the GHC AST If the context is missing it is captured as Nothing, rather than putting a noLoc in the ParsedSource. Updates haddock submodule - - - - - 51828c6d by Sebastian Graf at 2021-03-01T17:32:48-05:00 Fix a bug causing loss of sharing in `UniqSDFM` While fixing #18610, I noticed that ```hs f :: Bool -> Int f x = case (x, x) of (True, True) -> 1 (False, False) -> 2 ``` was *not* detected as exhaustive. I tracked it down to `equateUSDFM`, where upon merging equality classes of `x` and `y`, we failed to atually indirect the *representative* `x'` of the equality class of `x` to the representative `y'` of `y`. The fixed code is much more naturally and would I should have written in the first place. I can confirm that the above example now is detected as exhaustive. The commit that fixes #18610 comes directly after and it has `f` above as a regression test, so I saw no need to open a ticket or commit a separate regression test. - - - - - e571eda7 by Sebastian Graf at 2021-03-01T17:32:48-05:00 Pmc: Implement `considerAccessible` (#18610) Consider (`T18610`): ```hs f :: Bool -> Int f x = case (x, x) of (True, True) -> 1 (False, False) -> 2 (True, False) -> 3 -- Warning: Redundant ``` The third clause will be flagged as redundant. Nevertheless, the programmer might intend to keep the clause in order to avoid bitrot. After this patch, the programmer can write ```hs g :: Bool -> Int g x = case (x, x) of (True, True) -> 1 (False, False) -> 2 (True, False) | GHC.Exts.considerAccessible -> 3 -- No warning ``` And won't be bothered any longer. See also `Note [considerAccessible]` and the updated entries in the user's guide. Fixes #18610 and #19228. - - - - - 5d7978df by Matthew Pickering at 2021-03-02T17:29:05-05:00 Define TRY_ACQUIRE_LOCK correctly when non-threaded - - - - - 8188adf0 by Ben Gamari at 2021-03-02T17:29:05-05:00 eventlog: Fix various races Previously the eventlog infrastructure had a couple of races that could pop up when using the startEventLog/endEventLog interfaces. In particular, stopping and then later restarting logging could result in data preceding the eventlog header, breaking the integrity of the stream. To fix this we rework the invariants regarding the eventlog and generally tighten up the concurrency control surrounding starting and stopping of logging. We also fix an unrelated bug, wherein log events from disabled capabilities could end up never flushed. - - - - - da351e44 by David Eichmann at 2021-03-02T17:29:05-05:00 Test start/endEventlogging: first header must be EVENT_HEADER_BEGIN - - - - - 507f8de2 by ARATA Mizuki at 2021-03-02T17:29:43-05:00 Add a test for the calling convention of "foreign import prim" on x86_64 and AArch64 - - - - - 38ebb9db by ARATA Mizuki at 2021-03-02T17:29:43-05:00 Support auto-detection of MAX_REAL_FLOAT_REG and MAX_REAL_DOUBLE_REG up to 6 Fixes #17953 - - - - - ede60537 by Ben Gamari at 2021-03-02T17:30:20-05:00 gitlab-ci: Disable utimensat in Darwin builds Fixes #17895. - - - - - 59e95bdf by Sebastian Graf at 2021-03-03T08:12:27-05:00 Fix typo in docs [skip ci] - - - - - eea96042 by Daniel Winograd-Cort at 2021-03-03T08:12:28-05:00 Add cmpNat, cmpSymbol, and cmpChar Add Data.Type.Ord Add and update tests Metric Increase: MultiLayerModules - - - - - d8dc0f96 by Sylvain Henry at 2021-03-03T08:12:29-05:00 Fix array and cleanup conversion primops (#19026) The first change makes the array ones use the proper fixed-size types, which also means that just like before, they can be used without explicit conversions with the boxed sized types. (Before, it was Int# / Word# on both sides, now it is fixed sized on both sides). For the second change, don't use "extend" or "narrow" in some of the user-facing primops names for conversions. - Names like `narrowInt32#` are misleading when `Int` is 32-bits. - Names like `extendInt64#` are flat-out wrong when `Int is 32-bits. - `narrow{Int,Word}<N>#` however map a type to itself, and so don't suffer from this problem. They are left as-is. These changes are batched together because Alex happend to use the array ops. We can only use released versions of Alex at this time, sadly, and I don't want to have to have a release thatwon't work for the final GHC 9.2. So by combining these we get all the changes for Alex done at once. Bump hackage state in a few places, and also make that workflow slightly easier for the future. Bump minimum Alex version Bump Cabal, array, bytestring, containers, text, and binary submodules - - - - - d89deeba by Matthew Pickering at 2021-03-03T08:12:29-05:00 Profiling: Allow heap profiling to be controlled dynamically. This patch exposes three new functions in `GHC.Profiling` which allow heap profiling to be enabled and disabled dynamically. 1. startHeapProfTimer - Starts heap profiling with the given RTS options 2. stopHeapProfTimer - Stops heap profiling 3. requestHeapCensus - Perform a heap census on the next context switch, regardless of whether the timer is enabled or not. - - - - - fe4202ce by Sylvain Henry at 2021-03-03T08:12:39-05:00 Always INLINE ($!) ($) is INLINE so there is no reason ($!) shouldn't. - - - - - 38748d5f by Sylvain Henry at 2021-03-03T08:12:39-05:00 Minor simplification for leak indicators Avoid returning a lazy panic value when leak indicators are disabled. - - - - - 8a433a3c by Sylvain Henry at 2021-03-03T08:12:39-05:00 Fix leaks of the HscEnv with quick flavour (#19356) Thanks @mpickering for finding them! - - - - - e81f2e4e by Ben Gamari at 2021-03-03T08:12:40-05:00 hadrian: Fix profiled flavour transformer Previously the profiled flavour transformer failed to add the profiled ways to the library and RTS ways lists, resulting in link failures. - - - - - 5c4dcc3e by Ben Gamari at 2021-03-03T08:12:40-05:00 ghc-heap: Fix profiled build Previously a255b4e38918065ac028789872e53239ac30ae1a failed to update the non-profiling codepath. - - - - - 3630b9ba by Sebastian Graf at 2021-03-03T08:12:40-05:00 DmdAnal: Better syntax for demand signatures (#19016) The update of the Outputable instance resulted in a slew of documentation changes within Notes that used the old syntax. The most important doc changes are to `Note [Demand notation]` and the user's guide. Fixes #19016. - - - - - 3f9af891 by Sylvain Henry at 2021-03-03T08:12:42-05:00 Add a flag to dump the FastString table - - - - - ad0c2073 by Andreas Klebinger at 2021-03-03T08:12:43-05:00 Build event logging rts in all flavours except GhcinGhci. This applies the fix for #19033 to all the other flavours as well. - - - - - df74e95a by Ryan Scott at 2021-03-03T08:12:43-05:00 User's Guide: document DefaultSignatures' interaction with subsumption As reported in #19432, the rules governing how `DefaultSignatures` are typechecked became stricter in GHC 9.0 due to simplified subsumption. However, this was far from obvious to me after reading the User's Guide section on `DefaultSignatures`. In this patch, I spruce up the documentation in that section so that it mentions these nuances. Resolves #19432. - - - - - 2f7e879b by Matthew Pickering at 2021-03-03T19:09:34+00:00 Revert "Remove GHC.Types.Unique.Map module" This reverts commit 1c7c6f1afc8e7f7ba5d256780bc9d5bb5f3e7601. - - - - - 8402ea95 by Matthew Pickering at 2021-03-03T19:09:34+00:00 Profiling by info table mode (-hi) This profiling mode creates bands by the address of the info table for each closure. This provides a much more fine-grained profiling output than any of the other profiling modes. The `-hi` profiling mode does not require a profiling build. - - - - - 4b297979 by Matthew Pickering at 2021-03-03T19:09:34+00:00 Add -finfo-table-map which maps info tables to source positions This new flag embeds a lookup table from the address of an info table to information about that info table. The main interface for consulting the map is the `lookupIPE` C function > InfoProvEnt * lookupIPE(StgInfoTable *info) The `InfoProvEnt` has the following structure: > typedef struct InfoProv_{ > char * table_name; > char * closure_desc; > char * ty_desc; > char * label; > char * module; > char * srcloc; > } InfoProv; > > typedef struct InfoProvEnt_ { > StgInfoTable * info; > InfoProv prov; > struct InfoProvEnt_ *link; > } InfoProvEnt; The source positions are approximated in a similar way to the source positions for DWARF debugging information. They are only approximate but in our experience provide a good enough hint about where the problem might be. It is therefore recommended to use this flag in conjunction with `-g<n>` for more accurate locations. The lookup table is also emitted into the eventlog when it is available as it is intended to be used with the `-hi` profiling mode. Using this flag will significantly increase the size of the resulting object file but only by a factor of 2-3x in our experience. - - - - - a7aac008 by Matthew Pickering at 2021-03-03T19:09:34+00:00 Add option to give each usage of a data constructor its own info table The `-fdistinct-constructor-tables` flag will generate a fresh info table for the usage of any data constructor. This is useful for debugging as now by inspecting the info table, you can determine which usage of a constructor caused that allocation rather than the old situation where the info table always mapped to the definition site of the data constructor which is useless. In conjunction with `-hi` and `-finfo-table-map` this gives a more fine grained understanding of where constructor allocations arise from in a program. - - - - - 9087899e by Matthew Pickering at 2021-03-03T19:09:34+00:00 Add whereFrom and whereFrom# primop The `whereFrom` function provides a Haskell interface for using the information created by `-finfo-table-map`. Given a Haskell value, the info table address will be passed to the `lookupIPE` function in order to attempt to find the source location information for that particular closure. At the moment it's not possible to distinguish the absense of the map and a failed lookup. - - - - - db80a5cc by Matthew Pickering at 2021-03-03T19:10:47+00:00 Add test for whereFrom# - - - - - 91d09039 by Matthew Pickering at 2021-03-03T19:11:06+00:00 Add release notes for -hi, -finfo-table-map and -fdistinct-constructor-tables - - - - - f121ffe4 by Matthew Pickering at 2021-03-03T19:11:08+00:00 Don't use FastString to convert string to UTF8 - - - - - 7b9767b8 by Matthew Pickering at 2021-03-03T19:11:08+00:00 Use a newtype for CHeader and CStub in ForeignStubs - - - - - f943edb0 by Matthew Pickering at 2021-03-03T19:11:08+00:00 IPE: Give all constructor and function tables locations During testing it was observed that quite a few info tables were not being given locations (due to not being assigned source locations, because they were not enclosed by a source note). We can at least give the module name and type for such closures even if no more accurate source information. Especially for constructors this helps find them in the STG dumps. - - - - - db898c8a by Krzysztof Gogolewski at 2021-03-04T23:14:01-05:00 Add a Template Haskell warning flag -Wimplicit-lift Part of #17804. - - - - - e679321e by Matthew Pickering at 2021-03-04T23:14:37-05:00 Hadrian: Enable -ticky-dyn-thunk in ticky_ghc transformer This produces much more detailed ticky profiles which include names of constructors. Related !3340 !2098 Fixes #19403 - - - - - c6ec7f48 by Ben Gamari at 2021-03-04T23:15:12-05:00 testsuite: Add test for #19413 This was fixed as a result of #19181. - - - - - f191fce7 by Ben Gamari at 2021-03-04T23:15:13-05:00 base: Add reference to #19413 to Note [unsafePerformIO and strictness] - - - - - 9de44e57 by Ben Gamari at 2021-03-04T23:15:48-05:00 rts: Make markLiveObject thread-safe markLiveObject is called by GC worker threads and therefore must be thread-safe. This was a rather egregious oversight which the testsuite missed. (cherry picked from commit fe28a062e47bd914a6879f2d01ff268983c075ad) - - - - - 1a52c53b by Ben Gamari at 2021-03-04T23:16:24-05:00 gitlab-ci: Build releases with hyperlinked sources Fixes #19455. - - - - - 4cdf8b5e by Cale Gibbard at 2021-03-04T23:17:00-05:00 Bring back COMPLETE sets filtered by result TyCon (#14422) Commit 2a94228 dramatically simplified the implementation and improved the performance of COMPLETE sets while making them applicable in more scenarios at the same time. But it turned out that there was a change in semantics that (to me unexpectedly) broke users' expectations (see #14422): They relied on the "type signature" of a COMPLETE pragma to restrict the scrutinee types of a pattern match for which they are applicable. This patch brings back that filtering, so the semantics is the same as it was in GHC 9.0. See the updated Note [Implementation of COMPLETE pragmas]. There are a few testsuite output changes (`completesig13`, `T14422`) which assert this change. Co-authored-by: Sebastian Graf <sebastian.graf at kit.edu> - - - - - 6467a48e by Ben Gamari at 2021-03-04T23:17:36-05:00 testsuite: Prevent T16318 from picking up .ghci Previously this test did nothing to prevent GHC from reading .ghci due to the `-e` arguments. Consequently it could fail due to multiple reloadings of DynFlags while evaluating .ghci. - - - - - 4cd98bd2 by Krzysztof Gogolewski at 2021-03-05T04:48:39-05:00 Run linear Lint on the desugarer output (part of #19165) This addresses points (1a) and (1b) of #19165. - Move mkFailExpr to HsToCore/Utils, as it can be shared - Desugar incomplete patterns and holes to an empty case, as in Note [Incompleteness and linearity] - Enable linear linting of desugarer output - Mark MultConstructor as broken. It fails Lint, but I'd like to fix this separately. Metric Decrease: T6048 - - - - - b5155a6c by Harry Garrood harry at garrood.me at 2021-03-05T04:49:18-05:00 Add new driver test for use of outdated .o files This is something that's quite important for the correctness of the incremental build system and doesn't appear to be tested currently; this test fails on my hashing branch, whereas all of the other (non-perf) tests pass. - - - - - 6141aef4 by Andreas Klebinger at 2021-03-05T14:01:20-05:00 Update bounds/hadrian to fix bootstrapping with 9.0. This fixes #19484. In detail we: * Bump the index-state of hackage. * Require alex-3.2.6, as alex-3.2.5 doesn't build with 9.0. * Allow Cabal-3.4 as 3.2 doesn't build with ghc 9.0. * Allow a newer QuickCheck version that accepts the new base version. * Some code changes to account for Cabal changes. - - - - - 31e265c1 by Andreas Schwab at 2021-03-05T14:01:56-05:00 Implement riscv64 LLVM backend This enables a registerised build for the riscv64 architecture. - - - - - dd23bd74 by Sylvain Henry at 2021-03-06T02:33:32-05:00 Windows: fix crlf on checkout Using .gitatttributes, we don't require users to set git's core.autocrlf setting to false on Windows to be able to checkout a working tree. - - - - - 9e0c0c3a by Ben Gamari at 2021-03-06T02:34:08-05:00 hadrian: Pass -fno-use-rpaths to GHC while linking This mirrors the make build system and ensures that we don't end up with references to the build directory in the final executable. Fixes #19485. - - - - - cf65cf16 by Shayne Fletcher at 2021-03-06T19:27:04-05:00 Implement record dot syntax - - - - - 3e082f8f by Ben Gamari at 2021-03-07T17:01:40-05:00 Implement BoxedRep proposal This implements the BoxedRep proposal, refactoring the `RuntimeRep` hierarchy from: ```haskell data RuntimeRep = LiftedPtrRep | UnliftedPtrRep | ... ``` to ```haskell data RuntimeRep = BoxedRep Levity | ... data Levity = Lifted | Unlifted ``` Updates binary, haddock submodules. Closes #17526. Metric Increase: T12545 - - - - - 657b5538 by Peter Trommler at 2021-03-08T07:31:39-05:00 Hadrian: Add powerpc64[le] to supported arch list Fixes #19409 - - - - - 33a4fd99 by Matthew Pickering at 2021-03-08T07:32:15-05:00 eventlog: Add MEM_RETURN event to give information about fragmentation See #19357 The event reports the * Current number of megablocks allocated * The number that the RTS thinks it needs * The number is managed to return to the OS When current > need then the difference is returned to the OS, the successful number of returned mblocks is reported by 'returned'. In a fragmented heap current > need but returned < current - need. - - - - - ffc96439 by Matthew Pickering at 2021-03-08T07:32:15-05:00 eventlog: Add BLOCKS_SIZE event The BLOCKS_SIZE event reports the size of the currently allocated blocks in bytes. It is like the HEAP_SIZE event, but reports about the blocks rather than megablocks. You can work out the current heap fragmentation by looking at the difference between HEAP_SIZE and BLOCKS_SIZE. Fixes #19357 - - - - - e145e44c by Matthew Pickering at 2021-03-08T07:32:15-05:00 eventlog: Add changelog entry for BLOCKS_SIZE and MEM_RETURN - - - - - e483775c by Daniel Winograd-Cort at 2021-03-08T07:32:53-05:00 Update changelog and release notes for Data.Type.Ord change - - - - - daa6363f by Sylvain Henry at 2021-03-08T18:24:07-05:00 DynFlags: move temp file management into HscEnv (#17957) - - - - - 47d6acd3 by Matthew Pickering at 2021-03-08T18:24:42-05:00 rts: Use a separate free block list for allocatePinned The way in which allocatePinned took blocks out of the nursery was leading to horrible fragmentation in some workloads. The strategy now is that a separate free block list is reserved for each capability and blocks are taken from there. When it's empty the global SM lock is taken and a fresh block of size PINNED_EMPTY_SIZE is allocated. Fixes #19481 - - - - - bfa86250 by Matthew Pickering at 2021-03-08T18:25:19-05:00 eventlog: Repost initialisation events when eventlog restarts If startEventlog is called after the program has already started running then quite a few useful events are missing from the eventlog because they are only posted when the program starts. This patch adds a mechanism to declare that an event should be reposted everytime the startEventlog function is called. Now in EventLog.c there is a global list of functions called `eventlog_header_funcs` which stores a list of functions which should be called everytime the eventlog starts. When calling `postInitEvent`, the event will not only be immediately posted to the eventlog but also added to the global list. When startEventLog is called, the list is traversed and the events reposted. - - - - - 0a709dd9 by Ryan Scott at 2021-03-09T02:46:20-05:00 Require GHC 8.10 as the minimum compiler for bootstrapping Now that GHC 9.0.1 is released, it is time to drop support for bootstrapping with GHC 8.8, as we only support building with the previous two major GHC releases. As an added bonus, this allows us to remove several bits of CPP that are either always true or no longer reachable. - - - - - 376427ec by Ryan Scott at 2021-03-09T02:46:56-05:00 Document operator sections' interaction with subsumption This resolves #19457 by making a note of breaking changes (introduced in GHC 9.2) to the way that GHC typechecks operator sections where the operator has nested `forall`s or contexts in its type signature. - - - - - 7a728ca6 by Andreas Klebinger at 2021-03-09T02:47:31-05:00 Add a distclean command to hadrian. Hadrian should behave well and not delete files created by configure with the clean command. With this patch hadrian now deletes the fs/mingw tarballs only with distclean. This fixes #19320. The main impact being that validate won't have to redownload the tarballs when re-run. - - - - - aaa5fc21 by Vladislav Zavialov at 2021-03-09T18:51:55-05:00 Replace Ord TyLit with nonDetCmpTyLit (#19441) The Ord instance was non-deterministic, but it's easy assume that it is deterministic. In fact, haddock-api used to do exactly that before haddock/7e8c7c3491f3e769368b8e6c767c62a33e996c80 - - - - - 8fe274e2 by Simon Peyton Jones at 2021-03-09T18:52:32-05:00 Fixes to dealing with the export of main It's surprisingly tricky to deal with 'main' (#19397). This patch does quite bit of refactoring do to it right. Well, more-right anyway! The moving parts are documented in GHC.Tc.Module Note [Dealing with main] Some other oddments: * Rename tcRnExports to rnExports; no typechecking here! * rnExports now uses checkNoErrs rather than failIfErrsM; the former fails only if rnExports itself finds errors * Small improvements to tcTyThingCategory, which ultimately weren't important to the patch, but I've retained as a minor improvement. - - - - - e9189745 by Ryan Scott at 2021-03-09T18:53:07-05:00 Fix some warnings when bootstrapping with GHC 9.0 This fixes two classes of warnings that appear when bootstrapping with GHC 9.0: * `ghc-boot.cabal` was using `cabal-version: >=1.22`, which `cabal-install-3.4` now warns about, instead recommending the use of `cabal-version: 1.22`. * Several pattern matches were producing `Pattern match(es) are non-exhaustive` because of incorrect CPP. The pattern-match coverage checker _did_ become smarter in GHC 9.1, however, so I ended up needing to keep the CPP, adjusting them to use `#if __GLASGOW_HASKELL__ < 901` instead. - - - - - df8e8ba2 by Vladislav Zavialov at 2021-03-09T18:53:43-05:00 Location for tuple section pattern error (#19504) This fixes a regression that led to loss of location information in error messages about the use of tuple sections in patterns. - - - - - afc357d2 by Matthew Pickering at 2021-03-10T10:33:36-05:00 rts: Gradually return retained memory to the OS Related to #19381 #19359 #14702 After a spike in memory usage we have been conservative about returning allocated blocks to the OS in case we are still allocating a lot and would end up just reallocating them. The result of this was that up to 4 * live_bytes of blocks would be retained once they were allocated even if memory usage ended up a lot lower. For a heap of size ~1.5G, this would result in OS memory reporting 6G which is both misleading and worrying for users. In long-lived server applications this results in consistent high memory usage when the live data size is much more reasonable (for example ghcide) Therefore we have a new (2021) strategy which starts by retaining up to 4 * live_bytes of blocks before gradually returning uneeded memory back to the OS on subsequent major GCs which are NOT caused by a heap overflow. Each major GC which is NOT caused by heap overflow increases the consec_idle_gcs counter and the amount of memory which is retained is inversely proportional to this number. By default the excess memory retained is oldGenFactor (controlled by -F) / 2 ^ (consec_idle_gcs * returnDecayFactor) On a major GC caused by a heap overflow, the `consec_idle_gcs` variable is reset to 0 (as we could continue to allocate more, so retaining all the memory might make sense). Therefore setting bigger values for `-Fd` makes the rate at which memory is returned slower. Smaller values make it get returned faster. Setting `-Fd0` disables the memory return completely, which is the behaviour of older GHC versions. The default is `-Fd4` which results in the following scaling: > mapM print [(x, 1/ (2**(x / 4))) | x <- [1 :: Double ..20]] (1.0,0.8408964152537146) (2.0,0.7071067811865475) (3.0,0.5946035575013605) (4.0,0.5) (5.0,0.4204482076268573) (6.0,0.35355339059327373) (7.0,0.29730177875068026) (8.0,0.25) (9.0,0.21022410381342865) (10.0,0.17677669529663687) (11.0,0.14865088937534013) (12.0,0.125) (13.0,0.10511205190671433) (14.0,8.838834764831843e-2) (15.0,7.432544468767006e-2) (16.0,6.25e-2) (17.0,5.255602595335716e-2) (18.0,4.4194173824159216e-2) (19.0,3.716272234383503e-2) (20.0,3.125e-2) So after 13 consecutive GCs only 0.1 of the maximum memory used will be retained. Further to this decay factor, the amount of memory we attempt to retain is also influenced by the GC strategy for the oldest generation. If we are using a copying strategy then we will need at least 2 * live_bytes for copying to take place, so we always keep that much. If using compacting or nonmoving then we need a lower number, so we just retain at least `1.2 * live_bytes` for some protection. In future we might want to make this behaviour more aggressive, some relevant literature is > Ulan Degenbaev, Jochen Eisinger, Manfred Ernst, Ross McIlroy, and Hannes Payer. 2016. Idle time garbage collection scheduling. SIGPLAN Not. 51, 6 (June 2016), 570–583. DOI:https://doi.org/10.1145/2980983.2908106 which describes the "memory reducer" in the V8 javascript engine which on an idle collection immediately returns as much memory as possible. - - - - - d095954b by Adam Gundry at 2021-03-10T10:33:36-05:00 Do not remove shadowed record selectors from interactive context (fixes #19322) - - - - - 5581e7b4 by Adam Gundry at 2021-03-10T10:33:36-05:00 Simplify shadowing of DuplicateRecordFields in GHCi (fixes #19314) Previously, defining fields with DuplicateRecordFields in GHCi lead to strange shadowing behaviour, whereby fields would (accidentally) not shadow other fields. This simplifies things so that fields are shadowed in the same way whether or not DuplicateRecordFields is enabled. - - - - - 7d212b49 by Ben Gamari at 2021-03-10T13:18:17-05:00 FastMutInt: Drop FastMutPtr This appears to be unused. - - - - - e6c9b1e6 by Ben Gamari at 2021-03-10T13:20:49-05:00 FastMutInt: Ensure that newFastMutInt initializes value Updates haddock submodule. - - - - - 41b183d6 by Ben Gamari at 2021-03-10T13:20:55-05:00 FastMutInt: Introduce atomicFetchAddFastMutInt This will be needed by FastString. - - - - - aa9dc323 by Ben Gamari at 2021-03-10T13:20:55-05:00 FastString: Use FastMutInt instead of IORef Int This saves at least one I# allocation per FastString. - - - - - e687ba83 by Ben Gamari at 2021-03-10T15:55:09-05:00 Bump bytestring submodule to 0.11.1.0 - - - - - 8a59f49a by Luke Lau at 2021-03-10T15:55:09-05:00 template-haskell: Add putDoc, getDoc, withDecDoc and friends This adds two new methods to the Quasi class, putDoc and getDoc. They allow Haddock documentation to be added to declarations, module headers, function arguments and class/type family instances, as well as looked up. It works by building up a map of names to attach pieces of documentation to, which are then added in the extractDocs function in GHC.HsToCore.Docs. However because these template haskell names need to be resolved to GHC names at the time they are added, putDoc cannot directly add documentation to declarations that are currently being spliced. To remedy this, withDecDoc/withDecsDoc wraps the operation with addModFinalizer, and provides a more ergonomic interface for doing so. Similarly, the funD_doc, dataD_doc etc. combinators provide a more ergonomic interface for documenting functions and their arguments simultaneously. This also changes ArgDocMap to use an IntMap rather than an Map Int, for efficiency. Part of the work towards #5467 - - - - - 30ccf9ed by Joachim Breitner at 2021-03-10T16:57:59-05:00 Introduce GHC2021 language This adds support for -XGHC2021, as described in Proposal 0380 [1]. [1] https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0380-ghc2021.rst - - - - - 115cd3c8 by Joachim Breitner at 2021-03-10T16:58:50-05:00 Use GHC2021 as default language - - - - - fcfc66e5 by Roland Senn at 2021-03-10T16:59:05-05:00 Ignore breakpoint for a specified number of iterations. (#19157) * Implement new debugger command `:ignore` to set an `ignore count` for a specified breakpoint. * Allow new optional parameter on `:continue` command to set an `ignore count` for the current breakpoint. * In the Interpreter replace the current `Word8` BreakArray with an `Int` array. * Change semantics of values in `BreakArray` to: n < 0 : Breakpoint is disabled. n == 0 : Breakpoint is enabled. n > 0 : Breakpoint is enabled, but ignore next `n` iterations. * Rewrite `:enable`/`:disable` processing as a special case of `:ignore`. * Remove references to `BreakArray` from `ghc/UI.hs`. - - - - - d964d6fa by GHC GitLab CI at 2021-03-11T23:13:16-05:00 testsuite: Update Win32 test output for GHC2021 Fixes the Windows CI jobs. Requires update of the Win32 submodule. - - - - - 4fb704a5 by Tamar Christina at 2021-03-12T15:19:15-05:00 Update win32 submodule - - - - - edc9f7d4 by Moritz Angermann at 2021-03-13T01:09:03-05:00 Shorten the build pipeline - - - - - abe0f45b by Moritz Angermann at 2021-03-13T20:27:31+08:00 bump submodule nofib - - - - - ba601db4 by Moritz Angermann at 2021-03-13T23:29:03+08:00 Force eol=lf; to prevent windows breakage. - - - - - 96b3c66b by Moritz Angermann at 2021-03-14T11:52:56+08:00 Allow perf-nofib to fail - - - - - b73c9c5f by Sebastian Graf at 2021-03-14T12:54:29-04:00 Implement the UnliftedDatatypes extension GHC Proposal: 0265-unlifted-datatypes.rst Discussion: https://github.com/ghc-proposals/ghc-proposals/pull/265 Issues: https://gitlab.haskell.org/ghc/ghc/-/issues/19523 Implementation Details: Note [Implementation of UnliftedDatatypes] This patch introduces the `UnliftedDatatypes` extension. When this extension is enabled, GHC relaxes the restrictions around what result kinds are allowed in data declarations. This allows data types for which an unlifted or levity-polymorphic result kind is inferred. The most significant changes are in `GHC.Tc.TyCl`, where `Note [Implementation of UnliftedDatatypes]` describes the details of the implementation. Fixes #19523. - - - - - cd793767 by Matthew Pickering at 2021-03-14T12:55:07-04:00 Correct module name in `-fprof-callers` documentation - - - - - 1793ca9d by Sebastian Graf at 2021-03-14T12:55:45-04:00 Pmc: Consider Required Constraints when guessing PatSyn arg types (#19475) This patch makes `guessConLikeUnivTyArgsFromResTy` consider required Thetas of PatSynCons, by treating them as Wanted constraints to be discharged with the constraints from the Nabla's TyState and saying "does not match the match type" if the Wanted constraints are unsoluble. It calls out into a new function `GHC.Tc.Solver.tcCheckWanteds` to do so. In pushing the failure logic around call sites of `initTcDsForSolver` inside it by panicking, I realised that there was a bunch of dead code surrounding `pmTopMoraliseType`: I was successfully able to delete the `NoChange` data constructor of `TopNormaliseTypeResult`. The details are in `Note [Matching against a ConLike result type]` and `Note [Instantiating a ConLike]. The regression test is in `T19475`. It's pretty much a fork of `T14422` at the moment. Co-authored-by: Cale Gibbard <cgibbard at gmail.com> - - - - - b15c876d by Matthew Pickering at 2021-03-14T12:56:21-04:00 Make traceHeapEventInfo an init event This means it will be reposted everytime the eventlog is started. - - - - - d412cd10 by Sylvain Henry at 2021-03-14T12:57:01-04:00 Write explicit IOEnv's Functor and MonadIO instances (#18202) - - - - - 87ae062a by Sylvain Henry at 2021-03-14T12:57:40-04:00 Compute length only once in foldBal - - - - - 7ea7624c by Ryan Scott at 2021-03-15T00:42:27-04:00 Document the interaction between ScopedTypeVariables and StandaloneKindSignatures This documents a limitation of `StandaloneKindSignatures`—namely, that it does not bring type variables bound by an outermost `forall` into scope over a type-level declaration—in the GHC User's Guide. See #19498 for more discussion. - - - - - 92d98424 by Vladislav Zavialov at 2021-03-15T00:43:05-04:00 Fix record dot precedence (#19521) By moving the handling of TIGHT_INFIX_PROJ to the correct place, we can remove the isGetField hack and fix a bug at the same time. - - - - - 545cfefa by Vladislav Zavialov at 2021-03-15T00:43:05-04:00 Test chained record construction/update/access According to the proposal, we have the following equivalence: e{lbl1 = val1}.val2 == (e{lbl1 = val1}).val2 This is a matter of parsing. Record construction/update must have the same precedence as dot access. Add a test case to ensure this. - - - - - b5b51c54 by Moritz Angermann at 2021-03-16T10:04:23+08:00 [ci] Skip test's on windows that often fail in CI. - - - - - 58cfcc65 by Hécate Moonlight at 2021-03-17T00:57:17-04:00 Make the CI jobs interruptible closes #19362 - - - - - 43a64744 by Moritz Angermann at 2021-03-17T04:16:27-04:00 [ci] don't make marge double build. This fixes !18744 - - - - - f11954b1 by ARATA Mizuki at 2021-03-17T19:05:13-04:00 Add a test for fromInteger :: Integer -> Float/Double (#15926, #17231, #17782) - - - - - 540fa6b2 by ARATA Mizuki at 2021-03-17T19:05:13-04:00 fromInteger :: Integer -> {Float,Double} now always round to nearest even integerToFloat# and integerToDouble# were moved from ghc-bignum to base. GHC.Integer.floatFromInteger and doubleFromInteger were removed. Fixes #15926, #17231, #17782 - - - - - 84927818 by Ben Gamari at 2021-03-17T19:05:50-04:00 llvmGen: Accept range of LLVM versions Previously we would support only one LLVM major version. Here we generalize this to accept a range, taking this range to be LLVM 10 to 11, as 11 is necessary for Apple M1 support. We also accept 12, as that is what apple ships with BigSur on the M1. - - - - - d14a2068 by Sylvain Henry at 2021-03-17T19:06:33-04:00 Enhance pass result forcing When we use `withTiming` we need to force the results of each timed pass to better represent the time spent in each phase. This patch forces some results that weren't before. It also retrieve timings for the CoreToStg and WriteIface passes. - - - - - 665b757f by Ben Gamari at 2021-03-17T19:07:10-04:00 IfaceToType: Ensure that IfaceTyConInfo is shared In #19194 mpickering detailed that there are a LOT of allocations of IfaceTyConInfo: There are just two main cases: IfaceTyConInfo IsPromoted IfaceNormalTyCon and IfaceTyConInfo NotPromoted IfaceNormalTyCon. These should be made into CAFs and shared. From my analysis, the most common case is IfaceTyConInfo NotPromoted IfaceNormalTyCon (53 000) then IfaceTyConInfo IsPromoted IfaceNormalTyCon (28 000). This patch makes it so these are properly shared by using a smart constructor. Fixes #19194. - - - - - 4fbc8558 by Ben Gamari at 2021-03-17T19:07:47-04:00 Eliminate selector thunk allocations - - - - - 42049339 by Ben Gamari at 2021-03-17T19:07:47-04:00 CmmToAsm.Reg.Linear: Make linearRA body a join point Avoid top-level recursion. - - - - - fe6cad22 by Ben Gamari at 2021-03-17T19:07:47-04:00 CmmtoAsm.Reg.Linear: Rewrite process CmmToAsm.Reg.Linear: More strictness More strictness - - - - - 6b10163e by Sylvain Henry at 2021-03-17T19:08:27-04:00 Disable bogus assertion (#19489) - - - - - 26d26974 by Ryan Scott at 2021-03-17T19:09:03-04:00 Document how GADT patterns are matched from left-to-right, outside-in This adds some bullet points to the GHC User's Guide section on `GADTs` to explain some subtleties in how GHC typechecks GADT patterns. In particular, this adds examples of programs being rejected for matching on GADTs in a way that does not mesh with GHC's left-to-right, outside-in order for checking patterns, which can result in programs being rejected for seemingly counterintuitive reasons. (See #12018 for examples of confusion that arose from this.) In addition, now that we have visible type application in data constructor patterns, I mention a possible workaround of using `TypeApplications` to repair programs of this sort. Resolves #12018. - - - - - 30285415 by Vladislav Zavialov at 2021-03-17T19:09:40-04:00 Built-in type families: CharToNat, NatToChar (#19535) Co-authored-by: Daniel Rogozin <daniel.rogozin at serokell.io> Co-authored-by: Rinat Stryungis <rinat.stryungis at serokell.io> - - - - - 0a986685 by Ben Gamari at 2021-03-19T19:58:52-04:00 testsuite: Make --ignore-perf-tests more expressive Allow skipping of only increases/decreases. - - - - - d03d8761 by Ben Gamari at 2021-03-19T19:58:52-04:00 gitlab-ci: Ignore performance improvements in marge jobs Currently we have far too many merge failures due to cumulative performance improvements. Avoid this by accepting metric decreases in marge-bot jobs. Fixes #19562. - - - - - 7d027433 by Gaël Deest at 2021-03-20T07:48:01-04:00 [skip ci] Fix 'Ord' documentation inconsistency Current documentation for the `Ord` typeclass is inconsistent. It simultaneously mentions that: > The 'Ord' class is used for totally ordered datatypes. And: > The Haskell Report defines no laws for 'Ord'. However, '<=' is > customarily expected to implement a non-strict partial order […] The Haskell report (both 98 and 2010 versions) mentions total ordering, which implicitly does define laws. Moreover, `compare :: Ord a => a -> a -> Ordering` and `data Ordering = LT | EQ | GT` imply that the order is indeed total (there is no way to say that two elements are not comparable). This MR fixes the Haddock comment, and adds a comparability law to the list of suggested properties. - - - - - f940fd46 by Alan Zimmerman at 2021-03-20T07:48:37-04:00 Add the main types to be used for exactprint in the GHC AST The MR introducing the API Annotations, !2418 is huge. Conceptually it is two parts, the one deals with introducing the new types to be used for annotations, and outlining how they will be used. This is a small change, localised to compiler/GHC/Parser/Annotation.hs and is contained in this commit. The follow-up, larger commit deals with mechanically working this through the entire AST and updating all the parts affected by it. It is being split so the part that needs good review feedback can be seen in isolation, prior to the rest coming in. - - - - - 95275a5f by Alan Zimmerman at 2021-03-20T07:48:38-04:00 GHC Exactprint main commit Metric Increase: T10370 parsing001 Updates haddock submodule - - - - - adf93721 by GHC GitLab CI at 2021-03-20T07:48:38-04:00 check-ppr,check-exact: Write out result as binary Previously we would use `writeFile` to write the intermediate files to check for round-tripping. However, this will open the output handle as a text handle, which on Windows will change line endings. Avoid this by opening as binary. Explicitly use utf8 encoding. This is for tests only, do not need to worry about user compatibility. - - - - - ceef490b by GHC GitLab CI at 2021-03-20T07:48:38-04:00 testsuite: Normalise slashes In the `comments` and `literals` tests, since they contain file paths. - - - - - dd11f2d5 by Luite Stegeman at 2021-03-20T07:49:15-04:00 Save the type of breakpoints in the Breakpoint tick in STG GHCi needs to know the types of all breakpoints, but it's not possible to get the exprType of any expression in STG. This is preparation for the upcoming change to make GHCi bytecode from STG instead of Core. - - - - - 26328a68 by Luite Stegeman at 2021-03-20T07:49:15-04:00 remove superfluous 'id' type parameter from GenTickish The 'id' type is now determined by the pass, using the XTickishId type family. - - - - - 0107f356 by Luite Stegeman at 2021-03-20T07:49:15-04:00 rename Tickish to CoreTickish - - - - - 7de3532f by Luite Stegeman at 2021-03-20T07:49:15-04:00 Transfer tickish things to GHC.Types.Tickish Metric Increase: MultiLayerModules - - - - - 1f94e0f7 by Luite Stegeman at 2021-03-20T07:49:15-04:00 Generate GHCi bytecode from STG instead of Core and support unboxed tuples and sums. fixes #1257 - - - - - 62b0e1bc by Andreas Klebinger at 2021-03-20T07:49:50-04:00 Make the simplifier slightly stricter. This commit reduces allocations by the simplifier by 3% for the Cabal test at -O2. We do this by making a few select fields, bindings and arguments strict which reduces allocations for the simplifier by around 3% in total for the Cabal test. Which is about 2% fewer allocations in total at -O2. ------------------------- Metric Decrease: T18698a T18698b T9233 T9675 T9872a T9872b T9872c T9872d T10421 T12425 T13253 T5321FD T9961 ------------------------- - - - - - 044e5be3 by Sebastian Graf at 2021-03-20T07:50:26-04:00 Nested CPR light (#19398) While fixing #19232, it became increasingly clear that the vestigial hack described in `Note [Optimistic field binder CPR]` is complicated and causes reboxing. Rather than make the hack worse, this patch gets rid of it completely in favor of giving deeply unboxed parameters the Nested CPR property. Example: ```hs f :: (Int, Int) -> Int f p = case p of (x, y) | x == y = x | otherwise = y ``` Based on `p`'s `idDemandInfo` `1P(1P(L),1P(L))`, we can see that both fields of `p` will be available unboxed. As a result, we give `p` the nested CPR property `1(1,1)`. When analysing the `case`, the field CPRs are transferred to the binders `x` and `y`, respectively, so that we ultimately give `f` the CPR property. I took the liberty to do a bit of refactoring: - I renamed `CprResult` ("Constructed product result result") to plain `Cpr`. - I Introduced `FlatConCpr` in addition to (now nested) `ConCpr` and and according pattern synonym that rewrites flat `ConCpr` to `FlatConCpr`s, purely for compiler perf reasons. - Similarly for performance reasons, we now store binders with a Top signature in a separate `IntSet`, see `Note [Efficient Top sigs in SigEnv]`. - I moved a bit of stuff around in `GHC.Core.Opt.WorkWrap.Utils` and introduced `UnboxingDecision` to replace the `Maybe DataConPatContext` type we used to return from `wantToUnbox`. - Since the `Outputable Cpr` instance changed anyway, I removed the leading `m` which we used to emit for `ConCpr`. It's just noise, especially now that we may output nested CPRs. Fixes #19398. - - - - - 8592a246 by Simon Jakobi at 2021-03-20T07:51:01-04:00 Add compiler perf regression test for #9198 - - - - - d4605e7c by Simon Peyton Jones at 2021-03-20T07:51:36-04:00 Fix an levity-polymorphism error As #19522 points out, we did not account for visible type application when trying to reject naked levity-polymorphic functions that have no binding. This patch tidies up the code, and fixes the bug too. - - - - - 3fa3fb79 by John Ericson at 2021-03-20T07:52:12-04:00 Add more boundary checks for `rem` and `mod` It's quite backend-dependent whether we will actually handle that case right, so let's just always do this as a precaution. In particular, once we replace the native primops used here with the new sized primops, the 16-bit ones on x86 will begin to use 16-bit sized instructions where they didn't before. Though I'm not sure of any arch which has 8-bit scalar instructions, I also did those for consistency. Plus, there are *vector* 8-bit ops in the wild, so if we ever got into autovectorization or something maybe it's prudent to put this here as a reminder not to forget about catching overflows. Progress towards #19026 - - - - - 8e054ff3 by John Ericson at 2021-03-20T07:52:47-04:00 Fix literals for unregisterized backend of small types All credit to @hsyl20, who in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4717#note_338560 figured out this was a problem. To fix this, we use casts in addition to the shrinking and suffixing that is already done. It might make for more verbose code, I don't think that matters too much. In the future, perhaps some of the shrinking and suffixing can be removed for being redundant. That proved less trivial than it sounds, so this wasn't done at this time. Progress towards #19026 Metric Increase: T12707 T13379 Co-authored-by: Sylvain Henry <hsyl20 at gmail.com> - - - - - 226cefd0 by Sylvain Henry at 2021-03-20T07:53:24-04:00 Fix fake import in GHC.Exception.Type boot module It seems like I imported "GHC.Types ()" thinking that it would transitively import GHC.Num.Integer when I wrote that module; but it doesn't. This led to build failures. See https://mail.haskell.org/pipermail/ghc-devs/2021-March/019641.html - - - - - e84e2805 by Viktor Dukhovni at 2021-03-20T07:54:01-04:00 Add fold vs. mconcat test T17123 - - - - - fa499356 by Sebastian Graf at 2021-03-20T07:54:36-04:00 Remove outdated Vagrantfile - - - - - 71e609fb by Moritz Angermann at 2021-03-20T07:55:11-04:00 Add error information to osCommitMemory on failure. - - - - - fb939498 by Ben Gamari at 2021-03-20T10:20:30-04:00 gitlab-ci: Always start with fresh clone Currently we are suffering from issues that appear to be caused by non-hermetic builds. Try avoiding this by setting `GIT_STRATEGY` to `clone`. - - - - - c53faa0c by Ben Gamari at 2021-03-20T15:12:12-04:00 Clean up TBDs in changelog (cherry picked from commit 4f334120c8e9cc4aefcbf11d99f169f648af9fde) - - - - - 91ddac2f by Ryan Scott at 2021-03-20T15:12:12-04:00 Move miscategorized items in template-haskell changelog - - - - - 6a375b53 by Ryan Scott at 2021-03-20T15:12:12-04:00 Bump template-haskell version to 2.18.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #19083. - - - - - adbaa9a9 by Ryan Scott at 2021-03-21T19:40:02-04:00 Remove unnecessary extendTyVarEnvFVRn function The `extendTyVarEnvFVRn` function does the exact same thing as `bindLocalNamesFV`. I see no meaningful distinction between the two functions, so let's just remove the former (which is only used in a handful of places) in favor of the latter. Historical note: `extendTyVarEnvFVRn` and `bindLocalNamesFV` used to be distinct functions, but their implementations were synchronized in 2004 as a part of commit 20e39e0e07e4a8e9395894b2785d6675e4e3e3b3. - - - - - 0cbdba27 by Moritz Angermann at 2021-03-21T21:04:42-04:00 [ci/arm/darwin/testsuite] Forwards ports from GHC-8.10 This is a set of forward ports (cherry-picks) from 8.10 - a7d22795ed [ci] Add support for building on aarch64-darwin - 5109e87e13 [testlib/driver] denoise - 307d34945b [ci] default value for CONFIGURE_ARGS - 10a18cb4e0 [testsuite] mark ghci056 as fragile - 16c13d5acf [ci] Default value for MAKE_ARGS - ab571457b9 [ci/build] Copy config.sub around - 251892b98f [ci/darwin] bump nixpkgs rev - 5a6c36ecb4 [testsuite/darwin] fix conc059 - aae95ef0c9 [ci] add timing info - 3592d1104c [Aarch64] No div-by-zero; disable test. - 57671071ad [Darwin] mark stdc++ tests as broken - 33c4d49754 [testsuite] filter out superfluous dylib warnings - 4bea83afec [ci/nix-shell] Add Foundation and Security - 6345530062 [testsuite/json2] Fix failure with LLVM backends - c3944bc89d [ci/nix-shell] [Darwin] Stop the ld warnings about libiconv. - b821fcc714 [testsuite] static001 is not broken anymore. - f7062e1b0c [testsuite/arm64] fix section_alignment - 820b076698 [darwin] stop the DYLD_LIBRARY_PATH madness - 07b1af0362 [ci/nix-shell] uniquify NIX_LDFLAGS{_FOR_TARGET} As well as a few additional fixups needed to make this block compile: - Fixup all.T - Set CROSS_TARGET, BROKEN_TESTS, XZ, RUNTEST_ARGS, default value. - [ci] shell.nix bump happy - - - - - c46e8147 by Moritz Angermann at 2021-03-21T21:04:42-04:00 [elf/aarch64] Fall Through decoration - - - - - 069abe27 by Moritz Angermann at 2021-03-21T21:04:42-04:00 [llvm/darwin] change vortex cpu to generic For now only the apple flavoured llvm knows vortex, as we build against other toolchains, lets stay with generic for now. - - - - - 2907949c by Moritz Angermann at 2021-03-21T21:04:42-04:00 [ci] Default values for GITLAB_CI_BRANCH, and IGNORE_PERF_FAILURES - - - - - e82d32d6 by Ben Gamari at 2021-03-22T09:22:29-04:00 compiler: Introduce mutableByteArrayContents# primop As noted in #19540, a number of users within and outside of GHC rely on unsafeCoerceUnlifted to work around the fact that this was missing - - - - - eeba7a3a by Ben Gamari at 2021-03-22T09:22:29-04:00 base: Use mutableByteArrayContents - - - - - a9129f9f by Simon Peyton Jones at 2021-03-22T09:23:04-04:00 Short-circuit warning generation for partial type signatures This Note says it all: Note [Skip type holes rapidly] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have module with a /lot/ of partial type signatures, and we compile it while suppressing partial-type-signature warnings. Then we don't want to spend ages constructing error messages and lists of relevant bindings that we never display! This happened in #14766, in which partial type signatures in a Happy-generated parser cause a huge increase in compile time. The function ignoreThisHole short-circuits the error/warning generation machinery, in cases where it is definitely going to be a no-op. It makes a pretty big difference on the Sigs.hs example in #14766: Compile-time allocation GHC 8.10 5.6G Before this patch 937G With this patch 4.7G Yes, that's more than two orders of magnitude! - - - - - 6e437a12 by Ben Gamari at 2021-03-22T18:35:24-04:00 UniqSM: oneShot-ify Part of #18202 ------------------------- Metric Decrease: T12707 T3294 ------------------------- - - - - - 26dd1f88 by Simon Peyton Jones at 2021-03-23T08:09:05-04:00 More improvement to MonoLocalBinds documentation - - - - - 26ba86f7 by Peter Trommler at 2021-03-23T08:09:40-04:00 PPC NCG: Fix int to float conversion In commit 540fa6b2 integer to float conversions were changed to round to the nearest even. Implement a special case for 64 bit integer to single precision floating point numbers. Fixes #19563. - - - - - 7a657751 by Ben Gamari at 2021-03-23T13:00:37-04:00 rts: Use long-path-aware stat Previously `pathstat` relied on msvcrt's `stat` implementation, which was not long-path-aware. It should rather be defined in terms of the `stat` implementation provided by `utils/fs`. Fixes #19541. - - - - - 05c5c054 by Sylvain Henry at 2021-03-23T13:01:15-04:00 Move loader state into Interp The loader state was stored into HscEnv. As we need to have two interpreters and one loader state per interpreter in #14335, it's natural to make the loader state a field of the Interp type. As a side effect, many functions now only require a Interp parameter instead of HscEnv. Sadly we can't fully free GHC.Linker.Loader of HscEnv yet because the loader is initialised lazily from the HscEnv the first time it is used. This is left as future work. HscEnv may not contain an Interp value (i.e. hsc_interp :: Maybe Interp). So a side effect of the previous side effect is that callers of the modified functions now have to provide an Interp. It is satisfying as it pushes upstream the handling of the case where HscEnv doesn't contain an Interpreter. It is better than raising a panic (less partial functions, "parse, don't validate", etc.). - - - - - df895b3f by Ben Gamari at 2021-03-23T20:43:36-04:00 gitlab-ci: Rework handling of head.hackage job trigger GitLab 12.3 now has reasonable support [1] for cross-project job dependencies, allowing us to drop the awful hack of a shell script we used previously. [1] https://docs.gitlab.com/ee/ci/multi_project_pipelines.html#mirroring-status-from-triggered-pipeline - - - - - 25306ddc by GHC GitLab CI at 2021-03-23T20:44:11-04:00 EPA: Run exactprint transformation tests as part of CI EPA == exact print annotations. When !2418 landed, it did not run the tests brought over from ghc-exactprint for making sure the AST prints correctly efter being edited. This enables those tests. - - - - - 55fd158d by Ben Gamari at 2021-03-24T12:35:23+01:00 CmmToAsm.Reg.Linear: Use concat rather than repeated (++) - - - - - 23f4bc89 by Ben Gamari at 2021-03-24T12:35:23+01:00 CmmToAsm.Reg.Linear: oneShot-ify RegM ------------------------- Metric Decrease: T783 T4801 T12707 T13379 T3294 T4801 T5321FD ------------------------- - - - - - 60127035 by Andreas Klebinger at 2021-03-24T16:10:07-04:00 STG AST - Make ConstructorNumber always a field. It's used by all passes and already used as a regular field. So I figured it would be both more consistent and performant to make it a regular field for all constructors. I also added a few bangs in the process. - - - - - 5483b1a4 by Adam Sandberg Ericsson at 2021-03-24T23:31:09-04:00 hadrian: remove alex and happy from build-tools Hadrian doesn't actually depend on them as built-tools and normal usage where you want to compile GHC will pick up the tools before you run hadrian via the ./configure script. Not building an extra copy of alex and happy might also improve overall build-times when building from scratch. - - - - - aa99f516 by Simon Peyton Jones at 2021-03-24T23:31:44-04:00 Fix the binder-swap transformation in OccurAnal The binder-swap transformation needs to be iterated, as shown by #19581. The fix is pretty simple, and is explained in point (BS2) of Note [The binder-swap substitution]. Net effect: - sometimes, fewer simplifier iterations - sometimes, more case merging - - - - - 0029df2b by Hécate at 2021-03-25T04:52:41-04:00 Add compiler linting to CI This commit adds the `lint:compiler` Hadrian target to the CI runner. It does also fixes hints in the compiler/ and libraries/base/ codebases. - - - - - 1350a5cd by GHC GitLab CI at 2021-03-25T04:53:16-04:00 EPA : Remove ApiAnn from ParsedModule All the comments are now captured in the AST, there is no need for a side-channel structure for them. - - - - - c74bd3da by GHC GitLab CI at 2021-03-25T17:31:57+00:00 EPA: Tidy up some GHC.Parser.Annotation comments This is a follow up from !2418 / #19579 [skip ci] - - - - - 0d5d344d by Oleg Grenrus at 2021-03-25T17:36:50-04:00 Implement -Wmissing-kind-signatures Fixes #19564 - - - - - d930fecb by Sylvain Henry at 2021-03-26T19:00:07-04:00 Refactor interface loading In order to support several home-units and several independent unit-databases, it's easier to explicitly pass UnitState, DynFlags, etc. to interface loading functions. This patch converts some functions using monads such as IfG or TcRnIf with implicit access to HscEnv to use IO instead and to pass them specific fields of HscEnv instead of an HscEnv value. - - - - - 872a9444 by Sylvain Henry at 2021-03-26T19:00:07-04:00 Refactor NameCache * Make NameCache the mutable one and replace NameCacheUpdater with it * Remove NameCache related code duplicated into haddock Bump haddock submodule - - - - - 599efd90 by Sylvain Henry at 2021-03-26T19:00:07-04:00 Refactor FinderCache - - - - - 532c6a54 by Sylvain Henry at 2021-03-26T19:00:07-04:00 Remove UniqSupply from NameCache As suggested by @alexbiehl, this patch replaces the always updated UniqSupply in NameCache with a fixed Char and use it with `uniqFromMask` to generate uniques. This required some refactoring because getting a new unique from the NameCache can't be done in pure code anymore, in particular not in an atomic update function for `atomicModifyIORef`. So we use an MVar instead to store the OrigNameCache field. For some reason, T12545 increases (+1%) on i386 while it decreases on other CI runners. T9630 ghc/peak increases only with the dwarf build on CI (+16%). Metric Decrease: T12425 T12545 T9198 T12234 Metric Increase: T12545 T9630 Update haddock submodule - - - - - 89ee9206 by Sylvain Henry at 2021-03-26T19:00:07-04:00 Use foldGet in getSymbolTable Implement @alexbiehl suggestion of using a foldGet function to avoid the creation of an intermediate list while reading the symbol table. Do something similar for reading the Hie symbol table and the interface dictionary. Metric Decrease: T10421 - - - - - a9c0b3ca by Sylvain Henry at 2021-03-26T19:00:07-04:00 Bump haddock submodule - - - - - 628417b4 by Sylvain Henry at 2021-03-26T19:00:07-04:00 Fix lint issue - - - - - ef03fa6f by GHC GitLab CI at 2021-03-26T19:00:42-04:00 Bump Win32 to 2.13.0.0 Bumps Win32 submodule. - - - - - 5741caeb by Sylvain Henry at 2021-03-26T19:01:20-04:00 Only update config.sub when it already exists (#19574) - - - - - 57d21e6a by Sebastian Graf at 2021-03-26T23:02:15-04:00 Rubbish literals for all representations (#18983) This patch cleans up the complexity around WW's `mk_absent_let` by broadening the scope of `LitRubbish`. Rubbish literals now store the `PrimRep` they represent and are ultimately lowered in Cmm. This in turn allows absent literals of `VecRep` or `VoidRep`. The latter allows absent literals for unlifted coercions, as requested in #18983. I took the liberty to rewrite and clean up `Note [Absent fillers]` and `Note [Rubbish values]` to account for the new implementation and to make them more orthogonal in their description. I didn't add a new regression test, as `T18982` already contains the test in the ticket and its test output changes as expected. Fixes #18983. - - - - - c83e4d05 by Adam Sandberg Ericsson at 2021-03-26T23:02:52-04:00 hadrian: build ghc-stageN wrapper when building the stageN:exe:ghc-bin target - - - - - 59375de1 by Viktor Dukhovni at 2021-03-27T18:09:31-04:00 bump submodule nofib - - - - - f72d4ebb by Ben Gamari at 2021-03-27T18:10:06-04:00 rts: Fix joinOSThread on Windows Previously we were treating the thread ID as a HANDLE, but it is not. We must first OpenThread. - - - - - f6960b18 by Simon Peyton Jones at 2021-03-28T00:11:46-04:00 Make RULES more robust in GHC.Float The RULES that use hand-written specialised code for overloaded class methods like floor, ceiling, truncate etc were fragile to certain transformations. This patch makes them robust. See #19582. It's all described in Note [Rules for overloaded class methods]. No test case because currently we don't do the transformation (floating out over-saturated applications) that makes this patch have an effect. But we may so so in future, and this patch makes the RULES much more robust. - - - - - b02c8ef7 by Sebastian Graf at 2021-03-28T00:12:21-04:00 Rename StrictSig to DmdSig (#19597) In #19597, we also settled on the following renamings: * `idStrictness` -> `idDmdSig`, `strictnessInfo` -> `dmdSigInfo`, `HsStrictness` -> `HsDmdSig` * `idCprInfo` -> `idCprSig`, `cprInfo` -> `cprSigInfo`, `HsCpr` -> `HsCprSig` Fixes #19597. - - - - - 29d75863 by Fendor at 2021-03-28T17:26:37-04:00 Add UnitId to Target record In the future, we want `HscEnv` to support multiple home units at the same time. This means, that there will be 'Target's that do not belong to the current 'HomeUnit'. This is an API change without changing behaviour. Update haddock submodule to incorporate API changes. - - - - - 9594f6f6 by Ben Gamari at 2021-03-28T17:27:12-04:00 gitlab-ci: Bump ci-images Upgrades bootstrap GHC to 8.10.4, hopefully avoiding #19600. - - - - - 9c9e40e5 by Oleg Grenrus at 2021-03-28T17:27:49-04:00 Replace - with negate It also failed to parse with HLint (I wonder how GHC itself handles it?) - - - - - c30af951 by Alfredo Di Napoli at 2021-03-29T07:58:00+02:00 Add `MessageClass`, rework `Severity` and add `DiagnosticReason`. Other than that: * Fix T16167,json,json2,T7478,T10637 tests to reflect the introduction of the `MessageClass` type * Remove `makeIntoWarning` * Remove `warningsToMessages` * Refactor GHC.Tc.Errors 1. Refactors GHC.Tc.Errors so that we use `DiagnosticReason` for "choices" (defer types errors, holes, etc); 2. We get rid of `reportWarning` and `reportError` in favour of a general `reportDiagnostic`. * Introduce `DiagnosticReason`, `Severity` is an enum: This big commit makes `Severity` a simple enumeration, and introduces the concept of `DiagnosticReason`, which classifies the /reason/ why we are emitting a particular diagnostic. It also adds a monomorphic `DiagnosticMessage` type which is used for generic messages. * The `Severity` is computed (for now) from the reason, statically. Later improvement will add a `diagReasonSeverity` function to compute the `Severity` taking `DynFlags` into account. * Rename `logWarnings` into `logDiagnostics` * Add note and expand description of the `mkHoleError` function - - - - - 4421fb34 by Moritz Angermann at 2021-03-29T17:25:48-04:00 [macho] improved linker with proper plt support This is a pre-requisite for making aarch64-darwin work. - - - - - e754ff7f by Moritz Angermann at 2021-03-29T17:25:49-04:00 Allocate Adjustors and mark them readable in two steps This drops allocateExec for darwin, and replaces it with a alloc, write, mark executable strategy instead. This prevents us from trying to allocate an executable range and then write to it, which X^W will prohibit on darwin. This will *only* work if we can use mmap. - - - - - 026a53e0 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [linker] Additional FALLTHROUGH decorations. - - - - - dc6fa61c by Moritz Angermann at 2021-03-29T17:25:49-04:00 [linker] SymbolExtras are only used on PPC and X86 - - - - - 710ef9d2 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [linker] align prototype with implementation signature. - - - - - e72a2f77 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [linker/aarch64-elf] support section symbols for GOT relocation - - - - - 38504b6f by Moritz Angermann at 2021-03-29T17:25:49-04:00 [testsuite] Fix SubsectionsViaSymbols test - - - - - 93b8db6b by Moritz Angermann at 2021-03-29T17:25:49-04:00 [linker] no munmap if either agument is invalid. - - - - - 095e1624 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [rts] cast return value to struct. - - - - - 09ea36cf by Moritz Angermann at 2021-03-29T17:25:49-04:00 [aarch64-darwin] be very careful of warnings. So we did *not* have the stgCallocBytes prototype, and subsequently the C compiler defaulted to `int` as a return value. Thus generating sxtw instructions for the return value of stgCalloBytes to produce the expected void *. - - - - - 4bbd1445 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [testlib] ignore strip warnings - - - - - df08d548 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [armv7] arm32 needs symbols! - - - - - f3c23939 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [testsuite/aarch64] disable T18623 - - - - - 142950d9 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [testsuite/aarch64-darwin] disable T12674 - - - - - 66044095 by Moritz Angermann at 2021-03-29T17:25:49-04:00 [armv7] PIC by default + [aarch64-linux] T11276 metric increase Metric Increase: T11276 - - - - - afdacc55 by Takenobu Tani at 2021-03-30T20:41:46+09:00 users-guide: Correct markdown for ghc-9.2 This patch corrects some markdown. [skip ci] - - - - - 470839c5 by Oleg Grenrus at 2021-03-30T17:39:39-04:00 Additionally export asum from Control.Applicative Fixes #19575 - - - - - 128fd85c by Simon Jakobi at 2021-03-30T17:40:14-04:00 Add regression test for #5298 Closes #5298. - - - - - 86e7aa01 by Ben Gamari at 2021-03-30T19:14:19-04:00 gitlab-ci: Trigger head.hackage jobs via pipeline ID As noted in ghc/head.hackage!152, the previous plan of using the commit didn't work when the triggering pipeline had not yet successfully finished. - - - - - 59e82fb3 by Oleg Grenrus at 2021-03-31T11:12:17-04:00 import Data.List with explicit import list - - - - - 44774dc5 by Oleg Grenrus at 2021-03-31T11:12:17-04:00 Add -Wcompat to hadrian Update submodules haskeline and hpc - - - - - dbadd672 by Simon Peyton Jones at 2021-03-31T11:12:52-04:00 The result kind of a signature can't mention quantified vars This patch fixes a small but egregious bug, which allowed a type signature like f :: forall a. blah not to fail if (blah :: a). Acutally this only showed up as a ASSERT error (#19495). The fix is very short, but took quite a bit of head scratching Hence the long Note [Escaping kind in type signatures] While I was in town, I also added a short-cut for the common case of having no quantifiers to tcImplicitTKBndrsX. Metric Decrease: T9198 Metric Increase: T9198 - - - - - 2fcebb72 by Alan Zimmerman at 2021-03-31T11:13:28-04:00 EPA : Rename AddApiAnn to AddEpAnn As port of the process of migrating naming from API Annotations to exact print annotations (EPA) Follow-up from !2418, see #19579 - - - - - 0fe5175a by Alan Zimmerman at 2021-03-31T11:13:28-04:00 EPA : Rename ApiAnn to EPAnn Follow-up from !2418, see #19579 Updates haddock submodule - - - - - d03005e6 by Alan Zimmerman at 2021-03-31T11:13:28-04:00 EPA : rename 'api annotations' to 'exact print annotations' In comments, and notes. Follow-up from !2418, see #19579 - - - - - 49bc1e9e by Alan Zimmerman at 2021-03-31T11:13:28-04:00 EPA : rename AnnAnchor to EpaAnchor Follow-up from !2418, see #19579 - - - - - 798d8f80 by Alan Zimmerman at 2021-03-31T11:13:28-04:00 EPA : Rename AnnComment to EpaComment Follow-up from !2418, see #19579 - - - - - 317295da by Simon Peyton Jones at 2021-03-31T11:14:04-04:00 Avoid fundep-caused loop in the typechecker Ticket #19415 showed a nasty typechecker loop, which can happen with fundeps that do not satisfy the coverage condition. This patch fixes the problem. It's described in GHC.Tc.Solver.Interact Note [Fundeps with instances] It's not a perfect solution, as the Note explains, but it's better than the status quo. - - - - - aaf8e293 by Ryan Scott at 2021-03-31T11:14:39-04:00 Add regression tests for #17772 and #18308 Resolves #17772. Addresses one part of #18308. - - - - - efe5fdab by Ben Gamari at 2021-03-31T11:15:14-04:00 gitlab-ci: Extend expiration time of simple perf job artifacts - - - - - 5192183f by Oleg Grenrus at 2021-04-01T00:39:28-04:00 import Data.List with explicit import list - - - - - bddecda1 by Oleg Grenrus at 2021-04-01T00:39:28-04:00 Data.List specialization to [] - Remove GHC.OldList - Remove Data.OldList - compat-unqualified-imports is no-op - update haddock submodule - - - - - 751b2144 by Sylvain Henry at 2021-04-01T00:40:07-04:00 Encapsulate the EPS IORef in a newtype - - - - - 29326979 by Sylvain Henry at 2021-04-01T00:40:07-04:00 Properly initialise UnitEnv - - - - - 0219297c by Sylvain Henry at 2021-04-01T00:40:07-04:00 Move unit DBs in UnitEnv Also make the HomeUnit optional to keep the field strict and prepare for UnitEnvs without a HomeUnit (e.g. in Plugins envs, cf #14335). - - - - - 7acfb617 by Sylvain Henry at 2021-04-01T00:40:07-04:00 Move HPT in UnitEnv - - - - - 85d7056a by Sylvain Henry at 2021-04-01T00:40:07-04:00 Move the EPS into UnitEnv - - - - - 706fad60 by Sylvain Henry at 2021-04-01T00:40:07-04:00 Fix tests - - - - - b2f51099 by Ben Gamari at 2021-04-01T08:21:30-04:00 ghc-bignum: Add missing source files to cabal file - - - - - 9b05b601 by Ben Gamari at 2021-04-01T08:21:30-04:00 ghc-boot: Use cabal-version: 3.0 - - - - - 75e594d0 by Ben Gamari at 2021-04-01T08:21:30-04:00 libiserv: Add description - - - - - 2266bdae by Ben Gamari at 2021-04-01T08:21:30-04:00 configure: Update comment describing versioning policy As noted in my comment on #19058, this comment was previously a bit misleading in the case of stable branches. - - - - - 65c50d8d by Ben Gamari at 2021-04-01T08:21:30-04:00 gitlab-ci: Drop Debian 8 job - - - - - d44e42a2 by Vladislav Zavialov at 2021-04-01T08:22:06-04:00 Add missing axiom exports for CharToNat/NatToChar When the CharToNat and NatToChar type families were added, the corresponding axioms were not exported. This led to a failure much like #14934 - - - - - 15b6c9f9 by Alfredo Di Napoli at 2021-04-01T16:13:23-04:00 Compute Severity of diagnostics at birth This commit further expand on the design for #18516 by getting rid of the `defaultReasonSeverity` in favour of a function called `diagReasonSeverity` which correctly takes the `DynFlags` as input. The idea is to compute the `Severity` and the `DiagnosticReason` of each message "at birth", without doing any later re-classifications, which are potentially error prone, as the `DynFlags` might evolve during the course of the program. In preparation for a proper refactoring, now `pprWarning` from the Parser.Ppr module has been renamed to `mkParserWarn`, which now takes a `DynFlags` as input. We also get rid of the reclassification we were performing inside `printOrThrowWarnings`. Last but not least, this commit removes the need for reclassify inside GHC.Tc.Errors, and also simplifies the implementation of `maybeReportError`. Update Haddock submodule - - - - - 84b76f60 by Viktor Dukhovni at 2021-04-01T16:13:59-04:00 Chiral foldable caveats - - - - - 07393306 by Viktor Dukhovni at 2021-04-01T16:13:59-04:00 Address review feedback on chirality Also added nested foldr example for `concat`. - - - - - 8ef6eaf7 by Ben Gamari at 2021-04-02T05:15:23-04:00 sdist: Fix packaging of Windows tarballs These now live in the ghc-tarballs/mingw-w64 directory. Fixes #19316. - - - - - 82d8847e by Ben Gamari at 2021-04-02T05:15:23-04:00 gitlab-ci: CI wibbles Ensure that deb10-dwarf artifacts are preserved. - - - - - ee877571 by Ben Gamari at 2021-04-02T05:15:23-04:00 gitlab-ci: Ignore performance metrics failures in release jobs We don't want these failing merely due to performance metrics - - - - - ee55d57e by Matthew Pickering at 2021-04-02T05:15:59-04:00 Fix copy+pasto in Sanity.c - - - - - 78ca4a27 by Ben Gamari at 2021-04-02T05:16:35-04:00 testsuite: Make passFail a boolean - - - - - a9154662 by Ben Gamari at 2021-04-02T05:16:35-04:00 testsuite: Check test stats only after test correctness Ticket #19576 noted that a test that failed in correctness (e.g. due to stderr mismatch) *and* failed due to a metrics change would report misleading stats. This was due to the testsuite driver *first* checking stats, before checking for correctness. Fix this. Closes #19576. - - - - - c265d19f by Ben Gamari at 2021-04-02T05:17:11-04:00 testsuite: Add test for #7275 - - - - - ce706fae by Sebastian Graf at 2021-04-02T05:17:47-04:00 Pmc: Add regression test for #19622 It appears that the issue has already been fixed. Judging by the use of a pattern synonym with a provided constraint, my bet is on 1793ca9d. Fixes #19622. - - - - - 918d5021 by Ben Gamari at 2021-04-05T20:37:28-04:00 configure: Fix parsing of ARM triples To support proper parsing of arm64 targets, we needed to adjust the GHC_LLVM_TARGET function to allow parsing arm64-apple-darwin into aarch64. This however discared the proper os detection. To rectify this, we'll pull the os detection into separate block. Fixes #19173. - - - - - 9c9adbd0 by Oleg Grenrus at 2021-04-05T20:38:07-04:00 Implement proposal 403: Lexer cleanup This allows Other Numbers to be used in identifiers, and also documents other, already existing lexer divergence from Haskell Report - - - - - 89acbf35 by Matthew Pickering at 2021-04-05T20:38:42-04:00 Add special case to stripStgTicksTop for [] In the common case where the list of ticks is empty, building a thunk just applies 'reverse' to '[]' which is quite wasteful. - - - - - 77772bb1 by Harry Garrood harry at garrood.me at 2021-04-05T20:39:19-04:00 Add type signature for TargetContents.go These changes made it slightly easier for me to work out what was going on in this test. I've also fixed a typo in the comments. - - - - - 49528121 by Alfredo Di Napoli at 2021-04-05T20:39:54-04:00 Introduce SevIgnore Severity to suppress warnings This commit introduces a new `Severity` type constructor called `SevIgnore`, which can be used to classify diagnostic messages which are not meant to be displayed to the user, for example suppressed warnings. This extra constructor allows us to get rid of a bunch of redundant checks when emitting diagnostics, typically in the form of the pattern: ``` when (optM Opt_XXX) $ addDiagnosticTc (WarningWithFlag Opt_XXX) ... ``` Fair warning! Not all checks should be omitted/skipped, as evaluating some data structures used to produce a diagnostic might still be expensive (e.g. zonking, etc). Therefore, a case-by-case analysis must be conducted when deciding if a check can be removed or not. Last but not least, we remove the unnecessary `CmdLine.WarnReason` type, which is now redundant with `DiagnosticReason`. - - - - - 3483c3de by Alfredo Di Napoli at 2021-04-05T20:39:54-04:00 Correct warning for deprecated and unrecognised flags Fixes #19616. This commit changes the `GHC.Driver.Errors.handleFlagWarnings` function to rely on the newly introduced `DiagnosticReason`. This allows us to correctly pretty-print the flags which triggered some warnings and in turn remove the cruft around this function (like the extra filtering and the `shouldPrintWarning` function. - - - - - 54247fb1 by Joachim Breitner at 2021-04-05T20:40:30-04:00 ./configure: Indicate that GHC=… should be a full path and not just the name on the binary on the `$PATH`. - - - - - 5db116e9 by Joachim Breitner at 2021-04-05T20:40:30-04:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 2783d498 by Luite Stegeman at 2021-04-05T20:41:06-04:00 fix sub-word literals in GHCi - - - - - 33b88645 by Andreas Klebinger at 2021-04-05T20:41:41-04:00 Add regression test for T19474. In version 0.12.2.0 of vector when used with GHC-9.0 we rebox values from storeable mutable vectors. This should catch such a change in the future. - - - - - 939fa61c by Łukasz Gołębiewski at 2021-04-05T20:42:17-04:00 Fixes Monad's associativity docs It is incorrectly displayed in hackage as: `m1 <*> m2 = m1 >>= (x1 -> m2 >>= (x2 -> return (x1 x2)))` which isn't correct Haskell - - - - - 10782edf by Simon Jakobi at 2021-04-05T20:42:53-04:00 Mark p6 and T3333 as fragile See #17018. - - - - - 048af266 by Andreas Klebinger at 2021-04-05T20:43:27-04:00 One-Shotify GHC.Utils.Monad.State (#18202) - - - - - 83654240 by Matthew Pickering at 2021-04-05T20:44:02-04:00 Add (expect_broken) test for #11545 - - - - - 53cf2c04 by Ben Gamari at 2021-04-05T20:44:37-04:00 hadrian: Refactor hlint target Not only does this eliminate some code duplication but we also add a maximum core count to HLint's command-line, hopefully avoiding issue #19600. - - - - - eac9d376 by Ben Gamari at 2021-04-05T20:45:12-04:00 hadrian: Fix build-stack-nix As noted by #19589, `stack` is not stateful and therefore must be passed `--nix` on every invocation. Do so. Fixes #19589. - - - - - bfe8ef8e by Ben Gamari at 2021-04-05T20:45:46-04:00 rts: Fix usage of pthread_setname_np Previously we used this non-portable function unconditionally, breaking FreeBSD. Fixes #19637. - - - - - 403bf88c by Ben Gamari at 2021-04-05T20:46:21-04:00 Revert "[ci/arm/darwin/testsuite] Forwards ports from GHC-8.10" This reverts commit 0cbdba2768d84a0f6832ae5cf9ea1e98efd739da. - - - - - 54880c13 by Sylvain Henry at 2021-04-05T20:46:59-04:00 Bignum: fix invalid hs-boot declaration (#19638) - - - - - 247684ad by Sylvain Henry at 2021-04-05T20:47:37-04:00 Bignum: remove unused extra files - - - - - 2e3a6fba by Adam Sandberg Ericsson at 2021-04-07T12:37:11-04:00 hadrian: don't hardcode -fuse-ld=gold in hsc2hs wrapper #19514 - - - - - b06e457d by Simon Peyton Jones at 2021-04-07T12:37:47-04:00 Make specialisation a bit more aggressive The patch commit c43c981705ec33da92a9ce91eb90f2ecf00be9fe Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Oct 23 16:15:51 2009 +0000 Fix Trac #3591: very tricky specialiser bug fixed a nasty specialisation bug /for DFuns/. Eight years later, this patch commit 2b74bd9d8b4c6b20f3e8d9ada12e7db645cc3c19 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 7 12:03:51 2017 +0100 Stop the specialiser generating loopy code extended it to work for /imported/ DFuns. But in the process we lost the fact that it was needed only for DFuns! As a result we started silently losing useful specialisation for non-DFuns. But there was no regression test to spot the lossage. Then, nearly four years later, Andreas filed #19599, which showed the lossage in high relief. This patch restores the DFun test, and adds Note [Avoiding loops (non-DFuns)] to explain why. This is undoubtedly a very tricky corner of the specialiser, and one where I would love to have a more solid argument, even a paper! But meanwhile I think this fixes the lost specialisations without introducing any new loops. I have two regression tests, T19599 and T19599a, so I hope we'll know if we lose them again in the future. Vanishingly small effect on nofib. A couple of compile-time benchmarks improve T9872a(normal) ghc/alloc 1660559328.0 1643827784.0 -1.0% GOOD T9872c(normal) ghc/alloc 1691359152.0 1672879384.0 -1.1% GOOD Many others wiggled around a bit. Metric Decrease: T9872a T9872c - - - - - 546f8b14 by Matthew Pickering at 2021-04-07T12:38:22-04:00 hadrian: Don't try to build iserv-prof if we don't have profiled libraries Workaround for #19624 - - - - - d014ab0d by Sylvain Henry at 2021-04-07T12:39:00-04:00 Remove dynamic-by-default (#16782) Dynamic-by-default was a mechanism to automatically select the -dynamic way for some targets. It was implemented in a convoluted way: it was defined as a flavour option, hence it couldn't be passed as a global settings (which are produced by `configure` before considering flavours), so a build system rule was used to pass -DDYNAMIC_BY_DEFAULT to the C compiler so that deriveConstants could infer it. * Make build system has it disabled for 8 years (951e28c0625ece7e0db6ac9d4a1e61e2737b10de) * It has never been implemented in Hadrian * Last time someone tried to enable it 1 year ago it didn't work (!2436) * Having this as a global constant impedes making GHC multi-target (see !5427) This commit fully removes support for dynamic-by-default. If someone wants to reimplement something like this, it would probably need to move the logic in the compiler. (Doing this would probably need some refactoring of the way the compiler handles DynFlags: DynFlags are used to store and to pass enabled ways to many parts of the compiler. It can be set by command-line flags, GHC API, global settings. In multi-target GHC, we will use DynFlags to load the target platform and its constants: but at this point with the current DynFlags implementation we can't easily update the existing DynFlags with target-specific options such as dynamic-by-default without overriding ways previously set by the user.) - - - - - 88d8a0ed by James Foster at 2021-04-07T14:17:31-04:00 Change foldl' to inline when partially applied (#19534) And though partially applied foldl' is now again inlined, #4301 has not resurfaced, and appears to be resolved. - - - - - 898afe90 by Matthew Pickering at 2021-04-08T08:07:10-04:00 Stop retaining SimplEnvs in unforced Unfoldings Related to #15455 - - - - - 8417e866 by Matthew Pickering at 2021-04-08T08:07:10-04:00 Don't retain reference to whole TcLclEnv in SkolemTV - - - - - 352a463b by Matthew Pickering at 2021-04-08T08:07:10-04:00 Use DmdEnv rather than VarEnv DmdEnv - - - - - adc52bc8 by Matthew Pickering at 2021-04-08T08:07:10-04:00 Make updTcRef force the result This can lead to a classic thunk build-up in a TcRef Fixes #19596 - - - - - eaa1461a by Matthew Pickering at 2021-04-08T08:07:11-04:00 Make sure mergeWithKey is inlined and applied strictly In the particular case of `DmdEnv`, not applying this function strictly meant 500MB of thunks were accumulated before the values were forced at the end of demand analysis. - - - - - 629a5e98 by Matthew Pickering at 2021-04-08T08:07:11-04:00 Some extra strictness in Demand.hs It seems that these places were supposed to be forced anyway but the forcing has no effect because the result was immediately placed in a lazy box. - - - - - 42d88003 by Matthew Pickering at 2021-04-08T08:07:11-04:00 Make sure result of demand analysis is forced promptly This avoids a big spike in memory usage during demand analysis. Part of fixing #15455 ------------------------- Metric Decrease: T18698a T18698b T9233 T9675 T9961 ------------------------- - - - - - e0d861d4 by Matthew Pickering at 2021-04-08T08:07:11-04:00 T11545 now also passes due to modifications in demand analysis Fixes #11545 - - - - - a3cc9a29 by Ryan Scott at 2021-04-08T08:07:45-04:00 Fix #19649 by using filterInScopeM in rnFamEqn Previously, associated type family instances would incorrectly claim to implicitly quantify over type variables bound by the instance head in the `HsOuterImplicit`s that `rnFamEqn` returned. This is fixed by using `filterInScopeM` to filter out any type variables that the instance head binds. Fixes #19649. - - - - - 6e8e2e08 by Alfredo Di Napoli at 2021-04-08T08:08:20-04:00 Move Iface.Load errors into Iface.Errors module This commit moves the error-related functions in `GHC.Iface.Load` into a brand new module called `GHC.Iface.Errors`. This will avoid boot files and circular dependencies in the context of #18516, in the pretty-printing modules. - - - - - 8a099701 by Ben Gamari at 2021-04-09T03:30:26-04:00 CoreTidy: enhance strictness note - - - - - 0bdb867e by Sylvain Henry at 2021-04-09T03:30:26-04:00 CoreTidy: handle special cases to preserve more sharing. Metric Decrease: T16577 - - - - - c02ac1bb by Andreas Klebinger at 2021-04-09T03:31:02-04:00 Re-export GHC.Bits from GHC.Prelude with custom shift implementation. This allows us to use the unsafe shifts in non-debug builds for performance. For older versions of base we instead export Data.Bits See also #19618 - - - - - 35407d67 by Peter Trommler at 2021-04-09T03:31:37-04:00 testsuite: Skip T18623 on powerpc64le In commit f3c23939 T18623 is disabled for aarch64. The limit seems to be too low for powerpc64le, too. This could be because tables next to code is not supported and our code generator produces larger code on PowerPC. - - - - - d8f04425 by Peter Trommler at 2021-04-09T03:31:37-04:00 Fix typo - - - - - fd5ca9c3 by Peter Trommler at 2021-04-09T03:31:37-04:00 testsuite/ppc64le: Mark UnboxedTuples test broken - - - - - d4a71b0c by Matthew Pickering at 2021-04-09T03:32:12-04:00 Avoid repeated zonking and tidying of types in `relevant_bindings` The approach taking in this patch is that the tcl_bndrs in TcLclEnv are zonked and tidied eagerly, so that work can be shared across multiple calls to `relevant_bindings`. To test this patch I tried without the `keepThisHole` filter and the test finished quickly. Fixes #14766 - - - - - 28d2d646 by Matthew Pickering at 2021-04-09T03:32:47-04:00 Don't tidy type in pprTypeForUser There used to be some cases were kinds were not generalised properly before being printed in GHCi. This seems to have changed in the past so now it's uncessary to tidy before printing out the test case. ``` > :set -XPolyKinds > data A x y > :k A k1 -> k2 -> A ``` This tidying was causing issues with an attempt to increase sharing by making `mkTyConApp` (see !4762) - - - - - 6d29e635 by Matthew Pickering at 2021-04-09T03:33:22-04:00 Add perf test for #15304 The test max memory usage improves dramatically with the fixes to memory usage in demand analyser from #15455 - - - - - 70c39e22 by Douglas Wilson at 2021-04-09T03:33:56-04:00 [docs] release notes for !4729 + !3678 Also includes small unrelated type fix - - - - - c1d6daab by Matthew Pickering at 2021-04-09T03:34:31-04:00 Update HACKING.md - - - - - a951e069 by Sylvain Henry at 2021-04-09T03:35:08-04:00 Bignum: add BigNat Eq/Ord instances (#19647) - - - - - cd391756 by Richard Eisenberg at 2021-04-10T05:29:21-04:00 Tweak kick-out condition K2b to deal with LHSs Kick out condition K2b really only makes sense for inerts with a type variable on the left. This updates the commentary and the code to skip this check for inerts with type families on the left. Also cleans up some commentary around solver invariants and adds Note [K2b]. Close #19042. test case: typecheck/should_compile/T19042 - - - - - 7536126e by Richard Eisenberg at 2021-04-10T05:29:21-04:00 Kick out fewer equalities by thinking harder Close #17672. By scratching our heads quite hard, we realized that we should never kick out Given/Nominal equalities. This commit tweaks the kick-out conditions accordingly. See also Note [K4] which describes what is going on. This does not fix a known misbehavior, but it should be a small improvement in both practice (kicking out is bad, and we now do less of it) and theory (a Given/Nominal should behave just like a filled-in metavariable, which has no notion of kicking out). - - - - - 449be647 by Richard Eisenberg at 2021-04-10T05:29:21-04:00 Clarify commentary around the constraint solver No changes to code; no changes to theory. Just better explanation. - - - - - 3c98dda6 by Richard Eisenberg at 2021-04-10T05:29:21-04:00 Test #19665 as expect_broken, with commentary - - - - - 6b1d0b9c by Koz Ross at 2021-04-10T05:29:59-04:00 Implement list `fold` and `foldMap` via mconcat - This allows specialized mconcat implementations an opportunity to combine elements efficiently in a single pass. - Inline the default implementation of `mconcat`, this may result in list fusion. - In Monoids with strict `mappend`, implement `mconcat` as a strict left fold: * And (FiniteBits) * Ior (FiniteBits) * Xor (FiniteBits) * Iff (FiniteBits) * Max (Ord) * Min (Ord) * Sum (Num) * Product (Num) * (a -> m) (Monoid m) - Delegate mconcat for WrappedMonoid to the underlying monoid. Resolves: #17123 Per the discussion in !4890, we expect some stat changes: * T17123(normal) run/alloc 403143160.0 4954736.0 -98.8% GOOD This is the expected improvement in `fold` for a long list of `Text` elements. * T13056(optasm) ghc/alloc 381013328.0 447700520.0 +17.5% BAD Here there's an extra simplifier run as a result of the new methods of the Foldable instance for List. It looks benign. The test is a micro benchmark that compiles just the derived foldable instances for a pair of structures, a cost of this magnitude is not expected to extend to more realistic programs. * T9198(normal) ghc/alloc 504661992.0 541334168.0 +7.3% BAD This test regressed from 8.10 and 9.0 back to exponential blowup. This metric also fluctuates, for reasons not yet clear. The issue here is the exponetial blowup, not this MR. Metric Decrease: T17123 Metric Increase: T9198 T13056 - - - - - 3f851bbd by Sylvain Henry at 2021-04-10T05:30:37-04:00 Enhance pretty-printing perf A few refactorings made after looking at Core/STG * Use Doc instead of SDoc in pprASCII to avoid passing the SDocContext that is never used. * Inline every SDoc wrappers in GHC.Utils.Outputable to expose Doc constructs * Add text/[] rule for empty strings (i.e., text "") * Use a single occurrence of pprGNUSectionHeader * Use bangs on Platform parameters and some others Metric Decrease: ManyAlternatives ManyConstructors T12707 T13035 T13379 T18698a T18698b T1969 T3294 T4801 T5321FD T783 - - - - - 9c762f27 by Sylvain Henry at 2021-04-10T05:31:14-04:00 Generate parser for DerivedConstants.h deriveConstants utility now generates a Haskell parser for DerivedConstants.h. It can be used to replace the one used to read platformConstants file. - - - - - 085983e6 by Sylvain Henry at 2021-04-10T05:31:14-04:00 Read constants header instead of global platformConstants With this patch we switch from reading the globally installed platformConstants file to reading the DerivedConstants.h header file that is bundled in the RTS unit. When we build the RTS unit itself, we get it from its includes directories. The new parser is more efficient and strict than the Read instance for PlatformConstants and we get about 2.2MB less allocations in every cases. However it only really shows in tests that don't allocate much, hence the following metric decreases. Metric Decrease: Naperian T10421 T10547 T12150 T12234 T12425 T13035 T18304 T18923 T5837 T6048 T18140 - - - - - 2cdc95f9 by Sylvain Henry at 2021-04-10T05:31:14-04:00 Don't produce platformConstants file It isn't used for anything anymore - - - - - b699c4fb by Sylvain Henry at 2021-04-10T05:31:14-04:00 Constants: add a note and fix minor doc glitches - - - - - eb1a86bb by John Ericson at 2021-04-10T05:31:49-04:00 Allow C-- to scrutinize non-native-size words - - - - - c363108e by John Ericson at 2021-04-10T05:31:49-04:00 Add missing relational constant folding for sized numeric types - - - - - b39dec86 by Facundo Domínguez at 2021-04-10T05:32:28-04:00 Report actual port in libiserv:Remote.Slave.startSlave This allows to start iserv by passing port 0 to startSlave, which in turns allows to get an available port when no port is known to be free a priori. - - - - - 94d48ec9 by Matthew Pickering at 2021-04-10T05:33:03-04:00 Use CI_MERGE_REQUEST_SOURCE_BRANCH_NAME rather than undefined GITLAB_CI_BRANCH env var See https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - - - - - d39a2b24 by Matthew Pickering at 2021-04-10T05:33:03-04:00 tests: Allow --skip-perf-tests/--only-perf-tests to be used with --ignore-perf-failures - - - - - 6974c9e4 by Matthew Pickering at 2021-04-10T05:33:38-04:00 Fix magicDict in ghci (and in the presence of other ticks) The problem was that ghci inserts some ticks around the crucial bit of the expression. Just like in some of the other rules we now strip the ticks so that the rule fires more reliably. It was possible to defeat magicDict by using -fhpc as well, so not just an issue in ghci. Fixes #19667 and related to #19673 - - - - - 792d9289 by Simon Peyton Jones at 2021-04-12T13:50:49-04:00 More accurate SrcSpan when reporting redundant constraints We want an accurate SrcSpan for redundant constraints: • Redundant constraint: Eq a • In the type signature for: f :: forall a. Eq a => a -> () | 5 | f :: Eq a => a -> () | ^^^^ This patch adds some plumbing to achieve this * New data type GHC.Tc.Types.Origin.ReportRedundantConstraints (RRC) * This RRC value is kept inside - FunSigCtxt - ExprSigCtxt * Then, when reporting the error in GHC.Tc.Errors, use this SrcSpan to control the error message: GHC.Tc.Errors.warnRedundantConstraints Quite a lot of files are touched in a boring way. - - - - - 18cbff86 by Matthew Pickering at 2021-04-12T13:51:23-04:00 template-haskell: Run TH splices with err_vars from current context Otherwise, errors can go missing which arise when running the splices. Fixes #19470 - - - - - 89ff1230 by Matthew Pickering at 2021-04-12T13:51:58-04:00 Add regression test for T19615 Fixes #19615 - - - - - 9588f3fa by Matthew Pickering at 2021-04-12T13:52:33-04:00 Turn T11545 into a normal performance test This makes it more robust to people running it with `quick` flavour and so on. - - - - - d1acda98 by Matthew Pickering at 2021-04-12T17:07:01-04:00 CI: Also ignore metric decreases on master Otherwise, if the marge batch has decreased metrics, they will fail on master which will result in the pipeline being cut short and the expected metric values for the other jobs will not be updated. - - - - - 6124d172 by Stefan Schulze Frielinghaus at 2021-04-13T18:42:40-04:00 hadrian: Provide build rule for ghc-stage3 wrapper - - - - - ef013593 by Simon Peyton Jones at 2021-04-13T18:43:15-04:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T13056, because we generate more specialised code. This seems OK. Metric Increase: T13056 - - - - - 8d87975e by Sylvain Henry at 2021-04-13T18:43:53-04:00 Produce constant file atomically (#19684) - - - - - 1e2e62a4 by Ryan Scott at 2021-04-13T18:44:28-04:00 Add {lifted,unlifted}DataConKey to pretendNameIsInScope's list of Names Fixes #19688. - - - - - b665d983 by Ben Gamari at 2021-04-13T20:04:53-04:00 configure: Bump version to 9.3 Bumps the `haddock` submodule. - - - - - 726da09e by Matthew Pickering at 2021-04-14T05:07:45-04:00 Always generate ModDetails from ModIface This vastly reduces memory usage when compiling with `--make` mode, from about 900M when compiling Cabal to about 300M. As a matter of uniformity, it also ensures that reading from an interface performs the same as using the in-memory cache. We can also delete all the horrible knot-tying in updateIdInfos. Goes some way to fixing #13586 Accept new output of tests fixing some bugs along the way ------------------------- Metric Decrease: T12545 ------------------------- - - - - - 78ed7adf by Hécate Moonlight at 2021-04-14T14:40:46-04:00 Data.List strictness optimisations for maximumBy and minimumBy follow-up from !4675 - - - - - 79e5c867 by Peter Trommler at 2021-04-14T14:41:21-04:00 Prelude: Fix version bound on Bits import Fixes #19683 - - - - - 5f172299 by Adam Gundry at 2021-04-14T19:42:18-04:00 Add isInjectiveTyCon check to opt_univ (fixes #19509) - - - - - cc1ba576 by Matthew Pickering at 2021-04-14T19:42:53-04:00 Fix some negation issues when creating FractionalLit There were two different issues: 1. integralFractionalLit needed to be passed an already negated value. (T19680) 2. negateFractionalLit did not actually negate the argument, only flipped the negation flag. (T19680A) Fixes #19680 - - - - - da92e728 by Matthew Pickering at 2021-04-15T12:27:44-04:00 hie: Initialise the proper environment for calling dsExpr We now use DsM as the base monad for writing hie files and properly initialise it from the TcGblEnv. Before, we would end up reading the interface file from disk for the module we were currently compiling. The modules iface then ended up in the EPS causing all sorts of subtle carnage, including difference in the generated core and haddock emitting a lot of warnings. With the fix, the module in the TcGblEnv is set correctly so the lookups happen in the local name env rather than thinking the identifier comes from an external package. Fixes #19693 and #19334 - - - - - 0a8c14bd by Simon Peyton Jones at 2021-04-15T12:28:18-04:00 Fix handling ze_meta_tv_env in GHC.Tc.Utils.Zonk As #19668 showed, there was an /asymptotic/ slow-down in zonking in GHC 9.0, exposed in test T9198. The bug was actually present in earlier compilers, but by a fluke didn't actually show up in any of our tests; but adding Quick Look exposed it. The bug was that in zonkTyVarOcc we 1. read the meta-tyvar-env variable 2. looked up the variable in the env 3. found a 'miss' 4. looked in the variable, found `Indirect ty` 5. zonked `ty` 6. update the env *gotten from step 1* to map the variable to its zonked type. The bug is that we thereby threw away all teh work done in step 4. In T9198 that made an enormous, indeed asymptotic difference. The fix is easy: use updTcRef. I commented in `Note [Sharing when zonking to Type]` ------------------------- Metric Decrease: T9198 ------------------------- - - - - - 7bd12940 by Simon Peyton Jones at 2021-04-17T22:56:32+01:00 Improve CSE in STG-land This patch fixes #19717, a long-standing bug in CSE for STG, which led to a stupid loss of CSE in some situations. It's explained in Note [Trivial case scrutinee], which I have substantially extended. - - - - - c71b2204 by Simon Peyton Jones at 2021-04-17T23:03:56+01:00 Improvements in SpecConstr * Allow under-saturated calls to specialise See Note [SpecConstr call patterns] This just allows a bit more specialisation to take place. * Don't discard calls from un-specialised RHSs. This was a plain bug in `specialise`, again leading to loss of specialisation. Refactoring yields an `otherwise` case that is easier to grok. * I refactored CallPat to become a proper data type, not a tuple. All this came up when I was working on eta-reduction. The ticket is #19672. The nofib results are mostly zero, with a couple of big wins: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- awards +0.2% -0.1% -18.7% -18.8% 0.0% comp_lab_zift +0.2% -0.2% -23.9% -23.9% 0.0% fft2 +0.2% -1.0% -34.9% -36.6% 0.0% hpg +0.2% -0.3% -18.4% -18.4% 0.0% mate +0.2% -15.7% -19.3% -19.3% +11.1% parser +0.2% +0.6% -16.3% -16.3% 0.0% puzzle +0.4% -19.7% -33.7% -34.0% 0.0% rewrite +0.2% -0.5% -20.7% -20.7% 0.0% -------------------------------------------------------------------------------- Min +0.2% -19.7% -48.1% -48.9% 0.0% Max +0.4% +0.6% -1.2% -1.1% +11.1% Geometric Mean +0.2% -0.4% -21.0% -21.1% +0.1% I investigated the 0.6% increase on 'parser'. It comes because SpecConstr has a limit of 3 specialisations. With HEAD, hsDoExpr has 2 specialisations, and then a further several from the specialised bodies, of which 1 is picked. With this patch we get 3 specialisations right off the bat, so we discard all from the recursive calls. Turns out that that's not the best choice, but there is no way to tell that. I'm accepting it. NB: these figures actually come from this patch plus the preceding one for StgCSE, but I think the gains come from SpecConstr. - - - - - 40d28436 by Matthew Pickering at 2021-04-18T11:09:32-04:00 Only load package environment file once when starting GHCi Since d880d6b2e48268f5ed4d3eb751fe24cc833e9221 the parsing of the environment files was moved to `parseDynamicFlags`, under the assumption it was typically only called once. It turns out not to be true in GHCi and this led to continually reparsing the environment file whenever a new option was set, the options were appended to the package state and hence all packages reloaded, as it looked like the options were changed. The simplest fix seems to be a clearer specification: > Package environment files are only loaded in GHCi during initialisation. Fixes #19650 - - - - - a4234697 by Ben Gamari at 2021-04-18T20:12:26-04:00 Fix Haddock reference - - - - - 78288b97 by Ben Gamari at 2021-04-18T20:12:26-04:00 users-guide: Clarify GHC2021 documentation Point out that GHC2021 doesn't offer the same degree of stability that Haskell2010 does, as noted by @phadej. - - - - - b5189749 by Ben Gamari at 2021-04-18T20:12:26-04:00 users guide: Sort lists of implied language extensions - - - - - 0165b029 by Ben Gamari at 2021-04-18T20:12:26-04:00 users-guide: Add missing FieldSelectors to GHC2021 list - - - - - 0b398d55 by Ryan Scott at 2021-04-18T20:13:01-04:00 Use correct precedence in Complex's Read1/Show1 instances Fixes #19719. - - - - - 8b5e5b05 by Andreas Schwab at 2021-04-19T15:40:25-04:00 Enable tables next to code for riscv64 This requires adding another rewrite to the mangler, to avoid generating PLT entries. - - - - - 0619fb0f by Alan Zimmerman at 2021-04-19T15:41:00-04:00 EPA: cleanups after the merge Remove EpaAnn type synonym, rename EpaAnn' to EpaAnn. Closes #19705 Updates haddock submodule -- Change data EpaAnchor = AR RealSrcSpan | AD DeltaPos To instead be data EpaAnchor = AnchorReal RealSrcSpan | AnchorDelta DeltaPos Closes #19699 -- Change data DeltaPos = DP { deltaLine :: !Int, deltaColumn :: !Int } To instead be data DeltaPos = SameLine { deltaColumn :: !Int } | DifferentLine { deltaLine :: !Int, startColumn :: !Int } Closes #19698 -- Also some clean-ups of unused parts of check-exact. - - - - - 99bd4ae6 by Sebastian Graf at 2021-04-20T10:17:52+02:00 Factor out DynFlags from WorkWrap.Utils Plus a few minor refactorings: * Introduce `normSplitTyConApp_maybe` to Core.Utils * Reduce boolean blindness in the Bool argument to `wantToUnbox` * Let `wantToUnbox` also decide when to drop an argument, cleaning up `mkWWstr_one` - - - - - ee5dadad by Sebastian Graf at 2021-04-20T10:17:55+02:00 Refactor around `wantToUnbox` I renamed `wantToUnbox` to `wantToUnboxArg` and then introduced `wantToUnboxResult`, which we call in `mkWWcpr_one` now. I also deleted `splitArgType_maybe` (the single call site outside of `wantToUnboxArg` actually cared about the result type of a function, not an argument) and `splitResultType_maybe` (which is entirely superceded by `wantToUnboxResult`. - - - - - 0e541137 by Sebastian Graf at 2021-04-20T10:17:55+02:00 Worker/wrapper: Consistent names - - - - - fdbead70 by Sebastian Graf at 2021-04-20T14:55:16+02:00 Worker/wrapper: Refactor CPR WW to work for nested CPR (#18174) In another small step towards bringing a manageable variant of Nested CPR into GHC, this patch refactors worker/wrapper to be able to exploit Nested CPR signatures. See the new Note [Worker/wrapper for CPR]. The nested code path is currently not triggered, though, because all signatures that we annotate are still flat. So purely a refactoring. I am very confident that it works, because I ripped it off !1866 95% unchanged. A few test case outputs changed, but only it's auxiliary names only. I also added test cases for #18109 and #18401. There's a 2.6% metric increase in T13056 after a rebase, caused by an additional Simplifier run. It appears b1d0b9c saw a similar additional iteration. I think it's just a fluke. Metric Increase: T13056 - - - - - b7980b5d by Simon Peyton Jones at 2021-04-20T21:33:09-04:00 Fix occAnalApp In OccurAnal the function occAnalApp was failing to reset occ_encl to OccVanilla. This omission sometimes resulted in over-pessimistic occurrence information. I tripped over this when analysing eta-expansions. Compile times in perf/compiler fell slightly (no increases) PmSeriesG(normal) ghc/alloc 50738104.0 50580440.0 -0.3% PmSeriesS(normal) ghc/alloc 64045284.0 63739384.0 -0.5% PmSeriesT(normal) ghc/alloc 94430324.0 93800688.0 -0.7% PmSeriesV(normal) ghc/alloc 63051056.0 62758240.0 -0.5% T10547(normal) ghc/alloc 29322840.0 29307784.0 -0.1% T10858(normal) ghc/alloc 191988716.0 189801744.0 -1.1% T11195(normal) ghc/alloc 282654016.0 281839440.0 -0.3% T11276(normal) ghc/alloc 142994648.0 142338688.0 -0.5% T11303b(normal) ghc/alloc 46435532.0 46343376.0 -0.2% T11374(normal) ghc/alloc 256866536.0 255653056.0 -0.5% T11822(normal) ghc/alloc 140210356.0 138935296.0 -0.9% T12234(optasm) ghc/alloc 60753880.0 60720648.0 -0.1% T14052(ghci) ghc/alloc 2235105796.0 2230906584.0 -0.2% T17096(normal) ghc/alloc 297725396.0 296237112.0 -0.5% T17836(normal) ghc/alloc 1127785292.0 1125316160.0 -0.2% T17836b(normal) ghc/alloc 54761928.0 54637592.0 -0.2% T17977(normal) ghc/alloc 47529464.0 47397048.0 -0.3% T17977b(normal) ghc/alloc 42906972.0 42809824.0 -0.2% T18478(normal) ghc/alloc 777385708.0 774219280.0 -0.4% T18698a(normal) ghc/alloc 415097664.0 409009120.0 -1.5% GOOD T18698b(normal) ghc/alloc 500082104.0 493124016.0 -1.4% GOOD T18923(normal) ghc/alloc 72252364.0 72216016.0 -0.1% T1969(normal) ghc/alloc 811581860.0 804883136.0 -0.8% T5837(normal) ghc/alloc 37688048.0 37666288.0 -0.1% Nice! Metric Decrease: T18698a T18698b - - - - - 7f4d06e6 by Matthew Pickering at 2021-04-22T16:59:42-04:00 driver: Consider dyn_o files when checking recompilation in -c When -dynamic-too is enabled, there are two result files, .o and .dyn_o, therefore we should check both to decide whether to set SourceModified or not. The whole recompilation logic is very messy, a more thorough refactor would be beneficial in this area but this is the minimal patch to fix this more high priority problem. Fixes #17968 and hopefully #17534 - - - - - 4723652a by Fendor at 2021-04-22T17:00:19-04:00 Move 'nextWrapperNum' into 'DsM' and 'TcM' Previously existing in 'DynFlags', 'nextWrapperNum' is a global variable mapping a Module to a number for name generation for FFI calls. This is not the right location for 'nextWrapperNum', as 'DynFlags' should not contain just about any global variable. - - - - - 350f4f61 by Viktor Dukhovni at 2021-04-22T17:00:54-04:00 Support R_X86_64_TLSGD relocation on FreeBSD The FreeBSD C <ctype.h> header supports per-thread locales by exporting a static inline function that references the `_ThreadRuneLocale` thread-local variable. This means that object files that use e.g. isdigit(3) end up with TLSGD(19) relocations, and would not load into ghci or the language server. Here we add support for this type of relocation, for now just on FreeBSD, and only for external references to thread-specifics defined in already loaded dynamic modules (primarily libc.so). This is sufficient to resolve the <ctype.h> issues. Runtime linking of ".o" files which *define* new thread-specific variables would be noticeably more difficult, as this would likely require new rtld APIs. - - - - - aa685c50 by Viktor Dukhovni at 2021-04-22T17:00:55-04:00 Add background note in elf_tlsgd.c. Also some code cleanup, and a fix for an (extant unrelated) missing <pthread_np.h> include that should hopefully resolve a failure in the FreeBSD CI build, since it is best to make sure that this MR actually builds on FreeBSD systems other than mine. Some unexpected metric changes on FreeBSD (perhaps because CI had been failing for a while???): Metric Decrease: T3064 T5321Fun T5642 T9020 T12227 T13253-spj T15164 T18282 WWRec Metric Increase: haddock.compiler - - - - - 72b48c44 by Viktor Dukhovni at 2021-04-22T17:00:55-04:00 Block signals in the ticker thread This avoids surprises in the non-threaded runtime with blocked signals killing the process because they're only blocked in the main thread and not in the ticker thread. - - - - - 7bc7eea3 by Viktor Dukhovni at 2021-04-22T17:00:55-04:00 Make tests more portable on FreeBSD - - - - - 0015f019 by Adam Gundry at 2021-04-23T23:05:04+01:00 Rename references to Note [Trees That Grow] consistently [skip ci] I tend to find Notes by (case-sensitive) grep, and I spent a surprisingly long time looking for this Note, because it was referenced inconsistently with different cases, and without the module name. - - - - - d38397fa by Sebastian Graf at 2021-04-26T23:53:56-04:00 Parser: Unbox `ParseResult` Using `UnliftedNewtypes`, unboxed tuples and sums and a few pattern synonyms, we can make `ParseResult` completely allocation-free. Part of #19263. - - - - - 045e5f49 by Oleg Grenrus at 2021-04-26T23:54:34-04:00 Add Eq1 and Ord1 Fixed instances - - - - - 721ea018 by Ben Gamari at 2021-04-26T23:55:09-04:00 codeGen: Teach unboxed sum rep logic about levity Previously Unarise would happily project lifted and unlifted fields to lifted slots. This broke horribly in #19645, where a ByteArray# was passed in a lifted slot and consequently entered. The simplest way to fix this is what I've done here, distinguishing between lifted and unlifted slots in unarise. However, one can imagine more clever solutions, where we coerce the binder to the correct levity with respect to the sum's tag. I doubt that this would be worth the effort. Fixes #19645. - - - - - 9f9fab15 by Ben Gamari at 2021-04-26T23:55:09-04:00 testsuite: Add test for #19645 - - - - - 3339ed49 by Ben Gamari at 2021-04-26T23:55:44-04:00 users-guide: Document deprecation of -funfolding-keeness-factor See #15304. - - - - - 9d34f454 by Ben Gamari at 2021-04-26T23:55:44-04:00 users guide: Various other cleanups - - - - - 06654a6e by Matthew Pickering at 2021-04-26T23:56:18-04:00 Correct treatment of rexported modules in mkModuleNameProvidersMap Before we would get the incorrect error message saying that the rexporting package was the same as the defining package. I think this only affects error messages for now. ``` - it is bound as p-0.1.0.0:P2 by a reexport in package p-0.1.0.0 - it is bound as P by a reexport in package p-0.1.0.0 + it is bound as p-0.1.0.0:P2 by a reexport in package q-0.1.0.0 + it is bound as P by a reexport in package r-0.1.0.0 ``` and the output of `-ddump-mod-map` claimed.. ``` Moo moo-0.0.0.1 (hidden package, reexport by moo-0.0.0.1) ``` - - - - - 6c7fff0b by Simon Peyton Jones at 2021-04-26T23:56:53-04:00 Eliminate unsafeEqualityProof in CorePrep The main idea here is to avoid treating * case e of {} * case unsafeEqualityProof of UnsafeRefl co -> blah specially in CoreToStg. Instead, nail them in CorePrep, by converting case e of {} ==> e |> unsafe-co case unsafeEqualityProof of UnsafeRefl cv -> blah ==> blah[unsafe-co/cv] in GHC.Core.Prep. Now expressions that we want to treat as trivial really are trivial. We can get rid of cpExprIsTrivial. And we fix #19700. A downside is that, at least under unsafeEqualityProof, we substitute in types and coercions, which is more work. But a big advantage is that it's all very simple and principled: CorePrep really gets rid of the unsafeCoerce stuff, as it does empty case, runRW#, lazyId etc. I've updated the overview in GHC.Core.Prep, and added Note [Unsafe coercions] in GHC.Core.Prep Note [Implementing unsafeCoerce] in base:Unsafe.Coerce We get 3% fewer bytes allocated when compiling perf/compiler/T5631, which uses a lot of unsafeCoerces. (It's a happy-generated parser.) Metric Decrease: T5631 - - - - - b9e2491d by Rafal Gwozdzinski at 2021-04-26T23:57:29-04:00 Add GHC.Utils.Error.pprMessages - - - - - 72c1812f by Ben Gamari at 2021-04-26T23:58:16-04:00 rts/m32: Fix bounds check Previously we would check only that the *start* of the mapping was in the bottom 32-bits of address space. However, we need the *entire* mapping to be in low memory. Fix this. Noticed by @Phyx. - - - - - dd0a95a3 by Sasha Bogicevic at 2021-04-26T23:58:56-04:00 18000 Use GHC.IO.catchException in favor of Exception.catch fix #18000 - - - - - c1549069 by Adam Sandberg Ericsson at 2021-04-26T23:59:32-04:00 docs: add a short up-front description for -O, -n, -qn, -I and -Iw - - - - - d9ceb2fb by iori tsu at 2021-04-27T00:00:08-04:00 Add documentation for GHC.Exts.sortWith sortWith has the same type definition as `Data.List.sortOn` (eg: `Ord b => (a -> b) -> [a] -> [a]`). Nonetheless, they behave differently, sortOn being more efficient. This merge request add documentation to reflect on this differences - - - - - dd121fa1 by Ryan Scott at 2021-04-27T00:00:43-04:00 Pretty-print HsArgPar applications correctly (#19737) Previously, the `Outputable` instance for `HsArg` was being used to pretty-print each `HsArgPar` in a list of `HsArg`s individually, which simply doesn't work. In lieu of the `Outputable` instance, we now use a dedicated `pprHsArgsApp` function to print a list of `HsArg`s as a single unit. I have also added documentation to the `Outputable` instance for `HsArg` to more clearly signpost that it is only suitable for debug pretty-printing. Fixes #19737. - - - - - 484a8b2d by Ben Gamari at 2021-04-27T21:57:56-04:00 Introduce -ddump-verbose-inlinings Previously -ddump-inlinings and -dverbose-core2core used in conjunction would have the side-effect of dumping additional information about all inlinings considered by the simplifier. However, I have sometimes wanted this inlining information without the firehose of information produced by -dverbose-core2core. Introduce a new dump flag for this purpose. - - - - - 9ead1b35 by Daniel Rogozin at 2021-04-27T21:58:32-04:00 fix #19736 - - - - - d2399a46 by Sasha Bogicevic at 2021-04-27T21:59:08-04:00 19079 DerivingVia: incorrectly accepts deriving via types with differing runtime representations - - - - - 59cf287d by Sylvain Henry at 2021-04-29T17:26:43-04:00 Refactor divInt# to make it branchless (#18067, #19636) - - - - - 8d069477 by Sylvain Henry at 2021-04-29T17:26:43-04:00 Refactor modInt# to make it branchless - - - - - e50d0675 by Sylvain Henry at 2021-04-29T17:26:43-04:00 Allow divInt#/modInt# to inline (#18067) - - - - - c308c9af by Sylvain Henry at 2021-04-29T17:26:43-04:00 Make divModInt# branchless - - - - - 7bb3443a by Sylvain Henry at 2021-04-29T17:26:43-04:00 Fix inlining of division wrappers - - - - - 7d18e1ba by Alfredo Di Napoli at 2021-04-29T17:27:19-04:00 Add GhcMessage and ancillary types This commit adds GhcMessage and ancillary (PsMessage, TcRnMessage, ..) types. These types will be expanded to represent more errors generated by different subsystems within GHC. Right now, they are underused, but more will come in the glorious future. See https://gitlab.haskell.org/ghc/ghc/-/wikis/Errors-as-(structured)-values for a design overview. Along the way, lots of other things had to happen: * Adds Semigroup and Monoid instance for Bag * Fixes #19746 by parsing OPTIONS_GHC pragmas into Located Strings. See GHC.Parser.Header.toArgs (moved from GHC.Utils.Misc, where it didn't belong anyway). * Addresses (but does not completely fix) #19709, now reporting desugarer warnings and errors appropriately for TH splices. Not done: reporting type-checker warnings for TH splices. * Some small refactoring around Safe Haskell inference, in order to keep separate classes of messages separate. * Some small refactoring around initDsTc, in order to keep separate classes of messages separate. * Separate out the generation of messages (that is, the construction of the text block) from the wrapping of messages (that is, assigning a SrcSpan). This is more modular than the previous design, which mixed the two. Close #19746. This was a collaborative effort by Alfredo di Napoli and Richard Eisenberg, with a key assist on #19746 by Iavor Diatchki. Metric Increase: MultiLayerModules - - - - - 5981ac7d by Ryan Scott at 2021-04-29T17:27:54-04:00 Redesign withDict (formerly magicDict) This gives a more precise type signature to `magicDict` as proposed in #16646. In addition, this replaces the constant-folding rule for `magicDict` in `GHC.Core.Opt.ConstantFold` with a special case in the desugarer in `GHC.HsToCore.Expr.dsHsWrapped`. I have also renamed `magicDict` to `withDict` in light of the discussion in https://mail.haskell.org/pipermail/ghc-devs/2021-April/019833.html. All of this has the following benefits: * `withDict` is now more type safe than before. Moreover, if a user applies `withDict` at an incorrect type, the special-casing in `dsHsWrapped` will now throw an error message indicating what the user did incorrectly. * `withDict` can now work with classes that have multiple type arguments, such as `Typeable @k a`. This means that `Data.Typeable.Internal.withTypeable` can now be implemented in terms of `withDict`. * Since the special-casing for `withDict` no longer needs to match on the structure of the expression passed as an argument to `withDict`, it no longer cares about the presence or absence of `Tick`s. In effect, this obsoletes the fix for #19667. The new `T16646` test case demonstrates the new version of `withDict` in action, both in terms of `base` functions defined in terms of `withDict` as well as in terms of functions from the `reflection` and `singletons` libraries. The `T16646Fail` test case demonstrates the error message that GHC throws when `withDict` is applied incorrectly. This fixes #16646. By adding more tests for `withDict`, this also fixes #19673 as a side effect. - - - - - 51470000 by Ryan Scott at 2021-04-29T17:28:30-04:00 Expand synonyms in mkCastTy when necessary Doing so is important to maintain invariants (EQ3) and (EQ4) from `Note [Respecting definitional equality]` in `GHC.Core.TyCo.Rep`. For the details, see the new `Note [Using coreView in mk_cast_ty]`. Fixes #19742. - - - - - c2541c49 by Ryan Scott at 2021-04-29T17:29:05-04:00 Propagate free variables in extract_lctxt correctly This fixes an oversight in the implementation of `extract_lctxt` which was introduced in commit ce85cffc. Fixes #19759. - - - - - 1d03d8be by Sylvain Henry at 2021-04-29T17:29:44-04:00 Replace (ptext .. sLit) with `text` 1. `text` is as efficient as `ptext . sLit` thanks to the rewrite rules 2. `text` is visually nicer than `ptext . sLit` 3. `ptext . sLit` encourages using one `ptext` for several `sLit` as in: ptext $ case xy of ... -> sLit ... ... -> sLit ... which may allocate SDoc's TextBeside constructors at runtime instead of sharing them into CAFs. - - - - - 2d2985a7 by Adam Sandberg Ericsson at 2021-04-29T17:30:20-04:00 rts: export allocateWrite, freeWrite and markExec #19763 - - - - - c0c0b4e0 by Viktor Dukhovni at 2021-04-30T23:21:34-04:00 Tighten scope of non-POSIX visibility macros The __BSD_VISIBLE and _DARWIN_C_SOURCE macros expose non-POSIX prototypes in system header files. We should scope these to just the ".c" modules that actually need them, and avoid defining them in header files used in other C modules. - - - - - c7ca3619 by Sylvain Henry at 2021-04-30T23:22:13-04:00 Interpreter: replace DynFlags with EvalOpts/BCOOpts - - - - - 491266ee by Sylvain Henry at 2021-04-30T23:22:13-04:00 Make GHC.Runtime.Interpreter independent of GHC.Driver - - - - - 48c2c2af by Sylvain Henry at 2021-04-30T23:22:13-04:00 Fix genprimopcode warning - - - - - 6623790d by Sylvain Henry at 2021-04-30T23:22:13-04:00 Hadrian: build check-* with -Wall/-Werror Otherwise CI fails only with make build system. - - - - - 460afbe6 by Ryan Scott at 2021-04-30T23:22:48-04:00 Bring tcTyConScopedTyVars into scope in tcClassDecl2 It is possible that the type variables bound by a class header will map to something different in the typechecker in the presence of `StandaloneKindSignatures`. `tcClassDecl2` was not aware of this, however, leading to #19738. To fix it, in `tcTyClDecls` we map each class `TcTyCon` to its `tcTyConScopedTyVars` as a `ClassScopedTVEnv`. We then plumb that `ClassScopedTVEnv` to `tcClassDecl2` where it can be used. Fixes #19738. - - - - - e61d2d47 by Sylvain Henry at 2021-04-30T23:23:26-04:00 Make sized division primops ok-for-spec (#19026) - - - - - 1b9df111 by Harry Garrood harry at garrood.me at 2021-05-03T19:48:21-04:00 Add test case for #8144 Fixes #8144 - - - - - 4512ad2d by John Ericson at 2021-05-03T19:48:56-04:00 Use fix-sized bit-fiddling primops for fixed size boxed types Like !5572, this is switching over a portion of the primops which seems safe to use. - - - - - 8d6b2525 by Sylvain Henry at 2021-05-03T19:48:56-04:00 Move shift ops out of GHC.Base With a quick flavour I get: before T12545(normal) ghc/alloc 8628109152 after T12545(normal) ghc/alloc 8559741088 - - - - - 3a2f2475 by bit at 2021-05-03T19:49:32-04:00 Update documentation of 'Weak' - - - - - 4e546834 by Tamar Christina at 2021-05-03T19:50:10-04:00 pe: enable code unloading for Windows - - - - - 5126a07e by Philipp Dargel at 2021-05-03T19:50:46-04:00 Remove duplicate modules in GHCi %s prompt fixes #19757 - - - - - 0680e9a5 by Hécate Moonlight at 2021-05-03T19:51:22-04:00 Disable HLint colours closes #19776 - - - - - 7f5ee719 by iori tsu at 2021-05-03T19:51:58-04:00 visually align expected and actual modules name before: > /home/matt/Projects/persistent/persistent/Database/Persist/ImplicitIdDef.hs:1:8: error: > File name does not match module name: > Saw: ‘A.B.Module’ > Expected: ‘A.B.Motule’ > | > 1 | module A.B.Motule > | ^^^^^^^^^^> after: > /home/matt/Projects/persistent/persistent/Database/Persist/ImplicitIdDef.hs:1:8: error: > File name does not match module name: > Saw: ‘A.B.Module’ > Expected: ‘A.B.Motule’ > | > 1 | module A.B.Motule > | ^^^^^^^^^^> - - - - - 24a9b170 by sheaf at 2021-05-03T19:52:34-04:00 Improve hs-boot binds error (#19781) - - - - - 39020600 by Roland Senn at 2021-05-04T16:00:13-04:00 Tweak function `quantifyType` to fix #12449 In function `compiler/GHC/Runtime/Heap/Inspect.hs:quantifyType` replace `tcSplitForAllInvisTyVars` by `tcSplitNestedSigmaTys`. This will properly split off the nested foralls in examples like `:print fmap`. Do not remove the `forall`s from the `snd` part of the tuple returned by `quantifyType`. It's not necessary and the reason for the bug in #12449. Some code simplifications at the calling sites of `quantifyTypes`. - - - - - 6acadb79 by Simon Peyton Jones at 2021-05-04T16:00:48-04:00 Persist CorePrepProv into IfaceUnivCoProv CorePrepProv is only created in CorePrep, so I thought it wouldn't be needed in IfaceUnivCoProv. But actually IfaceSyn is used during pretty-printing, and we can certainly pretty-print things after CorePrep as #19768 showed. So the simplest thing is to represent CorePrepProv in IfaceSyn. To improve what Lint can do I also added a boolean to CorePrepProv, to record whether it is homogeneously kinded or not. It is introduced in two distinct ways (see Note [Unsafe coercions] in GHC.CoreToStg.Prep), one of which may be hetero-kinded (e.g. Int ~ Int#) beause it is casting a divergent expression; but the other is not. The boolean keeps track. - - - - - 7ffbdc3f by Ben Gamari at 2021-05-05T05:42:38-04:00 Break up aclocal.m4 - - - - - 34452fbd by Ben Gamari at 2021-05-05T05:42:38-04:00 configure: Move pthreads checks to macro - - - - - 0de2012c by Ben Gamari at 2021-05-05T05:42:38-04:00 configure: Move libnuma check to macro - - - - - 958c6fbd by Ben Gamari at 2021-05-05T05:42:38-04:00 configure: Move libdw search logic to macro - - - - - 101d25fc by Alfredo Di Napoli at 2021-05-05T05:43:14-04:00 Add some DriverMessage type constructors This commit expands the DriverMessage type with new type constructors, making the number of diagnostics GHC can emit richer. In particular: * Add DriverMissingHomeModules message * Add DriverUnusedPackage message * Add DriverUnnecessarySourceImports message This commit adds the `DriverUnnecessarySourceImports` message and fixes a small bug in its reporting: inside `warnUnnecessarySourceImports` we were checking for `Opt_WarnUnusedSourceImports` to be set, but we were emitting the diagnostic with `WarningWithoutFlag`. This also adjusts the T10637 test to reflect that. * Add DriverDuplicatedModuleDeclaration message * Add DriverModuleNotFound message * Add DriverFileModuleNameMismatch message * Add DriverUnexpectedSignature message * Add DriverFileNotFound message * Add DriverStaticPointersNotSupported message * Add DriverBackpackModuleNotFound message - - - - - e9617fba by Matthew Pickering at 2021-05-05T05:43:49-04:00 test driver: Make sure RESIDENCY_OPTS is passed for 'all' perf tests Fixes #19731 ------------------------- Metric Decrease: T11545 Metric Increase: T12545 T15304 ------------------------- - - - - - f464e477 by Jaro Reinders at 2021-05-05T05:44:26-04:00 More specific error messages for annotations (fixes #19740) - - - - - 3280eb22 by Luite Stegeman at 2021-05-05T05:45:03-04:00 support LiftedRep and UnliftedRep in GHCi FFI fixes #19733 - - - - - 049c3a83 by Hécate Moonlight at 2021-05-05T05:45:39-04:00 Add an .editorconfig file closes #19793 - - - - - a5e9e5b6 by Ben Gamari at 2021-05-06T02:30:18-04:00 Re-introduce Note [keepAlive# magic] Somewhere in the course of forward- and back-porting the keepAlive# branch the Note which described the mechanism was dropped. Reintroduce it. Closes #19712. - - - - - c4f4193a by John Ericson at 2021-05-06T02:30:54-04:00 Use fix-sized arithmetic primops for fixed size boxed types We think the compiler is ready, so we can do this for all over the 8-, 16-, and 32-bit boxed types. We are holding off on doing all the primops at once so things are easier to investigate. Metric Decrease: T12545 - - - - - 418295ea by Sasha Bogicevic at 2021-05-06T02:31:31-04:00 19486 Nearly all uses of `uniqCompareFS` are dubious and lack a non-determinism justification - - - - - 1635d5c2 by Alan Zimmerman at 2021-05-06T02:32:06-04:00 EPA: properly capture semicolons between Matches in a FunBind For the source module MatchSemis where { a 0 = 1; a _ = 2; } Make sure that the AddSemiAnn entries for the two trailing semicolons are attached to the component Match elements. Closes #19784 - - - - - e5778365 by PHO at 2021-05-06T02:32:44-04:00 rts/posix/GetTime.c: Use Solaris-specific gethrvtime(3) on OpenSolaris derivatives The constant CLOCK_THREAD_CPUTIME_ID is defined in a system header but it isn't acutally usable. clock_gettime(2) always returns EINVAL. - - - - - 87d8c008 by Ben Gamari at 2021-05-06T12:44:06-04:00 Bump binary submodule Fixes #19631. - - - - - 0281dae8 by Aaron Allen at 2021-05-06T12:44:43-04:00 Disallow -XDerivingVia when -XSafe is on (#19786) Since `GeneralizedNewtypeDeriving` is considered unsafe, `DerivingVia` should be as well. - - - - - 30f6923a by Ben Gamari at 2021-05-06T12:45:19-04:00 hadrian: Don't depend upon bash from PATH Previously Hadrian depended implicitly upon whatever `bash` it found in `PATH`, offerring no way for the user to override. Fix this by detecting `sh` in `configure` and passing the result to Hadrian. Fixes #19797. - - - - - c5454dc7 by Moritz Angermann at 2021-05-07T09:17:22+08:00 [ci] Add support for building on aarch64-darwin This will fail for now. But allows us to add aarch64-darwin machines to CI. (cherry picked from commit a7d22795ed118abfe64f4fc55d96d8561007ce1e) - - - - - 41b0c288 by Moritz Angermann at 2021-05-07T09:17:22+08:00 [testlib/driver] denoise this prevents the testlib/driver to be overly noisy, and will also kill some noise produiced by the aarch64-darwin cc (for now). Fixing sysctl, will allow us to run the test's properly in a nix-shell on aarch64-darwin (cherry picked from commit 5109e87e13ab45d799db2013535f54ca35f1f4dc) - - - - - bb78df78 by Moritz Angermann at 2021-05-07T09:17:22+08:00 [ci] default value for CONFIGURE_ARGS (cherry picked from commit 307d34945b7d932156e533736c91097493e6181b) - - - - - 5f5b02c2 by Moritz Angermann at 2021-05-07T09:17:22+08:00 [ci] Default value for MAKE_ARGS We don't pass MAKE_ARGS for windows builds, so this should unbreak them. (cherry picked from commit 16c13d5acfdc8053f7de9e908cc9d845e9bd34bb) - - - - - 79019dd6 by Moritz Angermann at 2021-05-07T09:17:23+08:00 [testsuite/darwin] fix conc059 This resolves the following: Compile failed (exit code 1) errors were: conc059_c.c:27:5: error: error: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Werror,-Wimplicit-function-declaration] exit(0); ^ conc059_c.c:27:5: error: note: include the header <stdlib.h> or explicitly provide a declaration for 'exit' (cherry picked from commit 5a6c36ecb41fccc07c1b01fe0f330cd38c2a0c76) - - - - - 8a36ebfa by Moritz Angermann at 2021-05-07T09:17:23+08:00 [Aarch64] No div-by-zero; disable test. (cherry picked from commit 3592d1104c47b006fd9f4127d93916f477a6e010) - - - - - 10b5dc88 by Moritz Angermann at 2021-05-07T09:19:47+08:00 [Darwin] mark stdc++ tests as broken There is no libstdc++, only libc++ (cherry picked from commit 57671071adeaf0b45e86bb0ee050e007e3b161fb) - - - - - 035f4bb1 by Moritz Angermann at 2021-05-07T09:19:47+08:00 [testsuite] filter out superfluous dylib warnings (cherry picked from commit 33c4d497545559a38bd8d1caf6c94e5e2a77647b) - - - - - 3f09c6f8 by Moritz Angermann at 2021-05-07T09:19:47+08:00 [ci/nix-shell] Add Foundation and Security (cherry picked from commit 4bea83afec009dfd3c6313cac4610d00ba1f9a3d) - - - - - 65440597 by Moritz Angermann at 2021-05-07T09:19:47+08:00 [testsuite/json2] Fix failure with LLVM backends -Wno-unsupported-llvm-version should suppress the LLVM version missmatch warning that messes up the output. (cherry picked from commit 63455300625fc12b2aafc3e339eb307510a6e8bd) - - - - - 582fc583 by Moritz Angermann at 2021-05-07T09:19:47+08:00 [ci/nix-shell] [Darwin] Stop the ld warnings about libiconv. (cherry picked from commit c3944bc89d062a4850946904133c7a1464d59012) - - - - - 7df44e43 by Moritz Angermann at 2021-05-07T09:19:48+08:00 [testsuite] static001 is not broken anymore. (cherry picked from commit b821fcc7142edff69aa4c47dc1a5bd30b13c1ceb) - - - - - 49839322 by Moritz Angermann at 2021-05-07T09:19:48+08:00 [testsuite/arm64] fix section_alignment (cherry picked from commit f7062e1b0c91e8aa78e245a3dab9571206fce16d) - - - - - ccea6117 by Moritz Angermann at 2021-05-07T09:19:48+08:00 [ci/nix-shell] uniquify NIX_LDFLAGS{_FOR_TARGET} (cherry picked from commit 07b1af0362beaaf221cbee7b17bbe0a5606fd87d) - - - - - cceb461a by Moritz Angermann at 2021-05-07T09:19:48+08:00 [darwin] stop the DYLD_LIBRARY_PATH madness this causes *significant* slowdown on macOS as the linker ends up looking through all the paths. Slowdown can be as bad as 100% or more. (cherry picked from commit 820b0766984d42c06c977a6c32da75c429106f7f) - - - - - a664a2ad by Moritz Angermann at 2021-05-07T09:19:48+08:00 [ci] Default values for CI_COMMIT_BRANCH, CI_PROJECT_PATH - - - - - 8e0f48bd by Simon Peyton Jones at 2021-05-07T09:43:57-04:00 Allow visible type application for levity-poly data cons This patch was driven by #18481, to allow visible type application for levity-polymorphic newtypes. As so often, it started simple but grew: * Significant refactor: I removed HsConLikeOut from the client-independent Language.Haskell.Syntax.Expr, and put it where it belongs, as a new constructor `ConLikeTc` in the GHC-specific extension data type for expressions, `GHC.Hs.Expr.XXExprGhcTc`. That changed touched a lot of files in a very superficial way. * Note [Typechecking data constructors] explains the main payload. The eta-expansion part is no longer done by the typechecker, but instead deferred to the desugarer, via `ConLikeTc` * A little side benefit is that I was able to restore VTA for data types with a "stupid theta": #19775. Not very important, but the code in GHC.Tc.Gen.Head.tcInferDataCon is is much, much more elegant now. * I had to refactor the levity-polymorphism checking code in GHC.HsToCore.Expr, see Note [Checking for levity-polymorphic functions] Note [Checking levity-polymorphic data constructors] - - - - - 740103c5 by PHO at 2021-05-07T20:06:43-04:00 rts/posix/OSThreads.c: Implement getNumberOfProcessors() for NetBSD - - - - - 39be3283 by PHO at 2021-05-07T20:06:43-04:00 rts: Correctly call pthread_setname_np() on NetBSD NetBSD supports pthread_setname_np() but it expects a printf-style format string and a string argument. Also use pthread for itimer on this platform. - - - - - a32eb0f3 by Simon Peyton Jones at 2021-05-07T20:07:19-04:00 Fix newtype eta-reduction The eta-reduction we do for newype axioms was generating an inhomogeneous axiom: see #19739. This patch fixes it in a simple way; see GHC.Tc.TyCl.Build Note [Newtype eta and homogeneous axioms] - - - - - ad5a3aeb by Alan Zimmerman at 2021-05-08T11:19:26+01:00 EPA: update some comments in Annotations. Follow-up from !2418, see #19579 - - - - - 736d47ff by Alan Zimmerman at 2021-05-09T18:13:40-04:00 EPA: properly capture leading semicolons in statement lists For the fragment blah = do { ; print "a" ; print "b" } capture the leading semicolon before 'print "a"' in 'al_rest' in AnnList instead of in 'al_trailing'. Closes #19798 - - - - - c4a85e3b by Andreas Klebinger at 2021-05-11T05:34:52-04:00 Expand Note [Data con representation]. Not perfect. But I consider this to be a documentation fix for #19789. - - - - - 087ac4eb by Simon Peyton Jones at 2021-05-11T05:35:27-04:00 Minor refactoring in WorkWrap This patch just does the tidying up from #19805. No change in behaviour. - - - - - 32367cac by Alan Zimmerman at 2021-05-11T05:36:02-04:00 EPA: Use custom AnnsIf structure for HsIf and HsCmdIf This clearly identifies the presence and location of optional semicolons in an if statement. Closes #19813 - - - - - 09918343 by Andreas Klebinger at 2021-05-11T16:58:38-04:00 Don't warn about ClassOp bindings not specialising. Fixes #19586 - - - - - 5daf1aa9 by Andreas Klebinger at 2021-05-11T16:59:17-04:00 Document unfolding treatment of simplLamBndr. Fixes #19817 - - - - - c7717949 by Simon Peyton Jones at 2021-05-11T23:00:27-04:00 Fix strictness and arity info in SpecConstr In GHC.Core.Opt.SpecConstr.spec_one we were giving join-points an incorrect join-arity -- this was fallout from commit c71b220491a6ae46924cc5011b80182bcc773a58 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Thu Apr 8 23:36:24 2021 +0100 Improvements in SpecConstr * Allow under-saturated calls to specialise See Note [SpecConstr call patterns] This just allows a bit more specialisation to take place. and showed up in #19780. I refactored the code to make the new function calcSpecInfo which treats join points separately. In doing this I discovered two other small bugs: * In the Var case of argToPat we were treating UnkOcc as uninteresting, but (by omission) NoOcc as interesting. As a result we were generating SpecConstr specialisations for functions with unused arguments. But the absence anlyser does that much better; doing it here just generates more code. Easily fixed. * The lifted/unlifted test in GHC.Core.Opt.WorkWrap.Utils.mkWorkerArgs was back to front (#19794). Easily fixed. * In the same function, mkWorkerArgs, we were adding an extra argument nullary join points, which isn't necessary. I added a test for this. That in turn meant I had to remove an ASSERT in CoreToStg.mkStgRhs for nullary join points, which was always bogus but now trips; I added a comment to explain. - - - - - c3868451 by Alan Zimmerman at 2021-05-11T23:01:03-04:00 EPA: record annotations for braces in LetStmt Closes #19814 - - - - - 6967088d by Ben Gamari at 2021-05-11T23:01:38-04:00 base: Update Unicode data to 13.0.0 (cherry picked from commit d22e087f7bf74341c4468f11b4eb0273033ca931) - - - - - 673ff667 by Matthew Pickering at 2021-05-11T23:02:14-04:00 hadrian: Don't always links against libffi The RTS flag `ffi` is set to either True or False depending on whether we want to link against `libffi`, therefore in order to work out whether to add the build tree to the arguments we check whether `ffi` is in the extraLibs or not before adding the argument. Fixes #16022 - - - - - d22e8d89 by Matthew Pickering at 2021-05-11T23:02:50-04:00 rts: Remove trailing whitespace from Adjustor.c - - - - - f0b73ddd by Sylvain Henry at 2021-05-11T23:03:28-04:00 Hadrian: add comment to avoid surprises - - - - - 55223780 by Andreas Klebinger at 2021-05-12T14:49:23-04:00 W/W: Always zap useless idInfos. tryWW used to always returns an Id with a zapped: * DmdEnv * Used Once info except in the case where the ID was guaranteed to be inlined. We now also zap the info in that case. Fixes #19818. - - - - - 541665b7 by Matthew Pickering at 2021-05-12T14:49:58-04:00 hadrian: Fix dynamic+debug flag combination for check-ppr executable - - - - - a7473e03 by Peter Trommler at 2021-05-12T14:50:33-04:00 Hadrian: Enable SMP on powerpc64{le} Fixes #19825 - - - - - f78c25da by Sylvain Henry at 2021-05-12T21:41:43-04:00 Move GlobalVar macros into GHC.Utils.GlobalVars That's the only place where they are used and they shouldn't be used elsewhere. - - - - - da56ed41 by Sylvain Henry at 2021-05-12T21:41:43-04:00 Ensure assert from Control.Exception isn't used - - - - - bfabf94f by Sylvain Henry at 2021-05-12T21:41:43-04:00 Replace CPP assertions with Haskell functions There is no reason to use CPP. __LINE__ and __FILE__ macros are now better replaced with GHC's CallStack. As a bonus, assert error messages now contain more information (function name, column). Here is the mapping table (HasCallStack omitted): * ASSERT: assert :: Bool -> a -> a * MASSERT: massert :: Bool -> m () * ASSERTM: assertM :: m Bool -> m () * ASSERT2: assertPpr :: Bool -> SDoc -> a -> a * MASSERT2: massertPpr :: Bool -> SDoc -> m () * ASSERTM2: assertPprM :: m Bool -> SDoc -> m () - - - - - 0ef11907 by Sylvain Henry at 2021-05-12T21:41:44-04:00 Fully remove HsVersions.h Replace uses of WARN macro with calls to: warnPprTrace :: Bool -> SDoc -> a -> a Remove the now unused HsVersions.h Bump haddock submodule - - - - - 67a5a91e by Sylvain Henry at 2021-05-12T21:41:44-04:00 Remove useless {-# LANGUAGE CPP #-} pragmas - - - - - c34f4c0c by Alan Zimmerman at 2021-05-12T21:42:21-04:00 EPA: Fix incorrect SrcSpan for FamDecl The SrcSpan for a type family declaration did not include the family equations. Closes #19821 - - - - - e0ded198 by Matthew Pickering at 2021-05-12T21:42:57-04:00 ci: Fix unbound CI_MERGE_REQUEST_SOURCE_BRANCH_NAME variable Fixes #19831 - - - - - c6de5805 by John Ericson at 2021-05-13T16:44:23-04:00 Use fix-sized order primops for fixed size boxed types Progress towards #19026 - - - - - fc9546ca by Sylvain Henry at 2021-05-13T16:45:03-04:00 genprimopcode: fix bootstrap errors * Fix for unqualified Data.List import * Fix monad instance - - - - - 60f088b3 by Matthew Pickering at 2021-05-19T09:10:16+01:00 CI: Disable darwin builds They are taking over 4 hours to complete which is stalling the rest of the merge pipeline. - - - - - baa969c3 by Koz Ross at 2021-05-19T23:31:51-04:00 Implement bitwise infix ops - - - - - c8564c63 by Alfredo Di Napoli at 2021-05-19T23:32:27-04:00 Add some TcRn diagnostic messages This commit converts some TcRn diagnostic into proper structured errors. Ported by this commit: * Add TcRnImplicitLift This commit adds the TcRnImplicitLift diagnostic message and a prototype API to be able to log messages which requires additional err info. * Add TcRnUnusedPatternBinds * Add TcRnDodgyExports * Add TcRnDodgyImports message * Add TcRnMissingImportList - - - - - 38faeea1 by Matthew Pickering at 2021-05-19T23:33:02-04:00 Remove transitive information about modules and packages from interface files This commit modifies interface files so that *only* direct information about modules and packages is stored in the interface file. * Only direct module and direct package dependencies are stored in the interface files. * Trusted packages are now stored separately as they need to be checked transitively. * hs-boot files below the compiled module in the home module are stored so that eps_is_boot can be calculated in one-shot mode without loading all interface files in the home package. * The transitive closure of signatures is stored separately This is important for two reasons * Less recompilation is needed, as motivated by #16885, a lot of redundant compilation was triggered when adding new imports deep in the module tree as all the parent interface files had to be redundantly updated. * Checking an interface file is cheaper because you don't have to perform a transitive traversal to check the dependencies are up-to-date. In the code, places where we would have used the transitive closure, we instead compute the necessary transitive closure. The closure is not computed very often, was already happening in checkDependencies, and was already happening in getLinkDeps. Fixes #16885 ------------------------- Metric Decrease: MultiLayerModules T13701 T13719 ------------------------- - - - - - 29d104c6 by nineonine at 2021-05-19T23:33:40-04:00 Implement :info for record pattern synonyms (#19462) - - - - - d45e3cda by Matthew Pickering at 2021-05-19T23:34:15-04:00 hadrian: Make copyFileLinked a bit more robust Previously it only worked if the two files you were trying to symlink were already in the same directory. - - - - - 176b1305 by Matthew Pickering at 2021-05-19T23:34:15-04:00 hadrian: Build check-ppr and check-exact using normal hadrian rules when in-tree Fixes #19606 #19607 - - - - - 3c04e7ac by Andreas Klebinger at 2021-05-19T23:34:49-04:00 Fix LitRubbish being applied to values. This fixes #19824 - - - - - 32725617 by Matthew Pickering at 2021-05-19T23:35:24-04:00 Tidy: Ignore rules (more) when -fomit-interface-pragmas is on Before this commit, the RHS of a rule would expose additional definitions, despite the fact that the rule wouldn't get exposed so it wouldn't be possible to ever use these definitions. The net-result is slightly less recompilation when specialisation introduces rules. Related to #19836 - - - - - 10ae305e by Alan Zimmerman at 2021-05-19T23:35:59-04:00 EPA: Remove duplicate annotations from HsDataDefn They are repeated in the surrounding DataDecl and FamEqn. Updates haddock submodule Closes #19834 - - - - - 8e7f02ea by Richard Eisenberg at 2021-05-19T23:36:35-04:00 Point posters to ghc-proposals - - - - - 6844ead4 by Matthew Pickering at 2021-05-19T23:37:09-04:00 testsuite: Don't copy .hi-boot and .o-boot files into temp dir - - - - - e87b8e10 by Sebastian Graf at 2021-05-19T23:37:44-04:00 CPR: Detect constructed products in `runRW#` apps (#19822) In #19822, we realised that the Simplifier's new habit of floating cases into `runRW#` continuations inhibits CPR analysis from giving key functions of `text` the CPR property, such as `singleton`. This patch fixes that by anticipating part of !5667 (Nested CPR) to give `runRW#` the proper CPR transformer it now deserves: Namely, `runRW# (\s -> e)` should have the CPR property iff `e` has it. The details are in `Note [Simplification of runRW#]` in GHC.CoreToStg.Prep. The output of T18086 changed a bit: `panic` (which calls `runRW#`) now has `botCpr`. As outlined in Note [Bottom CPR iff Dead-Ending Divergence], that's OK. Fixes #19822. Metric Decrease: T9872d - - - - - d3ef2dc2 by Baldur Blöndal at 2021-05-19T23:38:20-04:00 Add pattern TypeRep (#19691), exported by Type.Reflection. - - - - - f192e623 by Sylvain Henry at 2021-05-19T23:38:58-04:00 Cmm: fix sinking after suspendThread Suppose a safe call: myCall(x,y,z) It is lowered into three unsafe calls in Cmm: r = suspendThread(...); myCall(x,y,z); resumeThread(r); Consider the following situation for myCall arguments: x = Sp[..] -- stack y = Hp[..] -- heap z = R1 -- global register r = suspendThread(...); myCall(x,y,z); resumeThread(r); The sink pass assumes that unsafe calls clobber memory (heap and stack), hence x and y assignments are not sunk after `suspendThread`. The sink pass also correctly handles global register clobbering for all unsafe calls, except `suspendThread`! `suspendThread` is special because it releases the capability the thread is running on. Hence the sink pass must also take into account global registers that are mapped into memory (in the capability). In the example above, we could get: r = suspendThread(...); z = R1 myCall(x,y,z); resumeThread(r); But this transformation isn't valid if R1 is (BaseReg->rR1) as BaseReg is invalid between suspendThread and resumeThread. This caused argument corruption at least with the C backend ("unregisterised") in #19237. Fix #19237 - - - - - df4a0a53 by Sylvain Henry at 2021-05-19T23:39:37-04:00 Bignum: bump to version 1.1 (#19846) - - - - - d48b7e5c by Shayne Fletcher at 2021-05-19T23:40:12-04:00 Changes to HsRecField' - - - - - 441fdd6c by Adam Sandberg Ericsson at 2021-05-19T23:40:47-04:00 driver: check if clang is the assembler when passing clang specific arguments (#19827) Previously we assumed that the assembler was the same as the c compiler, but we allow setting them to different programs with -pgmc and -pgma. - - - - - 6a577cf0 by Peter Trommler at 2021-05-19T23:41:22-04:00 PPC NCG: Fix unsigned compare with 16-bit constants Fixes #19852 and #19609 - - - - - c4099b09 by Matthew Pickering at 2021-05-19T23:41:57-04:00 Make setBndrsDemandInfo work with only type variables Fixes #19849 Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - 4b5de954 by Matthew Pickering at 2021-05-19T23:42:32-04:00 constant folding: Make shiftRule for Word8/16/32# types return correct type Fixes #19851 - - - - - 82b097b3 by Sylvain Henry at 2021-05-19T23:43:09-04:00 Remove wired-in names hs-boot check bypass (#19855) The check bypass is no longer necessary and the check would have avoided #19638. - - - - - 939a56e7 by Baldur Blöndal at 2021-05-19T23:43:46-04:00 Added new regresion test for #18036 from ticket #19865. - - - - - 43139064 by Ben Gamari at 2021-05-20T11:36:55-04:00 gitlab-ci: Add Alpine job linking against gmp integer backend As requested by Michael Snoyman. - - - - - 7c066734 by Roland Senn at 2021-05-20T11:37:32-04:00 Use pprSigmaType to print GHCi debugger Suspension Terms (Fix #19355) In the GHCi debugger use the function `pprSigmaType` to print out Suspension Terms. The function `pprSigmaType` respect the flag `-f(no-)print-explicit-foralls` and so it fixes #19355. Switch back output of existing tests to default mode (no explicit foralls). - - - - - aac87bd3 by Alfredo Di Napoli at 2021-05-20T18:08:37-04:00 Extensible Hints for diagnostic messages This commit extends the GHC diagnostic hierarchy with a `GhcHint` type, modelling helpful suggestions emitted by GHC which can be used to deal with a particular warning or error. As a direct consequence of this, the `Diagnostic` typeclass has been extended with a `diagnosticHints` method, which returns a `[GhcHint]`. This means that now we can clearly separate out the printing of the diagnostic message with the suggested fixes. This is done by extending the `printMessages` function in `GHC.Driver.Errors`. On top of that, the old `PsHint` type has been superseded by the new `GhcHint` type, which de-duplicates some hints in favour of a general `SuggestExtension` constructor that takes a `GHC.LanguageExtensions.Extension`. - - - - - 649d63db by Divam Narula at 2021-05-20T18:09:13-04:00 Add tests for code generation options specified via OPTIONS_GHC in multi module compilation - - - - - 5dcb8619 by Matthías Páll Gissurarson at 2021-05-20T18:09:50-04:00 Add exports to GHC.Tc.Errors.Hole (fixes #19864) - - - - - 703c0c3c by Sylvain Henry at 2021-05-20T18:10:31-04:00 Bump libffi submodule to libffi-3.3 (#16940) - - - - - d9eb8bbf by Jakob Brünker at 2021-05-21T06:22:47-04:00 Only suggest names that make sense (#19843) * Don't show suggestions for similar variables when a data constructor in a pattern is not in scope. * Only suggest record fields when a record field for record creation or updating is not in scope. * Suggest similar record fields when a record field is not in scope with -XOverloadedRecordDot. * Show suggestions for data constructors if a type constructor or type is not in scope, but only if -XDataKinds is enabled. Fixes #19843. - - - - - ec10cc97 by Matthew Pickering at 2021-05-21T06:23:26-04:00 hadrian: Reduce verbosity on failed testsuite run When the testsuite failed before it would print a big exception which gave you the very long command line which was used to invoke the testsuite. By capturing the exit code and rethrowing the exception, the error is must less verbose: ``` Error when running Shake build system: at want, called at src/Main.hs:104:30 in main:Main * Depends on: test * Raised the exception: user error (tests failed) ``` - - - - - f5f74167 by Matthew Pickering at 2021-05-21T06:24:02-04:00 Only run armv7-linux-deb10 build nightly - - - - - 6eed426b by Sylvain Henry at 2021-05-21T06:24:44-04:00 SysTools: make file copy more efficient - - - - - 0da85d41 by Alan Zimmerman at 2021-05-21T15:05:44-04:00 EPA: Fix explicit specificity and unicode linear arrow annotations Closes #19839 Closes #19840 - - - - - 5ab174e4 by Alan Zimmerman at 2021-05-21T15:06:20-04:00 Remove Maybe from Context in HsQualTy Updates haddock submodule Closes #19845 - - - - - b4d240d3 by Matthew Pickering at 2021-05-22T00:07:42-04:00 hadrian: Reorganise modules so KV parser can be used to define transformers - - - - - 8c871c07 by Matthew Pickering at 2021-05-22T00:07:42-04:00 hadrian: Add omit_pragmas transformer This transformer builds stage2 GHC with -fomit-interface-pragmas which can greatly reduce the amount of rebuilding but still allows most the tests to pass. - - - - - c6806912 by Matthew Pickering at 2021-05-22T00:08:18-04:00 Remove ANN pragmas in check-ppr and check-exact This fixes the `devel2+werror` build combo as stage1 does not have TH enabled. ``` utils/check-exact/Preprocess.hs:51:1: error: [-Werror] Ignoring ANN annotations, because this is a stage-1 compiler without -fexternal-interpreter or doesn't support GHCi | 51 | {-# ANN module ("HLint: ignore Reduce duplication" :: String) #-} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` - - - - - e2d4f241 by PHO at 2021-05-22T00:08:55-04:00 Support NetBSD/aarch64 via LLVM codegen Only adding "aarch64-unknown-netbsd" to gen-data-layout.sh was sufficient to get it working. No other changes were strictly required. - - - - - ef4d2999 by nineonine at 2021-05-22T00:09:32-04:00 Add regression test for #19287 - - - - - 0b1eed74 by Shayne Fletcher at 2021-05-23T08:02:58+10:00 Change representation of field selector occurences - Change the names of the fields in in `data FieldOcc` - Renames `HsRecFld` to `HsRecSel` - Replace `AmbiguousFieldOcc p` in `HsRecSel` with `FieldOcc p` - Contains a haddock submodule update The primary motivation of this change is to remove `AmbiguousFieldOcc`. This is one of a suite of changes improving how record syntax (most notably record update syntax) is represented in the AST. - - - - - 406cd90b by Alan Zimmerman at 2021-05-23T02:07:36-04:00 EPA: AnnAt missing for type application in patterns Ensure that the exact print annotations accurately record the `@` for code like tyApp :: Con k a -> Proxy a tyApp (Con @kx @ax (x :: Proxy ax)) = x :: Proxy (ax :: kx) Closes #19850 - - - - - 82c6a939 by Vladislav Zavialov at 2021-05-23T18:53:13-04:00 Pre-add test case for #19156 - - - - - d82d3823 by Vladislav Zavialov at 2021-05-23T18:53:13-04:00 Introduce Strict.Maybe, Strict.Pair (#19156) This patch fixes a space leak related to the use of Maybe in RealSrcSpan by introducing a strict variant of Maybe. In addition to that, it also introduces a strict pair and uses the newly introduced strict data types in a few other places (e.g. the lexer/parser state) to reduce allocations. Includes a regression test. - - - - - f8c6fce4 by Vladislav Zavialov at 2021-05-23T18:53:50-04:00 HsToken for HsPar, ParPat, HsCmdPar (#19523) This patch is a first step towards a simpler design for exact printing. - - - - - fc23ae89 by nineonine at 2021-05-24T00:14:53-04:00 Add regression test for #9985 - - - - - 3e4ef4b2 by Sylvain Henry at 2021-05-24T00:15:33-04:00 Move warning flag handling into Flags module I need this to make the Logger independent of DynFlags. Also fix copy-paste errors: Opt_WarnNonCanonicalMonadInstances was associated to "noncanonical-monadfail-instances" (MonadFailInstances vs MonadInstances). In the process I've also made the default name for each flag more explicit. - - - - - 098c7794 by Matthew Pickering at 2021-05-24T09:47:52-04:00 check-{ppr/exact}: Rewrite more directly to just parse files There was quite a large amount of indirection in these tests, so I have rewritten them to just directly parse the files rather than making a module graph and entering other twisty packages. - - - - - a3665a7a by Matthew Pickering at 2021-05-24T09:48:27-04:00 docs: Fix example in toIntegralSized Thanks to Mathnerd3141 for the fixed example. Fixes #19880 - - - - - f243acf4 by Divam Narula at 2021-05-25T05:50:51-04:00 Refactor driver code; de-duplicate and split APIs (#14095, !5555) This commit does some de-duplication of logic between the one-shot and --make modes, and splitting of some of the APIs so that its easier to do the fine-grained parallelism implementation. This is the first part of the implementation plan as described in #14095 * compileOne now uses the runPhase pipeline for most of the work. The Interpreter backend handling has been moved to the runPhase. * hscIncrementalCompile has been broken down into multiple APIs. * haddock submodule bump: Rename of variables in html-test ref: This is caused by a change in ModDetails in case of NoBackend. Now the initModDetails is used to recreate the ModDetails from interface and in-memory ModDetails is not used. - - - - - 6ce8e687 by Zubin Duggal at 2021-05-25T05:51:26-04:00 Make tcIfaceCompleteMatch lazier. Insufficient lazyness causes a loop while typechecking COMPLETE pragmas from interfaces (#19744). - - - - - 8f22af8c by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci] darwin uses hadrian Make is bad, and really slow, and we should just stop using it outright, or kill hadrian. Let's rather go for hadrian all the way and phase out make. - - - - - 4d100f68 by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci] no more brew or pip We pull dependencies (reliably) via nix, and open up nix where needed. - - - - - c67c9e82 by Moritz Angermann at 2021-05-25T05:52:02-04:00 [bindist] inject xattr -c -r . into the darwin install phase This is so awful, but at least it might get the job done. - - - - - 544414ba by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci/darwin] use system provided iconv and curses Also make sure to be able to build with non-apple-clang, while using apple's SDK on macOS - - - - - 527543fc by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci/darwin] cabal-cache dir can be specified per arch Also while we are at it, run shellcheck on ci.sh - - - - - 7b1eeabf by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci/darwin] set SH to /bin/bash This should prevent some other `bash` to leak into the binary distributions. - - - - - f101e019 by Moritz Angermann at 2021-05-25T05:52:02-04:00 [hadrian] Do not add full tool paths This prohuibits CC=clang to work generically and will always bake in the clang that is found on the build machine in PATH, what ever clang that might be. It might not even be on the final host. - - - - - c4b4b1d7 by Moritz Angermann at 2021-05-25T05:52:02-04:00 [ci] faster pipeline - - - - - 50c3061d by Moritz Angermann at 2021-05-25T05:52:02-04:00 [hadrian] Properly build hsc2hs wrapper - - - - - 11bdf3cd by Matthew Pickering at 2021-05-25T05:52:02-04:00 Revert "hadrian: Don't always links against libffi" This reverts commit 673ff667c98eafc89e6746d1ac69d33b8330d755. - - - - - 2023b344 by Richard Eisenberg at 2021-05-25T09:08:36-04:00 Add 9.2 release note about linear case This is part of #18738 [skip ci] - - - - - cdbce8fc by Alfredo Di Napoli at 2021-05-26T16:03:15-04:00 Support new parser types in GHC This commit converts the lexers and all the parser machinery to use the new parser types and diagnostics infrastructure. Furthermore, it cleans up the way the parser code was emitting hints. As a result of this systematic approach, the test output of the `InfixAppPatErr` and `T984` tests have been changed. Previously they would emit a `SuggestMissingDo` hint, but this was not at all helpful in resolving the error, and it was even confusing by just looking at the original program that triggered the errors. Update haddock submodule - - - - - 9faafb0a by Pepe Iborra at 2021-05-26T16:03:52-04:00 Avoid fingerprinting the absolute path to the source file This change aims to make source files relocatable w.r.t. to the interface files produced by the compiler. This is so that we can download interface files produced by a cloud build system and then reuse them in a local ghcide session catch another case of implicit includes actually use the implicit quote includes add another missing case recomp020 test that .hi files are reused even if .hs files are moved to a new location Added recomp021 to record behaviour with non implicit includes add a note additional pointer to the note Mention #16956 in Note - - - - - 03d69e4b by Andreas Klebinger at 2021-05-27T02:35:11-04:00 Enable strict dicts by default at -O2. In the common case this is a straight performance win at a compile time cost so we enable it at -O2. In rare cases it can lead to compile time regressions because of changed inlining behaviour. Which can very rarely also affect runtime performance. Increasing the inlining threshold can help to avoid this which is documented in the user guide. In terms of measured results this reduced instructions executed for nofib by 1%. However for some cases (e.g. Cabal) enabling this by default increases compile time by 2-3% so we enable it only at -O2 where it's clear that a user is willing to trade compile time for runtime. Most of the testsuite runs without -O2 so there are few perf changes. Increases: T12545/T18698: We perform more WW work because dicts are now treated strict. T9198: Also some more work because functions are now subject to W/W Decreases: T14697: Compiling empty modules. Probably because of changes inside ghc. T9203: I can't reproduce this improvement locally. Might be spurious. ------------------------- Metric Decrease: T12227 T14697 T9203 Metric Increase: T9198 T12545 T18698a T18698b ------------------------- - - - - - 9935e99c by Shayne Fletcher at 2021-05-27T02:35:47-04:00 Change representation of HsGetField and HsProjection Another change in a series improving record syntax in the AST. The key change in this commit is the renaming of `HsFieldLabel` to `DotFieldOcc`. - - - - - ce1b8f42 by Andreas Klebinger at 2021-05-27T02:36:23-04:00 Improve deriveConstants error message. This fixes #19823 - - - - - 6de8ac89 by Alan Zimmerman at 2021-05-27T19:25:24+01:00 [EPA] exact print linear arrows. Closes #19903 Note: the normal ppr does not reproduce unicode linear arrows, so that part of the normal printing test is ommented out in the Makefile for this test. See #18846 - - - - - f74204c4 by Boris Lykah at 2021-05-28T15:32:01-04:00 Document release when TypeApplications allowed declaring variables as inferred - - - - - df997fac by Sylvain Henry at 2021-05-28T15:32:44-04:00 Use quotRemWord in showWord Using the following high-quality benchmark (with -O2): main :: IO () main = do let go 0 = "" go n@(W# n#) = showWord n# (go (n -1)) print $ length (go 10000000) I get the following performance results: - remWord+quotRem: 0,76s user 0,00s system 99% cpu 0,762 total - quotRemWord: 0,45s user 0,01s system 99% cpu 0,456 total Note that showSignedInt already uses quotRemInt. - - - - - 5ae070f1 by Thomas Winant at 2021-05-29T05:04:00-04:00 Add -Wmissing-exported-pattern-synonym-signatures After !4741, it was no longer possible to silence a warning about a missing pattern synonym signature if the `-Wmissing-signatures` flag was on. Restore the previous semantics while still adhering to the principle "enabling an additional warning flag should never make prior warnings disappear". For more symmetry and granularity, introduce `-Wmissing-exported-pattern-synonym-signatures`. See Note [Missing signatures] for an overview of all flags involved. - - - - - 28e0dca2 by Luite Stegeman at 2021-05-29T05:04:39-04:00 Work around LLVM backend overlapping register limitations The stg_ctoi_t and stg_ret_t procedures which convert unboxed tuples between the bytecode an native calling convention were causing a panic when using the LLVM backend. Fixes #19591 - - - - - 6412bf6e by parsonsmatt at 2021-05-29T05:05:18-04:00 Add `newDeclarationGroup` and provide documentation in reifyInstances and isInstance - - - - - 99b5cce9 by parsonsmatt at 2021-05-29T05:05:18-04:00 Address review comments, export from TH - - - - - 76902415 by parsonsmatt at 2021-05-29T05:05:18-04:00 Apply 2 suggestion(s) to 1 file(s) - - - - - 0c0e1855 by parsonsmatt at 2021-05-29T05:05:18-04:00 sigh - - - - - 10f48e22 by Matthew Pickering at 2021-05-29T05:05:55-04:00 ghci: Enable -fkeep-going by default This also demotes the error message about -fkeep-going to a trace message which matches the behaviour of other build systems (such as cabal-install and nix) which don't print any message like this on a failure. We want to remove the stable module check in a future patch, which is an approximation of `-fkeep-going`. At the moment this change shouldn't do very much. - - - - - 492b2dc5 by Zubin Duggal at 2021-05-29T05:06:32-04:00 Fix Note [Positioning of forkM] - - - - - 45387760 by Sylvain Henry at 2021-05-29T10:18:01-04:00 Bignum: match on DataCon workers in rules (#19892) We need to match on DataCon workers for the rules to be triggered. T13701 ghc/alloc decreases by ~2.5% on some archs Metric Decrease: T13701 - - - - - 0f8872ec by Sylvain Henry at 2021-05-29T10:18:01-04:00 Fix and slight improvement to datacon worker/wrapper notes - - - - - 6db8a0f7 by Richard Eisenberg at 2021-05-29T10:18:37-04:00 Rip GHC.Tc.Solver.Monad asunder (only) This creates new modules GHC.Tc.Solver.InertSet and GHC.Tc.Solver.Types. The Monad module is still pretty big, but this is an improvement. Moreover, it means that GHC.HsToCore.Pmc.Solver.Types no longer depends on the constraint solver (it now depends on GHC.Tc.Solver.InertSet), making the error-messages work easier. This patch thus contributes to #18516. - - - - - 42c611cf by Ben Gamari at 2021-05-29T11:57:51-04:00 Split GHC.Utils.Monad.State into .Strict and .Lazy - - - - - ec646247 by Ben Gamari at 2021-05-29T11:58:45-04:00 Use GHC's State monad consistently GHC's internal State monad benefits from oneShot annotations on its state, allowing for more aggressive eta expansion. We currently don't have monad transformers with the same optimisation, so we only change uses of the pure State monad here. See #19657 and 19380. Metric Decrease: hie002 - - - - - 21bdd9b7 by Ben Gamari at 2021-05-29T11:58:52-04:00 StgM: Use ReaderT rather than StateT - - - - - 6b6c4b9a by Viktor Dukhovni at 2021-06-02T04:38:47-04:00 Improve wording of fold[lr]M documentation. The sequencing of monadic effects in foldlM and foldrM was described as respectively right-associative and left-associative, but this could be confusing, as in essence we're just composing Kleisli arrows, whose composition is simply associative. What matters therefore is the order of sequencing of effects, which can be described more clearly without dragging in associativity as such. This avoids describing these folds as being both left-to-right and right-to-left depending on whether we're tracking effects or operator application. The new text should be easier to understand. - - - - - fcd124d5 by Roland Senn at 2021-06-02T04:39:23-04:00 Allow primops in a :print (and friends) command. Fix #19394 * For primops from `GHC.Prim` lookup the HValues in `GHC.PrimopWrappers`. * Add short error messages if a user tries to use a *Non-Id* value or a `pseudoop` in a `:print`, `:sprint` or `force`command. * Add additional test cases for `Magic Ids`. - - - - - adddf248 by Zubin Duggal at 2021-06-02T04:39:58-04:00 Fail before checking instances in checkHsigIface if exports don't match (#19244) - - - - - c5a9e32e by Divam Narula at 2021-06-02T04:40:34-04:00 Specify the reason for import for the backpack's extra imports - - - - - 7d8e1549 by Vladislav Zavialov at 2021-06-02T04:41:08-04:00 Disallow linear arrows in GADT records (#19928) Before this patch, GHC used to silently accept programs such as the following: data R where D1 :: { d1 :: Int } %1 -> R The %1 annotation was completely ignored. Now it is a proper error. One remaining issue is that in the error message (⊸) turns into (%1 ->). This is to be corrected with upcoming exactprint updates. - - - - - 437a6ccd by Matthew Pickering at 2021-06-02T16:23:53-04:00 hadrian: Speed up lint:base rule The rule before decided to build the whole stage1 compiler, but this was unecessary as we were just missing one header file which can be generated directly by calling configure. Before: 18 minutes After: 54s - - - - - de33143c by Matthew Pickering at 2021-06-02T16:23:53-04:00 Run both lint jobs together - - - - - 852a12c8 by Matthew Pickering at 2021-06-02T16:23:53-04:00 CI: Don't explicitly build hadrian before using run_hadrian This causes hadrian to be built twice because the second time uses a different index state. - - - - - b66cf8ad by Matthew Pickering at 2021-06-02T16:24:27-04:00 Fix infinite looping in hptSomeModulesBelow When compiling Agda we entered into an infinite loop as the stopping condition was a bit wrong in hptSomeModulesBelow. The bad situation was something like * We would see module A (NotBoot) and follow it dependencies * Later on we would encounter A (Boot) and follow it's dependencies, because the lookup would not match A (NotBoot) and A (IsBoot) * Somewhere in A (Boot)s dependencies, A (Boot) would appear again and lead us into an infinite loop. Now the state marks whether we have been both variants (IsBoot and NotBoot) so we don't follow dependencies for A (Boot) many times. - - - - - b585aff0 by Sebastian Graf at 2021-06-02T23:06:18-04:00 WW: Mark absent errors as diverging again As the now historic part of `NOTE [aBSENT_ERROR_ID]` explains, we used to have `exprIsHNF` respond True to `absentError` and give it a non-bottoming demand signature, in order to perform case-to-let on certain `case`s we used to emit that scrutinised `absentError` (Urgh). What changed, why don't we emit these questionable absent errors anymore? The absent errors in question filled in for binders that would end up in strict fields after being seq'd. Apparently, the old strictness analyser would give these binders an absent demand, but today we give them head-strict demand `1A` and thus don't replace with absent errors at all. This fixes items (1) and (2) of #19853. - - - - - 79d12d34 by Shayne Fletcher at 2021-06-02T23:06:52-04:00 CountDeps: print graph of module dependencies in dot format The tests `CountParserDeps.hs` and `CountAstDeps.hs` are implemented by calling `CountDeps`. In this MR, `CountDeps.printDeps` is updated such tat by uncommenting a line, you can print a module's dependency graph showing what includes what. The output is in a format suitable for use with graphviz. - - - - - 25977ab5 by Matthew Pickering at 2021-06-03T08:46:47+01:00 Driver Rework Patch This patch comprises of four different but closely related ideas. The net result is fixing a large number of open issues with the driver whilst making it simpler to understand. 1. Use the hash of the source file to determine whether the source file has changed or not. This makes the recompilation checking more robust to modern build systems which are liable to copy files around changing their modification times. 2. Remove the concept of a "stable module", a stable module was one where the object file was older than the source file, and all transitive dependencies were also stable. Now we don't rely on the modification time of the source file, the notion of stability is moot. 3. Fix TH/plugin recompilation after the removal of stable modules. The TH recompilation check used to rely on stable modules. Now there is a uniform and simple way, we directly track the linkables which were loaded into the interpreter whilst compiling a module. This is an over-approximation but more robust wrt package dependencies changing. 4. Fix recompilation checking for dynamic object files. Now we actually check if the dynamic object file exists when compiling with -dynamic-too Fixes #19774 #19771 #19758 #17434 #11556 #9121 #8211 #16495 #7277 #16093 - - - - - d5b89ed4 by Alfredo Di Napoli at 2021-06-03T15:58:33-04:00 Port HsToCore messages to new infrastructure This commit converts a bunch of HsToCore (Ds) messages to use the new GHC's diagnostic message infrastructure. In particular the DsMessage type has been expanded with a lot of type constructors, each encapsulating a particular error and warning emitted during desugaring. Due to the fact that levity polymorphism checking can happen both at the Ds and at the TcRn level, a new `TcLevityCheckDsMessage` constructor has been added to the `TcRnMessage` type. - - - - - 7a05185a by Roland Senn at 2021-06-03T15:59:10-04:00 Follow up #12449: Improve function `Inspect.hs:check2` * Add a Note to clarify RttiTypes. * Don't call `quantifyType` at all the call sites of `check2`. * Simplyfy arguments of functions `Inspect.hs:check1` and `Inspect.hs:check2`. - `check1` only uses the two lists of type variables, but not the types. - `check2` only uses the two types, but not the lists of type variables. * In `Inspect.hs:check2` send only the tau part of the type to `tcSplitTyConApp_maybe`. - - - - - 1bb0565c by Thomas Winant at 2021-06-04T00:30:22-04:00 Fix incorrect mention of -Wprepositive-qualified-syntax in docs The flag is called `-Wprepositive-qualified-module`, not `-Wprepositive-qualified-syntax`. Use the `:ghc-flag:` syntax, which would have caught the mistake in the first place. - - - - - 44d131af by Takenobu Tani at 2021-06-04T00:30:59-04:00 users-guide: Add OverloadedRecordDot and OverloadedRecordUpdate for ghc-9.2 This patch adds OverloadedRecordDot and OverloadedRecordUpdate in 9.2.1's release note. - - - - - f1b748b4 by Alfredo Di Napoli at 2021-06-04T12:43:41-04:00 Add PsHeaderMessage diagnostic (fixes #19923) This commit replaces the PsUnknownMessage diagnostics over at `GHC.Parser.Header` with a new `PsHeaderMessage` type (part of the more general `PsMessage`), so that we can throw parser header's errors which can be correctly caught by `GHC.Driver.Pipeline.preprocess` and rewrapped (correctly) as Driver messages (using the `DriverPsHeaderMessage`). This gets rid of the nasty compiler crash as part of #19923. - - - - - 733757ad by sheaf at 2021-06-04T12:44:19-04:00 Make some simple primops levity-polymorphic Fixes #17817 - - - - - 737b0ae1 by Sylvain Henry at 2021-06-04T12:45:01-04:00 Fix Integral instances for Words * ensure that division wrappers are INLINE * make div/mod/divMod call quot/rem/quotRem (same code) * this ensures that the quotRemWordN# primitive is used to implement divMod (it wasn't the case for sized Words) * make first argument strict for Natural and Integer (similarly to other numeric types) - - - - - 1713cbb0 by Shayne Fletcher at 2021-06-05T03:47:48-04:00 Make 'count-deps' a ghc/util standalone program - Move 'count-deps' into 'ghc/utils' so that it can be called standalone. - Move 'testsuite/tests/parser/should_run/' tests 'CountParserDeps' and 'CountAstDeps' to 'testsuite/tests/count-deps' and reimplement in terms of calling the utility - Document how to use 'count-deps' in 'ghc/utils/count-deps/README' - - - - - 9a28680d by Sylvain Henry at 2021-06-05T03:48:25-04:00 Put Unique related global variables in the RTS (#19940) - - - - - 8c90e6c7 by Richard Eisenberg at 2021-06-05T10:29:22-04:00 Fix #19682 by breaking cycles in Deriveds This commit expands the old Note [Type variable cycles in Givens] to apply as well to Deriveds. See the Note for details and examples. This fixes a regression introduced by my earlier commit that killed off the flattener in favor of the rewriter. A few other things happened along the way: * unifyTest was renamed to touchabilityTest, because that's what it does. * isInsolubleOccursCheck was folded into checkTypeEq, which does much of the same work. To get this to work out, though, we need to keep more careful track of what errors we spot in checkTypeEq, and so CheckTyEqResult has become rather more glorious. * A redundant Note or two was eliminated. * Kill off occCheckForErrors; due to Note [Rewriting synonyms], the extra occCheckExpand here is always redundant. * Store blocked equalities separately from other inerts; less stuff to look through when kicking out. Close #19682. test case: typecheck/should_compile/T19682{,b} - - - - - 3b1aa7db by Moritz Angermann at 2021-06-05T10:29:57-04:00 Adds AArch64 Native Code Generator In which we add a new code generator to the Glasgow Haskell Compiler. This codegen supports ELF and Mach-O targets, thus covering Linux, macOS, and BSDs in principle. It was tested only on macOS and Linux. The NCG follows a similar structure as the other native code generators we already have, and should therfore be realtively easy to follow. It supports most of the features required for a proper native code generator, but does not claim to be perfect or fully optimised. There are still opportunities for optimisations. Metric Decrease: ManyAlternatives ManyConstructors MultiLayerModules PmSeriesG PmSeriesS PmSeriesT PmSeriesV T10421 T10421a T10858 T11195 T11276 T11303b T11374 T11822 T12227 T12545 T12707 T13035 T13253 T13253-spj T13379 T13701 T13719 T14683 T14697 T15164 T15630 T16577 T17096 T17516 T17836 T17836b T17977 T17977b T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T3064 T5030 T5321FD T5321Fun T5631 T5642 T5837 T783 T9198 T9233 T9630 T9872d T9961 WWRec Metric Increase: T4801 - - - - - db1e07f1 by Moritz Angermann at 2021-06-05T10:29:57-04:00 [ci] -llvm with --way=llvm - - - - - 1b2f894f by Moritz Angermann at 2021-06-05T10:29:57-04:00 [ci] no docs for aarch64-linux-llvm - - - - - a1fed3a5 by Moritz Angermann at 2021-06-05T10:29:57-04:00 [ci] force CC=clang for aarch64-linux - - - - - 4db2d44c by Moritz Angermann at 2021-06-05T10:29:57-04:00 [testsuite] fix T13702 with clang - - - - - ecc3a405 by Moritz Angermann at 2021-06-05T10:29:57-04:00 [testsuite] fix T6132 when using the LLVM toolchain - - - - - cced9454 by Shayne Fletcher at 2021-06-05T19:23:11-04:00 Countdeps: Strictly documentation markup fixes [ci skip] - - - - - ea9a4ef6 by Simon Peyton Jones at 2021-06-05T19:23:46-04:00 Avoid useless w/w split, take 2 This commit: commit c6faa42bfb954445c09c5680afd4fb875ef03758 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Mon Mar 9 10:20:42 2020 +0000 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. turns out to have a bug in it. Instead of /moving/ the conditional, I /duplicated/ it. Then in a subsequent unrelated tidy-up (087ac4eb) I removed the second (redundant) test! This patch does what I originally intended. There is also a small refactoring in GHC.Core.Unfold, to make the code clearer, but with no change in behaviour. It does, however, have a generally good effect on compile times, because we aren't dealing with so many silly stable unfoldings. Here are the non-zero changes: Metrics: compile_time/bytes allocated ------------------------------------- Baseline Test Metric value New value Change --------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 791969344.0 792665048.0 +0.1% ManyConstructors(normal) ghc/alloc 4351126824.0 4358303528.0 +0.2% PmSeriesG(normal) ghc/alloc 50362552.0 50482208.0 +0.2% PmSeriesS(normal) ghc/alloc 63733024.0 63619912.0 -0.2% T10421(normal) ghc/alloc 121224624.0 119695448.0 -1.3% GOOD T10421a(normal) ghc/alloc 85256392.0 83714224.0 -1.8% T10547(normal) ghc/alloc 29253072.0 29258256.0 +0.0% T10858(normal) ghc/alloc 189343152.0 187972328.0 -0.7% T11195(normal) ghc/alloc 281208248.0 279727584.0 -0.5% T11276(normal) ghc/alloc 141966952.0 142046224.0 +0.1% T11303b(normal) ghc/alloc 46228360.0 46259024.0 +0.1% T11545(normal) ghc/alloc 2663128768.0 2667412656.0 +0.2% T11822(normal) ghc/alloc 138686944.0 138760176.0 +0.1% T12227(normal) ghc/alloc 482836000.0 475421056.0 -1.5% GOOD T12234(optasm) ghc/alloc 60710520.0 60781808.0 +0.1% T12425(optasm) ghc/alloc 104089000.0 104022424.0 -0.1% T12545(normal) ghc/alloc 1711759416.0 1705711528.0 -0.4% T12707(normal) ghc/alloc 991541120.0 991921776.0 +0.0% T13035(normal) ghc/alloc 108199872.0 108370704.0 +0.2% T13056(optasm) ghc/alloc 414642544.0 412580384.0 -0.5% T13253(normal) ghc/alloc 361701272.0 355838624.0 -1.6% T13253-spj(normal) ghc/alloc 157710168.0 157397768.0 -0.2% T13379(normal) ghc/alloc 370984400.0 371345888.0 +0.1% T13701(normal) ghc/alloc 2439764144.0 2441351984.0 +0.1% T14052(ghci) ghc/alloc 2154090896.0 2156671400.0 +0.1% T15164(normal) ghc/alloc 1478517688.0 1440317696.0 -2.6% GOOD T15630(normal) ghc/alloc 178053912.0 172489808.0 -3.1% T16577(normal) ghc/alloc 7859948896.0 7854524080.0 -0.1% T17516(normal) ghc/alloc 1271520128.0 1202096488.0 -5.5% GOOD T17836(normal) ghc/alloc 1123320632.0 1123922480.0 +0.1% T17836b(normal) ghc/alloc 54526280.0 54576776.0 +0.1% T17977b(normal) ghc/alloc 42706752.0 42730544.0 +0.1% T18140(normal) ghc/alloc 108834568.0 108693816.0 -0.1% T18223(normal) ghc/alloc 5539629264.0 5579500872.0 +0.7% T18304(normal) ghc/alloc 97589720.0 97196944.0 -0.4% T18478(normal) ghc/alloc 770755472.0 771232888.0 +0.1% T18698a(normal) ghc/alloc 408691160.0 374364992.0 -8.4% GOOD T18698b(normal) ghc/alloc 492419768.0 458809408.0 -6.8% GOOD T18923(normal) ghc/alloc 72177032.0 71368824.0 -1.1% T1969(normal) ghc/alloc 803523496.0 804655112.0 +0.1% T3064(normal) ghc/alloc 198411784.0 198608512.0 +0.1% T4801(normal) ghc/alloc 312416688.0 312874976.0 +0.1% T5321Fun(normal) ghc/alloc 325230680.0 325474448.0 +0.1% T5631(normal) ghc/alloc 592064448.0 593518968.0 +0.2% T5837(normal) ghc/alloc 37691496.0 37710904.0 +0.1% T783(normal) ghc/alloc 404629536.0 405064432.0 +0.1% T9020(optasm) ghc/alloc 266004608.0 266375592.0 +0.1% T9198(normal) ghc/alloc 49221336.0 49268648.0 +0.1% T9233(normal) ghc/alloc 913464984.0 742680256.0 -18.7% GOOD T9675(optasm) ghc/alloc 552296608.0 466322000.0 -15.6% GOOD T9872a(normal) ghc/alloc 1789910616.0 1793924472.0 +0.2% T9872b(normal) ghc/alloc 2315141376.0 2310338056.0 -0.2% T9872c(normal) ghc/alloc 1840422424.0 1841567224.0 +0.1% T9872d(normal) ghc/alloc 556713248.0 556838432.0 +0.0% T9961(normal) ghc/alloc 383809160.0 384601600.0 +0.2% WWRec(normal) ghc/alloc 773751272.0 753949608.0 -2.6% GOOD Residency goes down too: Metrics: compile_time/max_bytes_used ------------------------------------ Baseline Test Metric value New value Change ----------------------------------------------------------- T10370(optasm) ghc/max 42058448.0 39481672.0 -6.1% T11545(normal) ghc/max 43641392.0 43634752.0 -0.0% T15304(normal) ghc/max 29895824.0 29439032.0 -1.5% T15630(normal) ghc/max 8822568.0 8772328.0 -0.6% T18698a(normal) ghc/max 13882536.0 13787112.0 -0.7% T18698b(normal) ghc/max 14714112.0 13836408.0 -6.0% T1969(normal) ghc/max 24724128.0 24733496.0 +0.0% T3064(normal) ghc/max 14041152.0 14034768.0 -0.0% T3294(normal) ghc/max 32769248.0 32760312.0 -0.0% T9630(normal) ghc/max 41605120.0 41572184.0 -0.1% T9675(optasm) ghc/max 18652296.0 17253480.0 -7.5% Metric Decrease: T10421 T12227 T15164 T17516 T18698a T18698b T9233 T9675 WWRec Metric Increase: T12545 - - - - - 52a524f7 by Simon Peyton Jones at 2021-06-05T19:23:46-04:00 Re-do rubbish literals As #19882 pointed out, we were simply doing rubbish literals wrong. (I'll refrain from explaining the wrong-ness here -- see the ticket.) This patch fixes it by adding a Type (of kind RuntimeRep) as field of LitRubbish, rather than [PrimRep]. The Note [Rubbish literals] in GHC.Types.Literal explains the details. - - - - - 34424b9d by Simon Peyton Jones at 2021-06-05T19:23:46-04:00 Drop absent bindings in worker/wrapper Consider this (from #19824) let t = ...big... in ...(f t x)... were `f` ignores its first argument. With luck f's wrapper will inline thereby dropping `t`, but maybe not: the arguments to f all look boring. So we pre-empt the problem by replacing t's RHS with an absent filler during w/w. Simple and effective. The main payload is the new `isAbsDmd` case in `tryWw`, but there are some other minor refactorings: * To implment this I had to refactor `mk_absent_let` to `mkAbsentFiller`, which can be called from `tryWW`. * wwExpr took both WwOpts and DynFlags which seems silly. I combined them into one. * I renamed the historical mkInineRule to mkWrapperUnfolding - - - - - 3e343292 by Ben Gamari at 2021-06-05T19:23:46-04:00 testsuite: Eliminate fragility of ioprof As noted in #10037, the `ioprof` test would change its stderr output (specifically the stacktrace produced by `error`) depending upon optimisation level. As the `error` backtrace is not the point of this test, we now ignore the `stderr` output. - - - - - 5e1a2244 by Ben Gamari at 2021-06-05T19:23:46-04:00 testsuite: Fix Note style - - - - - 4dc681c7 by Sylvain Henry at 2021-06-07T10:35:39+02:00 Make Logger independent of DynFlags Introduce LogFlags as a independent subset of DynFlags used for logging. As a consequence in many places we don't have to pass both Logger and DynFlags anymore. The main reason for this refactoring is that I want to refactor the systools interfaces: for now many systools functions use DynFlags both to use the Logger and to fetch their parameters (e.g. ldInputs for the linker). I'm interested in refactoring the way they fetch their parameters (i.e. use dedicated XxxOpts data types instead of DynFlags) for #19877. But if I did this refactoring before refactoring the Logger, we would have duplicate parameters (e.g. ldInputs from DynFlags and linkerInputs from LinkerOpts). Hence this patch first. Some flags don't really belong to LogFlags because they are subsystem specific (e.g. most DumpFlags). For example -ddump-asm should better be passed in NCGConfig somehow. This patch doesn't fix this tight coupling: the dump flags are part of the UI but they are passed all the way down for example to infer the file name for the dumps. Because LogFlags are a subset of the DynFlags, we must update the former when the latter changes (not so often). As a consequence we now use accessors to read/write DynFlags in HscEnv instead of using `hsc_dflags` directly. In the process I've also made some subsystems less dependent on DynFlags: - CmmToAsm: by passing some missing flags via NCGConfig (see new fields in GHC.CmmToAsm.Config) - Core.Opt.*: - by passing -dinline-check value into UnfoldingOpts - by fixing some Core passes interfaces (e.g. CallArity, FloatIn) that took DynFlags argument for no good reason. - as a side-effect GHC.Core.Opt.Pipeline.doCorePass is much less convoluted. - - - - - 3a90814f by Sylvain Henry at 2021-06-07T11:19:35+02:00 Parser: make less DynFlags dependent This is an attempt at reducing the number of dependencies of the Parser (as reported by CountParserDeps). Modules in GHC.Parser.* don't import GHC.Driver.Session directly anymore. Sadly some GHC.Driver.* modules are still transitively imported and the number of dependencies didn't decrease. But it's a step in the right direction. - - - - - 40c0f67f by Sylvain Henry at 2021-06-07T11:19:35+02:00 Bump haddock submodule - - - - - 9e724f6e by Viktor Dukhovni at 2021-06-07T15:35:22-04:00 Small ZipList optimisation In (<|>) for ZipList, avoid processing the first argument twice (both as first argument of (++) and for its length in drop count of the second argument). Previously, the entire first argument was forced into memory, now (<|>) can run in constant space even with long inputs. - - - - - 7ea3b7eb by Ryan Scott at 2021-06-08T01:07:10+05:30 Introduce `hsExprType :: HsExpr GhcTc -> Type` in the new module `GHC.Hs.Syn.Type` The existing `hsPatType`, `hsLPatType` and `hsLitType` functions have also been moved to this module This is a less ambitious take on the same problem that !2182 and !3866 attempt to solve. Rather than have the `hsExprType` function attempt to efficiently compute the `Type` of every subexpression in an `HsExpr`, this simply computes the overall `Type` of a single `HsExpr`. - Explicitly forbids the `SplicePat` `HsIPVar`, `HsBracket`, `HsRnBracketOut` and `HsTcBracketOut` constructors during the typechecking phase by using `Void` as the TTG extension field - Also introduces `dataConCantHappen` as a domain specific alternative to `absurd` to handle cases where the TTG extension points forbid a constructor. - Turns HIE file generation into a pure function that doesn't need access to the `DsM` monad to compute types, but uses `hsExprType` instead. - Computes a few more types during HIE file generation - Makes GHCi's `:set +c` command also use `hsExprType` instead of going through the desugarer to compute types. Updates haddock submodule Co-authored-by: Zubin Duggal <zubin.duggal at gmail.com> - - - - - 378c0bba by Tamar Christina at 2021-06-08T15:40:50-04:00 winio: use synchronous access explicitly for handles that may not be asynchronous. - - - - - 31bfafec by Baldur Blöndal at 2021-06-09T09:46:17-04:00 Added a regression test, this would trigger a Core Lint error before GHC 9 - - - - - d69067a1 by Matthew Pickering at 2021-06-09T09:46:51-04:00 FinderCache: Also cache file hashing in interface file checks Now that we hash object files to decide when to recompile due to TH, this can make a big difference as each interface file in a project will contain reference to the object files of all package dependencies. Especially when these are statically linked, hashing them can add up. The cache is invalidated when `depanalPartial` is called, like the normal finder cache. - - - - - f4a5e30e by Simon Peyton Jones at 2021-06-10T02:38:19-04:00 Do not add unfoldings to lambda-binders For reasons described in GHC.Core.Opt.Simplify Historical Note [Case binders and join points], we used to keep a Core unfolding in one of the lambda-binders for a join point. But this was always a gross hack -- it's very odd to have an unfolding in a lambda binder, that refers to earlier lambda binders. The hack bit us in various ways: * Most seriously, it is incompatible with linear types in Core. * It complicated demand analysis, and could worsen results * It required extra care in the simplifier (simplLamBinder) * It complicated !5641 (look for "join binder unfoldings") So this patch just removes the hack. Happily, doind so turned out to have no effect on performance. - - - - - 8baa8874 by Li-yao Xia at 2021-06-10T02:38:54-04:00 User's Guide: reword and fix punctuation in description of PostfixOperators - - - - - fb6b6379 by Matthew Pickering at 2021-06-10T02:39:29-04:00 Add (broken) test for #19966 - - - - - 61c51c00 by Sylvain Henry at 2021-06-10T02:40:07-04:00 Fix redundant import - - - - - 472c2bf0 by sheaf at 2021-06-10T13:54:05-04:00 Reword: representation instead of levity fixes #19756, updates haddock submodule - - - - - 3d5cb335 by Simon Peyton Jones at 2021-06-10T13:54:40-04:00 Fix INLINE pragmas in desugarer In #19969 we discovered that GHC has has a bug *forever* that means it sometimes essentially discarded INLINE pragams. This happened when you have * Two more more mutually recursive functions * Some of which (presumably not all!) have an INLINE pragma * Completely monomorphic. This hits a particular case in GHC.HsToCore.Binds.dsAbsBinds, which was simply wrong -- it put the INLINE pragma on the wrong binder. This patch fixes the bug, rather easily, by adjusting the no-tyvar, no-dict case of GHC.HsToCore.Binds.dsAbsBinds. I also discovered that the GHC.Core.Opt.Pipeline.shortOutIndirections was not doing a good job for {-# INLINE lcl_id #-} lcl_id = BIG gbl_id = lcl_id Here we want to transfer the stable unfolding to gbl_id (we do), but we also want to remove it from lcl_id (we were not doing that). Otherwise both Ids have large stable unfoldings. Easily fixed. Note [Transferring IdInfo] explains. - - - - - 2a7e29e5 by Ben Gamari at 2021-06-16T16:58:37+00:00 gitlab-ci: Bump ci-images - - - - - 6c131ba0 by Baldur Blöndal at 2021-06-16T20:18:35-04:00 DerivingVia for Hsc instances. GND for NonDetFastString and LexicalFastString. - - - - - a2e4cb80 by Vladislav Zavialov at 2021-06-16T20:19:10-04:00 HsUniToken and HsToken for HsArrow (#19623) Another step towards a simpler design for exact printing. Updates the haddock submodule. - - - - - 01fd2617 by Matthew Pickering at 2021-06-16T20:19:45-04:00 profiling: Look in RHS of rules for cost centre ticks There are some obscure situations where the RHS of a rule can contain a tick which is not mentioned anywhere else in the program. If this happens you end up with an obscure linker error. The solution is quite simple, traverse the RHS of rules to also look for ticks. It turned out to be easier to implement if the traversal was moved into CoreTidy rather than at the start of code generation because there we still had easy access to the rules. ./StreamD.o(.text+0x1b9f2): error: undefined reference to 'StreamK_mkStreamFromStream_HPC_cc' ./MArray.o(.text+0xbe83): error: undefined reference to 'StreamK_mkStreamFromStream_HPC_cc' Main.o(.text+0x6fdb): error: undefined reference to 'StreamK_mkStreamFromStream_HPC_cc' - - - - - d8bfebec by AriFordsham at 2021-06-16T20:20:22-04:00 Corrected typo - - - - - 34484c89 by Divam Narula at 2021-06-16T20:20:59-04:00 Remove the backend correction logic, as it is already been fixed at this point - - - - - e25772a0 by Peter Trommler at 2021-06-16T20:21:34-04:00 PPC NCG: Fix panic in linear register allocator - - - - - a83d2999 by Krzysztof Gogolewski at 2021-06-16T20:22:09-04:00 Fix error message for record updates, #19972 Fix found by Adam Gundry. - - - - - a0622459 by Matthew Pickering at 2021-06-17T11:55:17+01:00 Move validate-x86_64-linux-deb9-hadrian back to quick-build This increases the critical path length but in practice will reduce pressure on runners because less jobs overall will be spawned. See #20003 [skip ci] - - - - - 3b783496 by Simon Peyton Jones at 2021-06-18T12:27:33-04:00 Enhance cast worker/wrapper for INLINABLE In #19890 we realised that cast worker/wrapper didn't really work properly for functions with an INLINABLE pragma, and hence a stable unfolding. This patch fixes the problem. Instead of disabling cast w/w when there is a stable unfolding (as we did before), we now tranfer the stable unfolding to the worker. It turned out that it was easier to do that if I moved the cast w/w stuff from prepareBinding to completeBind. No chnages at all in nofib results: -------------------------------------------------------------------------------- Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- Min -0.0% 0.0% -63.8% -78.2% 0.0% Max -0.0% 0.0% +11.8% +11.7% 0.0% Geometric Mean -0.0% -0.0% -26.6% -33.4% -0.0% Small decreases in compile-time allocation for two tests (below) of around 2%. T12545 increased in compile-time alloc by 4%, but it's not reproducible on my machine, and is a known-wobbly test. Metric Increase: T12545 Metric Decrease: T18698a T18698b - - - - - c6a00c15 by Simon Peyton Jones at 2021-06-18T12:27:33-04:00 Improve abstractVars quantification ordering When floating a binding out past some type-variable binders, don't gratuitiously change the order of the binders. This small change gives code that is simpler, has less risk of non-determinism, and does not gratuitiously change type-variable order. See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. This is really just refactoring; no change in behaviour. - - - - - db7e6dc5 by Simon Peyton Jones at 2021-06-18T12:27:33-04:00 Improve pretty-printing of coercions With -dsuppress-coercions, it's still good to be able to see the type of the coercion. This patch prints the type. Maybe we should have a flag to control this too. - - - - - 5d3d9925 by Gleb Popov at 2021-06-18T12:27:36-04:00 Pass -DLIBICONV_PLUG when building base library on FreeBSD. If libiconv is installed from packages on the build machine, there is a high chance that the build system will pick up /usr/local/include/iconv.h instead of base /usr/include/iconv.h This additional preprocessor define makes package's libiconv header compatible with system one, fixing the build. Closes issue #19958 - - - - - 1e2ba8a4 by Matthew Pickering at 2021-06-19T12:22:27-04:00 CI: Keep the value of PERF_NOTE_KEY in darwin environments This fixes the performance test tracking for all darwin environments. - - - - - 028b9474 by Simon Peyton Jones at 2021-06-19T12:23:02-04:00 Add comments explaining why #19833 is wrong I realised that the suggestion in #19833 doesn't work, and documented why in Note [Zapping Used Once info in WorkWrap] - - - - - 6b2952cf by Sylvain Henry at 2021-06-19T12:23:39-04:00 RTS: fix indentation warning - - - - - a6548a66 by David at 2021-06-19T12:24:15-04:00 Correct haddock annotations in GetOpt - - - - - 23bb09c9 by Sylvain Henry at 2021-06-19T12:24:52-04:00 Perf: fix appendFS To append 2 FastString we don't need to convert them into ByteString: use ShortByteString's Semigroup instance instead. - - - - - 1c79ddc8 by Matthew Pickering at 2021-06-19T12:25:26-04:00 RTS: Fix flag parsing for --eventlog-flush-interval Fixes #20006 - - - - - fc8ad5f3 by Simon Peyton Jones at 2021-06-19T12:26:01-04:00 Fix type and strictness signature of fork# When working eta-expansion and reduction, I found that fork# had a weaker strictness signature than it should have (#19992). In particular, it didn't record that it applies its argument exactly once. To this I needed to give it a proper type (its first argument is always a function, which in turn entailed a small change to the call in GHC.Conc.Sync This patch fixes it. - - - - - 217b4dcc by Krzysztof Gogolewski at 2021-06-19T12:26:35-04:00 Deprecate -Wmissing-monadfail-instances (#17875) Also document deprecation of Wnoncanonical-monadfail-instances and -Wimplicit-kind-vars - - - - - 8838241f by Sylvain Henry at 2021-06-19T12:27:12-04:00 Fix naturalToFloat/Double * move naturalToFloat/Double from ghc-bignum to base:GHC.Float and make them wired-in (as their integerToFloat/Double counterparts) * use the same rounding method as integerToFloat/Double. This is an oversight of 540fa6b2cff3802877ff56a47ab3611e33a9ac86 * add passthrough rules for intToFloat, intToDouble, wordToFloat, wordToDouble. - - - - - 3f60a7e5 by Vladislav Zavialov at 2021-06-19T22:58:33-04:00 Do not reassociate lexical negation (#19838) - - - - - 4c87a3d1 by Ryan Scott at 2021-06-19T22:59:08-04:00 Simplify pprLHsContext This removes an _ad hoc_ special case for empty `LHsContext`s in `pprLHsContext`, fixing #20011. To avoid regressions in pretty-printing data types and classes constructed via TH, we now apply a heuristic where we convert empty datatype contexts and superclasses to a `Nothing` (rather than `Just` an empty context). This will, for instance, avoid pretty-printing every TH-constructed data type as `data () => Blah ...`. - - - - - a6a8d3f5 by Moritz Angermann at 2021-06-20T07:11:58-04:00 Guard Allocate Exec via LIBFFI by LIBFFI We now have two darwin flavours. AArch64-Darwin, and x86_64-darwin, the latter one which has proper custom adjustor support, the former though relies on libffi. Mixing both leads to odd crashes, as the closures might not fit the size of the libffi closures. Hence this needs to be guarded by the USE_LBFFI_FOR_ADJUSTORS guard. Original patch by Hamish Mackenzie - - - - - 689016dc by Matthew Pickering at 2021-06-20T07:12:32-04:00 Darwin CI: Don't explicitly pass ncurses/iconv paths Passing --with-ncurses-libraries means the path which gets backed in progagate into the built binaries. This is incorrect when we want to distribute the binaries because the user might not have the library in that specific place. It's the user's reponsibility to direct the dynamic linker to the right place. Fixes #19968 - - - - - 4a65c0f8 by Matthew Pickering at 2021-06-20T07:12:32-04:00 rts: Pass -Wl,_U,___darwin_check_fd_set_overflow on Darwin Note [fd_set_overflow] ~~~~~~~~~~~~~~~~~~~~~~ In this note is the very sad tale of __darwin_fd_set_overflow. The 8.10.5 release was broken because it was built in an environment where the libraries were provided by XCode 12.*, these libraries introduced a reference to __darwin_fd_set_overflow via the FD_SET macro which is used in Select.c. Unfortunately, this symbol is not available with XCode 11.* which led to a linker error when trying to link anything. This is almost certainly a bug in XCode but we still have to work around it. Undefined symbols for architecture x86_64: "___darwin_check_fd_set_overflow", referenced from: _awaitEvent in libHSrts.a(Select.o) ld: symbol(s) not found for architecture x86_64 One way to fix this is to upgrade your version of xcode, but this would force the upgrade on users prematurely. Fortunately it also seems safe to pass the linker option "-Wl,-U,___darwin_check_fd_set_overflow" because the usage of the symbol is guarded by a guard to check if it's defined. __header_always_inline int __darwin_check_fd_set(int _a, const void *_b) { if ((uintptr_t)&__darwin_check_fd_set_overflow != (uintptr_t) 0) { return __darwin_check_fd_set_overflow(_a, _b, 1); return __darwin_check_fd_set_overflow(_a, _b, 0); } else { return 1; } Across the internet there are many other reports of this issue See: https://github.com/mono/mono/issues/19393 , https://github.com/sitsofe/fio/commit/b6a1e63a1ff607692a3caf3c2db2c3d575ba2320 The issue was originally reported in #19950 Fixes #19950 - - - - - 6c783817 by Zubin Duggal at 2021-06-20T07:13:07-04:00 Set min LLVM version to 9 and make version checking use a non-inclusive upper bound. We use a non-inclusive upper bound so that setting the upper bound to 13 for example means that all 12.x versions are accepted. - - - - - 6281a333 by Matthew Pickering at 2021-06-20T07:13:41-04:00 Linker/darwin: Properly honour -fno-use-rpaths The specification is now simple * On linux, use `-Xlinker -rpath -Xlinker` to set the rpath of the executable * On darwin, never use `-Xlinker -rpath -Xlinker`, always inject the rpath afterwards, see `runInjectRPaths`. * If `-fno-use-rpaths` is passed then *never* inject anything into the rpath. Fixes #20004 - - - - - 5abf5997 by Fraser Tweedale at 2021-06-20T07:14:18-04:00 hadrian/README.md: update bignum options - - - - - 65bad0de by Matthew Pickering at 2021-06-22T02:33:00-04:00 CI: Don't set EXTRA_HC_OPTS in head.hackage job Upstream environment variables take precedance over downstream variables. It is more consistent (and easier to modify) if the variables are all set in the head.hackage CI file rather than setting this here. [skip ci] - - - - - 14956cb8 by Sylvain Henry at 2021-06-22T02:33:38-04:00 Put tracing functions into their own module Now that Outputable is independent of DynFlags, we can put tracing functions using SDocs into their own module that doesn't transitively depend on any GHC.Driver.* module. A few modules needed to be moved to avoid loops in DEBUG mode. - - - - - 595dfbb0 by Matthew Pickering at 2021-06-22T02:34:13-04:00 rts: Document --eventlog-flush-interval in RtsFlags Fixes #19995 - - - - - 362f078e by Krzysztof Gogolewski at 2021-06-22T02:34:49-04:00 Typos, minor comment fixes - Remove fstName, sndName, fstIdKey, sndIdKey - no longer used, removed from basicKnownKeyNames - Remove breakpointId, breakpointCondId, opaqueTyCon, unknownTyCon - they were used in the old implementation of the GHCi debugger - Fix typos in comments - Remove outdated comment in Lint.hs - Use 'LitRubbish' instead of 'RubbishLit' for consistency - Remove comment about subkinding - superseded by Note [Kind Constraint and kind Type] - Mention ticket ID in a linear types error message - Fix formatting in using-warnings.rst and linear-types.rst - Remove comment about 'Any' in Dynamic.hs - Dynamic now uses Typeable + existential instead of Any - Remove codeGen/should_compile/T13233.hs This was added by accident, it is not used and T13233 is already in should_fail - - - - - f7e41d78 by Matthew Pickering at 2021-06-22T02:35:24-04:00 ghc-bignum: trimed ~> trimmed Just a small typo which propagated through ghc-bignum - - - - - 62d720db by Potato Hatsue at 2021-06-22T02:36:00-04:00 Fix a typo in pattern synonyms doc - - - - - 87f57ecf by Adam Sandberg Ericsson at 2021-06-23T02:58:00-04:00 ci: fix ci.sh by creating build.mk in one place Previously `prepare_build_mk` created a build.mk that was overwritten right after. This makes the BIGNUM_BACKEND choice take effect, fixing #19953, and causing the metric increase below in the integer-simple job. Metric Increase: space_leak_001 - - - - - 7f6454fb by Matthew Pickering at 2021-06-23T02:58:35-04:00 Optimiser: Correctly deal with strings starting with unicode characters in exprConApp_maybe For example: "\0" is encoded to "C0 80", then the rule would correct use a decoding function to work out the first character was "C0 80" but then just used BS.tail so the rest of the string was "80". This resulted in "\0" being transformed into '\C0\80' : unpackCStringUTF8# "80" Which is obviously bogus. I rewrote the function to call utf8UnconsByteString directly and avoid the roundtrip through Faststring so now the head/tail is computed by the same call. Fixes #19976 - - - - - e14b893a by Matthew Pickering at 2021-06-23T02:59:09-04:00 testsuite: Don't try to run tests with missing libraries As noticed by sgraf, we were still running reqlib tests, even if the library was not available. The reasons for this were not clear to me as they would never work and it was causing some issues with empty stderr files being generated if you used --test-accept. Now if the required library is not there, the test is just skipped, and a counter increased to mark the fact. Perhaps in the future it would be nicer to explicitly record why certain tests are skipped. Missing libraries causing a skip is a special case at the moment. Fixes #20005 - - - - - aa1d0eb3 by sheaf at 2021-06-23T02:59:48-04:00 Enable TcPlugin tests on Windows - - - - - d8e5b274 by Matthew Pickering at 2021-06-23T03:00:23-04:00 ghci: Correct free variable calculation in StgToByteCode Fixes #20019 - - - - - 6bf82316 by Matthew Pickering at 2021-06-23T03:00:57-04:00 hadrian: Pass correct leading_underscore configuration to tests - - - - - 8fba28ec by Moritz Angermann at 2021-06-23T03:01:32-04:00 [testsuite] mark T3007 broken on darwin. Cabal explicitly passes options to set the rpath, which we then also try to set using install_name_tool. Cabal should also pass `-fno-use-rpaths` to suppress the setting of the rpath from within GHC. - - - - - 633bbc1f by Douglas Wilson at 2021-06-23T08:52:26+01:00 ci: Don't allow the nightly pipeline to be interrupted. Since 58cfcc65 the default for jobs has been "interruptible", this means that when new commits are pushed to a branch which already has a running pipeline then the old pipelines for this branch are cancelled. This includes the master branch, and in particular, new commits merged to the master branch will cancel the nightly job. The semantics of pipeline cancelling are actually a bit more complicated though. The interruptible flag is *per job*, but once a pipeline has run *any* non-interruptible job, then the whole pipeline is considered non-interruptible (ref https://gitlab.com/gitlab-org/gitlab/-/issues/32837). This leads to the hack in this MR where by default all jobs are `interruptible: True`, but for pipelines we definitely want to run, there is a dummy job which happens first, which is `interreuptible: False`. This has the effect of dirtying the whole pipeline and preventing another push to master from cancelling it. For now, this patch solves the immediate problem of making sure nightly jobs are not cancelled. In the future, we may want to enable this job also for the master branch, making that change might mean we need more CI capacity than currently available. [skip ci] Ticket: #19554 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 8191785e by Aaron Allen at 2021-06-23T20:33:48-04:00 Converts diagnostics for two errors in Ghc.Tc.Module (#19926) This adds constructors to TcRnMessage to replace use of TcRnUnknownMessage in Ghc.Tc.Module. Adds a test case for the UnsafeDueToPlugin warning. Closes #19926 - - - - - e2d8023d by Sylvain Henry at 2021-06-23T20:34:23-04:00 Add some tests for sized primops - - - - - d79530d1 by Moritz Angermann at 2021-06-23T20:34:23-04:00 [aarch64 NCG] Add better support for sub-word primops During the intial NCG development, GHC did not have support for anything below Words. As such the NCG didn't support any of this either. AArch64-Darwin however needs support for subword, as arguments in excess of the first eight (8) passed via registers are passed on the stack, and there in a packed fashion. Thus ghc learned about subword sizes. This than lead us to gain subword primops, and these subsequently highlighted deficiencies in the AArch64 NCG. This patch rectifies the ones I found through via the test-suite. I do not claim this to be exhaustive. Fixes: #19993 Metric Increase: T10421 T13035 T13719 T14697 T1969 T9203 T9872a T9872b T9872c T9872d T9961 haddock.Cabal haddock.base parsing001 - - - - - 38a6d8b8 by Viktor Dukhovni at 2021-06-23T20:34:58-04:00 Fix typo in Note [Quick Look for particular Ids] Fixes #20029 - - - - - 74c87414 by Tamar Christina at 2021-06-24T12:01:58-04:00 rts: move xxxHash out of the user namespace - - - - - 4023d4d9 by Krzysztof Gogolewski at 2021-06-24T12:02:33-04:00 Fix desugaring with unboxed types (#19883) - - - - - 4c6af6be by Alan Zimmerman at 2021-06-24T12:03:10-04:00 EPA: Bringing over tests and updates from ghc-exactprint - - - - - d6ab9c60 by Moritz Angermann at 2021-06-24T12:03:45-04:00 [aarch64-macho] Fix off-by-one error in the linker We need to be careful about the sign bit for BR26 relocation otherwise we end up encoding a large positive number and reading back a large negative number. - - - - - 48171833 by Matthew Pickering at 2021-06-24T12:04:19-04:00 CI: Fix the cabal_test job to compile the Distribution.Simple target The "Cabal test" was previously testing the compilation of the very advanced Setup.hs file. Now we compile the whole library, as the test intended. - - - - - 171413c6 by Matthew Pickering at 2021-06-24T12:04:19-04:00 cabal_test: Make output more like head.hackage output This helps with the import of the results into the performance database. - - - - - 138b7a57 by Viktor Dukhovni at 2021-06-24T12:04:54-04:00 There's no "errorWithCallStack", just use "error". There's no `errorWithCallStack`, only `errorWithStackTrace`, but the latter is now deprecated, since `error` now defaults to returning a stack strace. So rather than change this to the intended deprecated function we replace `errorWithCallStack` with `error` instead. - - - - - 4d5967b5 by Krzysztof Gogolewski at 2021-06-24T20:35:56-04:00 Fixes around incomplete guards (#20023, #20024) - Fix linearity error with incomplete MultiWayIf (#20023) - Fix partial pattern binding error message (#20024) - Remove obsolete test LinearPolyTest It tested the special typing rule for ($), which was removed during the implementation of Quick Look 97cff9190d3. - Fix ticket numbers in linear/*/all.T, they referred to linear types issue tracker - - - - - c1c29808 by Christian Takle at 2021-06-24T20:36:32-04:00 Update quantified_constraints.rst - - - - - 1c811959 by Moritz Angermann at 2021-06-24T20:37:07-04:00 [iserv] learn -wait cli flag Often times when attaching a debugger to iserv it's helpful to have iserv wait a few seconds for the debugger to attach. -wait can be passed via -opti-wait if needed. - - - - - f926ecfd by Matthew Pickering at 2021-06-24T20:37:42-04:00 linker: Replace one missed usage of Opt_RPath with useXLinkerRPath Thanks to @wz1000 for spotting this oversight. - - - - - fa6451b7 by Luite Stegeman at 2021-06-24T20:38:18-04:00 fix sdist for base library config.sub and config.guess aren't used anymore, so they should be removed from the base.cabal file - - - - - d1f59540 by sheaf at 2021-06-25T05:19:18-04:00 Make reallyUnsafePtrEquality# levity-polymorphic fixes #17126, updates containers submodule - - - - - 30afb381 by Matthew Pickering at 2021-06-25T05:19:53-04:00 ghci: Add test for #18330 This test was fixed by 25977ab542a30df4ae71d9699d015bcdd1ab7cfb Fixes #18330 - - - - - f43a11d7 by Matthew Pickering at 2021-06-25T05:19:53-04:00 driver: Add test for #17481 Fixed in 25977ab542a30df4ae71d9699d015bcdd1ab7cfb Fixes #17481 - - - - - eb39981a by Matthew Pickering at 2021-06-25T05:19:53-04:00 driver: Add test for T14923 - - - - - 83dce402 by Zubin Duggal at 2021-06-25T05:20:27-04:00 Add regression test for #19921 - - - - - 0bb78838 by Vladislav Zavialov at 2021-06-25T15:41:24-04:00 Suggest similar names when reporting types in terms (#19978) This fixes an error message regression. - - - - - 6cc80766 by Matthew Pickering at 2021-06-25T15:41:58-04:00 driver: Add implicit package dependencies for template-haskell package When TemplateHaskellQuotes is enabled, we also generate programs which mention symbols from the template-haskell module. So that package is added conditionally if the extension is turned on. We should really do the same for other wired-in packages: * base * ghc-bignum * ghc-prim * rts When we link an executable, we must also link against these libraries. In accordance with every other package, these dependencies should be added into the direct dependencies for a module automatically and end up in the interface file to record the fact the object file was created by linking against these packages. Unfortunately it is not so easy to work out when symbols from each of these libraries ends up in the generated program. You might think that `base` would always be used but the `ghc-prim` package doesn't depend on `base`, so you have to be a bit careful and this futher enhancement is left to a future patch. - - - - - 221a104f by GHC GitLab CI at 2021-06-26T22:42:03-04:00 codeGen: Fix header size for array write barriers Previously the code generator's logic for invoking the nonmoving write barrier was inconsistent with the write barrier itself. Namely, the code generator treated the header size argument as being in words whereas the barrier expected bytes. This was the cause of #19715. Fixes #19715. - - - - - 30f233fe by GHC GitLab CI at 2021-06-26T22:42:03-04:00 rts: Eliminate redundant branch Previously we branched unnecessarily on IF_NONMOVING_WRITE_BARRIER_ENABLED on every trip through the array barrier push loop. - - - - - 9b776cbb by sheaf at 2021-06-26T22:42:39-04:00 Re-export UnliftedRep and UnliftedType from GHC.Exts - - - - - b1792fef by Zubin Duggal at 2021-06-27T06:14:36-04:00 user-guide: Improve documentation of NumDecimals - - - - - 3e71874b by Jakob Brünker at 2021-06-27T06:15:11-04:00 Tc: Allow Typeable in quantified constraints Previously, when using Typeable in a quantified constraint, GHC would complain that user-specified instances of Typeable aren't allowed. This was because checking for SigmaCtxt was missing from a check for whether an instance head is a hand-written binding. Fixes #20033 - - - - - d7758da4 by Sebastian Graf at 2021-06-27T14:57:39-04:00 Simplifier: Do Cast W/W for INLINE strong loop-breakers Strong loop-breakers never inline, INLINE pragma or not. Hence they should be treated as if there was no INLINE pragma on them. Also not doing Cast W/W for INLINE strong loop-breakers will trip up Strictness W/W, because it treats them as if there was no INLINE pragma. Subsequently, that will lead to a panic once Strictness W/W will no longer do eta-expansion, as we discovered while implementing !5814. I also renamed to `unfoldingInfo` to `realUnfoldingInfo` and redefined `unfoldingInfo` to zap the unfolding it returns in case of a strong loop-breaker. Now the naming and semantics is symmetrical to `idUnfolding`/`realIdUnfolding`. Now there was no more reason for `hasInlineUnfolding` to operate on `Id`, because the zapping of strong loop-breaker unfoldings moved from `idUnfolding` to `unfoldingInfo`, so I refactored it to take `IdInfo` and call it both from the Simplifier and WorkWrap, making it utterly clear that both checks are equivalent. - - - - - eee498bf by Sebastian Graf at 2021-06-27T14:57:39-04:00 WorkWrap: Remove mkWWargs (#19874) `mkWWargs`'s job was pushing casts inwards and doing eta expansion to match the arity with the number of argument demands we w/w for. Nowadays, we use the Simplifier to eta expand to arity. In fact, in recent years we have even seen the eta expansion done by w/w as harmful, see Note [Don't eta expand in w/w]. If a function hasn't enough manifest lambdas, don't w/w it! What purpose does `mkWWargs` serve in this world? Not a great one, it turns out! I could remove it by pulling some important bits, notably Note [Freshen WW arguments] and Note [Join points and beta-redexes]. Result: We reuse the freshened binder names of the wrapper in the worker where possible (see testuite changes), much nicer! In order to avoid scoping errors due to lambda-bound unfoldings in worker arguments, we zap those unfoldings now. In doing so, we fix #19766. Fixes #19874. - - - - - 37472a10 by Sebastian Graf at 2021-06-27T14:57:39-04:00 WorkWrap: Make mkWWstr and mkWWcpr generate fewer let bindings In https://gitlab.haskell.org/ghc/ghc/-/merge_requests/5814#note_355144, Simon noted that `mkWWstr` and `mkWWcpr` could generate fewer let bindings and be implemented less indirectly by returning the rebuilt expressions directly, e.g. instead of ``` f :: (Int, Int) -> Int f (x, y) = x+y ==> f :: (Int, Int) -> Int f p = case p of (x, y) -> case x of I# x' -> case y of I# y' -> case $wf x' y' of r' -> let r = I# r' -- immediately returned in r f :: Int# -> Int# -> Int# $wf x' y' = let x = I# x' in -- only used in p let y = I# y' in -- only used in p let p = (x, y) in -- only used in the App below case (\(x,y) -> x+y) p of I# r' -> r' ``` we know generate ``` f :: (Int, Int) -> Int f p = case p of (x, y) -> case x of I# x' -> case y of I# y' -> case $wf x' y' of r' -> I# r' -- 1 fewer let f :: Int# -> Int# -> Int# $wf x' y' = case (\(x,y) -> x+y) (I# x, I# y) of I# r' -> -- 3 fewer lets r' ``` Which is much nicer and makes it easier to comprehend the output of worker-wrapper pre-Simplification as well as puts less strain on the Simplifier. I had to drop support for #18983, but we found that it's broken anyway. Simon is working on a patch that provides a bit more justification. - - - - - e69d070b by Sebastian Graf at 2021-06-27T14:57:39-04:00 Add regression test for #17819 The only item left in #17819. Fixes #17819. - - - - - b92479f9 by Sebastian Graf at 2021-06-27T14:57:39-04:00 Inliner: Regard LitRubbish as TrivArg and not ConLike Part of fixing #19766 required the emission of `LitRubbish` as absent filler in places where we used `absentError` before. In WWRec we have the situation that such bindings occur in the argument to functions. With `LitRubbish` we inlined those functions, because 1. The absent binding was regarded as ConLike. So I fixed `exprIsHNFLike` to respond `False` to `LitRubbish`. 2. The other source of inlining was that after inlining such an absent binding, `LitRubbish` itself was regarded `ValueArg` by `interestingArg`, leading to more inlining. It now responds `TrivArg` to `LitRubbish`. Fixes #20035. There's one slight 1.6% ghc/alloc regression left in T15164 that is due to an additional specialisation `$s$cget`. I've no idea why that happens; the Core output before is identical and has the call site that we specialise for. Metric Decrease: WWRec - - - - - 43bbf4b2 by Sebastian Graf at 2021-06-27T14:57:39-04:00 testsuite: Widen acceptance window of T12545 (#19414) In a sequel of #19414, I wrote a script that measures min and max allocation bounds of T12545 based on randomly modifying -dunique-increment. I got a spread of as much as 4.8%. But instead of widening the acceptance window further (to 5%), I committed the script as part of this commit, so that false positive increases can easily be diagnosed by comparing min and max bounds to HEAD. Indeed, for !5814 we have seen T12545 go from -0.3% to 3.3% after a rebase. I made sure that the min and max bounds actually stayed the same. In the future, this kind of check can very easily be done in a matter of a minute. Maybe we should increase the acceptance threshold if we need to check often (leave a comment on #19414 if you had to check), but I've not been bitten by it for half a year, which seems OK. Metric Increase: T12545 - - - - - 469126b3 by Matthew Pickering at 2021-06-27T14:58:14-04:00 Revert "Make reallyUnsafePtrEquality# levity-polymorphic" This reverts commit d1f59540e8b7be96b55ab4b286539a70bc75416c. This commit breaks the build of unordered-containers ``` [3 of 9] Compiling Data.HashMap.Internal.Array ( Data/HashMap/Internal/Array.hs, dist/build/Data/HashMap/Internal/Array.o, dist/build/Data/HashMap/Internal/Array.dyn_o ) *** Parser [Data.HashMap.Internal.Array]: Parser [Data.HashMap.Internal.Array]: alloc=21043544 time=13.621 *** Renamer/typechecker [Data.HashMap.Internal.Array]: Renamer/typechecker [Data.HashMap.Internal.Array]: alloc=151218672 time=187.083 *** Desugar [Data.HashMap.Internal.Array]: ghc: panic! (the 'impossible' happened) GHC version 9.3.20210625: expectJust splitFunTy CallStack (from HasCallStack): error, called at compiler/GHC/Data/Maybe.hs:68:27 in ghc:GHC.Data.Maybe expectJust, called at compiler/GHC/Core/Type.hs:1247:14 in ghc:GHC.Core.Type ``` Revert containers submodule update - - - - - 46c2d0b0 by Peter Trommler at 2021-06-28T10:45:54-04:00 Fix libffi on PowerPC Update submodule libffi-tarballs to upstream commit 4f9e20a. Remove C compiler flags that suppress warnings in the RTS. Those warnings have been fixed by libffi upstream. Fixes #19885 - - - - - d4c43df1 by Zubin Duggal at 2021-06-28T10:46:29-04:00 Update docs for change in parsing behaviour of infix operators like in GHC 9 - - - - - 755cb2b0 by Alfredo Di Napoli at 2021-06-28T16:57:28-04:00 Try to simplify zoo of functions in `Tc.Utils.Monad` This commit tries to untangle the zoo of diagnostic-related functions in `Tc.Utils.Monad` so that we can have the interfaces mentions only `TcRnMessage`s while we push the creation of these messages upstream. It also ports TcRnMessage diagnostics to use the new API, in particular this commit switch to use TcRnMessage in the external interfaces of the diagnostic functions, and port the old SDoc to be wrapped into TcRnUnknownMessage. - - - - - a7f9670e by Ryan Scott at 2021-06-28T16:58:03-04:00 Fix type and strictness signature of forkOn# This is a follow-up to #19992, which fixes the type and strictness signature for `fork#`. The `forkOn#` primop also needs analogous changes, which this patch accomplishes. - - - - - b760c1f7 by Sebastian Graf at 2021-06-29T15:35:29-04:00 Demand: Better representation (#19050) In #19050, we identified several ways in which we could make more illegal states irrepresentable. This patch introduces a few representation changes around `Demand` and `Card` with a better and earlier-failing API exported through pattern synonyms. Specifically, 1. The old enum definition of `Card` led to severely bloated code of operations on it. I switched to a bit vector representation; much nicer overall IMO. See Note [Bit vector representation for Card]. Most of the gripes with the old representation were related to where which kind of `Card` was allowed and the fact that it doesn't make sense for an absent or bottoming demand to carry a `SubDemand` that describes an evaluation context that is never realised. 2. So I refactored the `Demand` representation so that it has two new data constructors for `AbsDmd` and `BotDmd`. The old `(:*)` data constructor becomes a pattern synonym which expands absent demands as needed, so that it still forms a complete match and a versatile builder. The new `Demand` data constructor now carries a `CardNonAbs` and only occurs in a very limited number of internal call sites. 3. Wherever a full-blown `Card` might end up in a `CardNonAbs` field (like that of `D` or `Call`), I assert the consistency. When the smart builder of `(:*)` is called with an absent `Card`, I assert that the `SubDemand` is the same that we would expand to in the matcher. 4. `Poly` now takes a `CardNonOnce` and encodes the previously noticed invariant that we never produce `Poly C_11` or `Poly C_01`. I made sure that we never construct a `Poly` with `C_11` or `C_01`. Fixes #19050. We lose a tiny bit of anal perf overall, probably because the new `Demand` definition can't be unboxed. The biggest loser is WWRec, where allocations go from 16MB to 26MB in DmdAnal, making up for a total increase of (merely) 1.6%. It's all within acceptance thresholds. There are even two ghc/alloc metric decreases. T11545 decreases by *67%*! Metric Decrease: T11545 T18304 - - - - - 4e9f58c7 by sheaf at 2021-06-29T15:36:08-04:00 Use HsExpansion for overloaded list patterns Fixes #14380, #19997 - - - - - 2ce7c515 by Matthew Pickering at 2021-06-29T15:36:42-04:00 ci: Don't allow aarch64-darwin to fail Part way to #20013 - - - - - f79615d2 by Roland Senn at 2021-07-01T03:29:58-04:00 Add testcase for #19460 Avoid an other regression. - - - - - b51b4b97 by Sylvain Henry at 2021-07-01T03:30:36-04:00 Make withException use SDocContext instead of DynFlags - - - - - 6f097a81 by Sylvain Henry at 2021-07-01T03:30:36-04:00 Remove useless .hs-boot - - - - - 6d712150 by Sylvain Henry at 2021-07-01T03:30:36-04:00 Dynflags: introduce DiagOpts Use DiagOpts for diagnostic options instead of directly querying DynFlags (#17957). Surprising performance improvements on CI: T4801(normal) ghc/alloc 313236344.0 306515216.0 -2.1% GOOD T9961(normal) ghc/alloc 384502736.0 380584384.0 -1.0% GOOD ManyAlternatives(normal) ghc/alloc 797356128.0 786644928.0 -1.3% ManyConstructors(normal) ghc/alloc 4389732432.0 4317740880.0 -1.6% T783(normal) ghc/alloc 408142680.0 402812176.0 -1.3% Metric Decrease: T4801 T9961 T783 ManyAlternatives ManyConstructors Bump haddock submodule - - - - - d455c39e by Emily Martins at 2021-07-01T03:31:13-04:00 Unify primary and secondary GHCi prompt Fixes #20042 Signed-off-by: Emily Martins <emily.flakeheart at gmail.com> Signed-off-by: Hécate Moonlight <hecate at glitchbra.in> - - - - - 05ae4772 by Emily Martins at 2021-07-01T03:31:13-04:00 Unify remaining GHCi prompt example Signed-off-by: Emily Martins <emily.flakeheart at gmail.com> - - - - - c22761fa by Moritz Angermann at 2021-07-01T03:31:48-04:00 [ci] don't allow aarch64-linux (ncg) to fail by accepting the current state of metrics (and the NCG is new, so this seems prudent to do), we can require aarch64-linux (ncg) to build without permitting failure. Metric Increase: T13035 T13719 T14697 T1969 T9203 T9872a T9872b T9872c T9872d T9961 WWRec haddock.Cabal haddock.base parsing001 - - - - - 82e6a4d2 by Moritz Angermann at 2021-07-01T03:31:48-04:00 [ci] Separate llvm and NCG test metrics for aarch64-linux - - - - - e8192ae4 by Moritz Angermann at 2021-07-01T03:31:48-04:00 [Parser: Lexer] Fix !6132 clang's cpp injects spaces prior to #!/. - - - - - 66bd5931 by Moritz Angermann at 2021-07-01T03:31:48-04:00 [ci] Enable T6132 across all targets We should have fixed clangs mess now. - - - - - 66834286 by Marco Zocca at 2021-07-01T10:23:52+00:00 float out some docstrings and comment some function parameters - - - - - a3c451be by Roland Senn at 2021-07-01T16:05:21-04:00 Remove redundant test case print036. The test case `print036` was marked `broken` by #9046. Issue #9046 is a duplicate of #12449. However the test case `T12449` contains several test that are similar to those in `print036`. Hence test case `print036` is redundant and can be deleted. - - - - - 6ac9ea86 by Simon Peyton Jones at 2021-07-02T00:27:04-04:00 One-shot changes (#20008) I discovered that GHC.Core.Unify.bindTv was getting arity 2, rather than 3, in one of my builds. In HEAD it does get the right arity, but only because CallArity (just) manages to spot it. In my situation it (just) failed to discover this. Best to make it robust, which this patch does. See Note [INLINE pragmas and (>>)] in GHC.Utils.Monad. There a bunch of other modules that probably should have the same treatment: GHC.CmmToAsm.Reg.Linear.State GHC.Tc.Solver.Monad GHC.Tc.Solver.Rewrite GHC.Utils.Monad.State.Lazy GHC.Utils.Monad.State.Strict but doing so is not part of this patch - - - - - a820f900 by Sylvain Henry at 2021-07-02T00:27:42-04:00 Detect underflow in fromIntegral/Int->Natural rule Fix #20066 - - - - - bb716a93 by Viktor Dukhovni at 2021-07-02T04:28:34-04:00 Fix cut/paste typo foldrM should be foldlM - - - - - 39d665e4 by Moritz Angermann at 2021-07-02T04:29:09-04:00 Revert "Move validate-x86_64-linux-deb9-hadrian back to quick-build" This reverts commit a0622459f1d9a7068e81b8a707ffc63e153444f8. - - - - - c1c98800 by Moritz Angermann at 2021-07-02T04:29:09-04:00 Move aarch64-linux-llvm to nightly This job takes by far the longest time on its own, we now have a NCG. Once we have fast aarch64 machines, we can consider putting this one back. - - - - - 5e30451d by Luite Stegeman at 2021-07-02T23:24:38-04:00 Support unlifted datatypes in GHCi fixes #19628 - - - - - 9b1d9cbf by Sebastian Graf at 2021-07-02T23:25:13-04:00 Arity: Handle shadowing properly In #20070, we noticed that `findRhsArity` copes badly with shadowing. A simple function like `g_123 x_123 = x_123`, where the labmda binder shadows, already regressed badly. Indeed, the whole `arityType` function wasn't thinking about shadowing *at all*. I rectified that and established the invariant that `ae_join` and `am_sigs` should always be disjoint. That entails deleting bindings from `ae_join` whenever we add something to `am_sigs` and vice versa, which would otherwise be a bug in the making. That *should* fix (but I don't want to close it) #20070. - - - - - 4b4c5e43 by Fraser Tweedale at 2021-07-06T13:36:46-04:00 Implement improved "get executable path" query System.Environment.getExecutablePath has some problems: - Some system-specific implementations throw an exception in some scenarios, e.g. when the executable file has been deleted - The Linux implementation succeeds but returns an invalid FilePath when the file has been deleted. - The fallback implementation returns argv[0] which is not necessarily an absolute path, and is subject to manipulation. - The documentation does not explain any of this. Breaking the getExecutablePath API or changing its behaviour is not an appealing direction. So we will provide a new API. There are two facets to the problem of querying the executable path: 1. Does the platform provide a reliable way to do it? This is statically known. 2. If so, is there a valid answer, and what is it? This may vary, even over the runtime of a single process. Accordingly, the type of the new mechanism is: Maybe (IO (Maybe FilePath)) This commit implements this mechanism, defining the query action for FreeBSD, Linux, macOS and Windows. Fixes: #10957 Fixes: #12377 - - - - - a4e742c5 by Fraser Tweedale at 2021-07-06T13:36:46-04:00 Add test for executablePath - - - - - 4002bd1d by Ethan Kiang at 2021-07-06T13:37:24-04:00 Pass '-x c++' and '-std=c++11' to `cc` for cpp files, in Hadrian '-x c++' was found to be required on Darwin Clang 11 and 12. '-std=c++' was found to be needed on Clang 12 but not 11. - - - - - 354ac99d by Sylvain Henry at 2021-07-06T13:38:06-04:00 Use target platform in guessOutputFile - - - - - 17091114 by Edward at 2021-07-06T13:38:42-04:00 Fix issue 20038 - Change 'variable' -> 'variables' - - - - - 6618008b by Andreas Klebinger at 2021-07-06T21:17:37+00:00 Fix #19889 - Invalid BMI2 instructions generated. When arguments are 8 *or 16* bits wide, then truncate before/after and use the 32bit operation. - - - - - 421beb3f by Matthew Pickering at 2021-07-07T11:56:36-04:00 driver: Convert runPipeline to use a free monad This patch converts the runPipeline function to be implemented in terms of a free monad rather than the previous CompPipeline. The advantages of this are three-fold: 1. Different parts of the pipeline can return different results, the limits of runPipeline were being pushed already by !5555, this opens up futher fine-grainedism of the pipeline. 2. The same mechanism can be extended to build-plan at the module level so the whole build plan can be expressed in terms of one computation which can then be treated uniformly. 3. The pipeline monad can now be interpreted in different ways, for example, you may want to interpret the `TPhase` action into the monad for your own build system (such as shake). That bit will probably require a bit more work, but this is a step in the right directin. There are a few more modules containing useful functions for interacting with the pipelines. * GHC.Driver.Pipeline: Functions for building pipelines at a high-level * GHC.Driver.Pipeline.Execute: Functions for providing the default interpretation of TPhase, in terms of normal IO. * GHC.Driver.Pipeline.Phases: The home for TPhase, the typed phase data type which dictates what the phases are. * GHC.Driver.Pipeline.Monad: Definitions to do with the TPipelineClass and MonadUse class. Hooks consumers may notice the type of the `phaseHook` has got slightly more restrictive, you can now no longer control the continuation of the pipeline by returning the next phase to execute but only override individual phases. If this is a problem then please open an issue and we will work out a solution. ------------------------- Metric Decrease: T4029 ------------------------- - - - - - 5a31abe3 by Matthew Pickering at 2021-07-07T11:56:36-04:00 driver: Add test for #12983 This test has worked since 8.10.2 at least but was recently broken and is now working again after this patch. Closes #12983 - - - - - 56eb57a6 by Alfredo Di Napoli at 2021-07-08T08:13:23+02:00 Rename getErrorMessages and getMessages function in parser code This commit renames the `getErrorMessages` and `getMessages` function in the parser code to `getPsErrorMessages` and `getPsMessages`, to avoid import conflicts, as we have already `getErrorMessages` and `getMessages` defined in `GHC.Types.Error`. Fixes #19920. Update haddock submodule - - - - - 82284ba1 by Matthew Pickering at 2021-07-09T08:46:09-04:00 Remove reqlib from cgrun025 test - - - - - bc38286c by Matthew Pickering at 2021-07-09T08:46:09-04:00 Make throwto002 a normal (not reqlib) test - - - - - 573012c7 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add the TcRnShadowedName constructor to TcRnMessage This commit adds the TcRnShadowedName to the TcRnMessage type and it uses it in GHC.Rename.Utils. - - - - - 55872423 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add the TcRnDuplicateWarningDecls to TcRnMessage - - - - - 1e805517 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnSimplifierTooManyIterations to TcRnMessage - - - - - bc2c00dd by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnIllegalPatSynDecl to TcRnMessage - - - - - 52353476 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnEmptyRecordUpdate to TcRnMessage - - - - - f0a02dcc by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnIllegalFieldPunning to TcRnMessage - - - - - 5193bd06 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnIllegalWildCardsInRecord to TcRnMessage - - - - - e17850c4 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnDuplicateFieldName to TcRnMessage - - - - - 6b4f3a99 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnIllegalViewPattern to TcRnMessage - - - - - 8d28b481 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnCharLiteralOutOfRange to TcRnMessage - - - - - 64e20521 by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Remove redundant patSigErr - - - - - 60fabd7e by Alfredo Di Napoli at 2021-07-09T08:46:44-04:00 Add TcRnIllegalWildcardsInConstructor to TcRnMessage - - - - - 2d4cdfda by Sylvain Henry at 2021-07-09T08:47:22-04:00 Avoid unsafePerformIO for getProgName getProgName was used to append the name of the program (e.g. "ghc") to printed error messages in the Show instance of GhcException. It doesn't belong here as GHCi and GHC API users may want to override this behavior by setting a different error handler. So we now call it in the defaultErrorHandler instead. - - - - - 901f0e1b by sheaf at 2021-07-10T13:29:03+02:00 Don't return unitExpr in dsWhenNoErrs - fixes #18149 and #14765 dsWhenNoErrs now returns "runtimeError @ty" when disallowed representation polymorphism is detected, where ty is the type of the result CoreExpr. "ty" is passed as an additional argument to dsWhenNoErrs, and is used only in the case of such an error. The calls to dsWhenNoErrs must now compute the type of the CoreExpr they are trying to build, so that an error of the right type can be used in case of a representation polymorphism failure. - - - - - c38bce73 by Matthew Pickering at 2021-07-10T19:59:34-04:00 ci: Copy the cache from inside the nix-shell where $HOME is different on darwin Hopefully fixes the flaky CI failures we have seen recently. Co-authored-by: Moritz Angerman <moritz.angermann at gmail.com> - - - - - a181313e by Alfredo Di Napoli at 2021-07-12T14:19:22+02:00 Add proper GHCHints for most PsMessage constructors This commit adds proper hints to most diagnostic types in the `GHC.Parser.Errors.Types` module. By "proper" we mean that previous to this commit the hints were bundled together with the diagnostic message, whereas now we moved most of them as proper `[GhcHint]` in the implementation of `diagnosticHints`. More specifically, this is the list of constructors which now has proper hints: * PsErrIllegalBangPattern * PsWarnOperatorWhitespaceExtConflict * PsErrLambdaCase * PsErrIllegalPatSynExport * PsWarnOperatorWhitespace * PsErrMultiWayIf * PsErrIllegalQualifiedDo * PsErrNumUnderscores * PsErrLinearFunction * PsErrIllegalTraditionalRecordSyntax * PsErrIllegalExplicitNamespace * PsErrOverloadedRecordUpdateNotEnabled * PsErrIllegalDataTypeContext * PsErrSemiColonsInCondExpr * PsErrSemiColonsInCondCmd * PsWarnStarIsType * PsWarnImportPreQualified * PsErrImportPostQualified * PsErrEmptyDoubleQuotes * PsErrIllegalRoleName * PsWarnStarBinder For some reason, this patch increases the peak_megabyte_allocated of the T11545 test to 90 (from a baseline of 80) but that particular test doesn't emit any parsing diagnostic or hint and the metric increase happens only for the `aarch64-linux-deb10`. Metric Increase: T11545 - - - - - aef7d513 by Matthew Pickering at 2021-07-13T15:16:19-04:00 driver: Fix interaction of -Wunused-packages and reexported-modules Spurious warnings were previously emitted if an import came from a reexport due to how -Wunused-packages were implemented. Removing the dependency would cause compilation to fail. The fix is to reimplement the warning a bit more directly, by searching for which package each import comes from using the normal module finding functions rather than consulting the EPS. This has the advantage that the check could be performed at any time after downsweep rather than also relying on a populated EPS. Fixes #19518 and #19777 - - - - - bb8e0df8 by Adrien at 2021-07-13T15:16:56-04:00 Added a hopefully clarificatory sentence about the notion of "atomicity" presupposed in the documentation on MVar. - - - - - 99921593 by Zubin Duggal at 2021-07-13T20:45:44+00:00 Don't panic on 'no skolem info' and add failing tests - - - - - de98a0ce by Sylvain Henry at 2021-07-15T23:29:09-04:00 Additional constant-folding rule for binary AND/OR Add a constant folding rule allowing the subsumption of an application if the same argument is applied twice, e.g. (v .&. 0xFF) .&. 0xFF ~~> v .&. 0xFF (v .|. 0xFF) .|. 0xFF ~~> v .|. 0xFF - - - - - 41d6cfc4 by Sylvain Henry at 2021-07-15T23:29:09-04:00 Add Word64#/Int64# primops Word64#/Int64# are only used on 32-bit architectures. Before this patch, operations on these types were directly using the FFI. Now we use real primops that are then lowered into ccalls. The advantage of doing this is that we can now perform constant folding on Word64#/Int64# (#19024). Most of this work was done by John Ericson in !3658. However this patch doesn't go as far as e.g. changing Word64 to always be using Word64#. Noticeable performance improvements T9203(normal) run/alloc 89870808.0 66662456.0 -25.8% GOOD haddock.Cabal(normal) run/alloc 14215777340.8 12780374172.0 -10.1% GOOD haddock.base(normal) run/alloc 15420020877.6 13643834480.0 -11.5% GOOD Metric Decrease: T9203 haddock.Cabal haddock.base - - - - - 5b187575 by Simon Peyton Jones at 2021-07-19T10:59:38+01:00 Better sharing of join points (#19996) This patch, provoked by regressions in the text package (#19557), improves sharing of join points. This also fixes the terrible behaviour in #20049. See Note [Duplicating join points] in GHC.Core.Opt.Simplify. * In the StrictArg case of mkDupableContWithDmds, don't use Plan A for data constructors * In postInlineUnconditionally, don't inline JoinIds Avoids inlining join $j x = Just x in case blah of A -> $j x1 B -> $j x2 C -> $j x3 * In mkDupableStrictBind and mkDupableStrictAlt, create join points (much) more often: exprIsTrivial rather than exprIsDupable. This may be much, but we'll see. Metric Decrease: T12545 T13253-spj T13719 T18140 T18282 T18304 T18698a T18698b Metric Increase: T16577 T18923 T9961 - - - - - e5a4cfa5 by Sylvain Henry at 2021-07-19T19:36:37-04:00 Bignum: don't allocate in bignat_mul (#20028) We allocated the recursively entered `mul` helper function because it captures some args. - - - - - 952ba18e by Matthew Pickering at 2021-07-19T19:37:12-04:00 th: Weaken return type of myCoreToStgExpr The previous code assumed properties of the CoreToStg translation, namely that a core let expression which be translated to a single non-recursive top-level STG binding. This assumption was false, as evidenced by #20060. The consequence of this was the need to modify the call sites of `myCoreToStgExpr`, the main one being in hscCompileCoreExpr', which the meant we had to use byteCodeGen instead of stgExprToBCOs to convert the returned value to bytecode. I removed the `stgExprToBCOs` function as it is no longer used in the compiler. There is still some partiallity with this patch (the lookup in hscCompileCoreExpr') but this should be more robust that before. Fixes #20060 - - - - - 3e8b39ea by Alfredo Di Napoli at 2021-07-19T19:37:47-04:00 Rename RecordPuns to NamedFieldPuns in LangExt.Extension This commit renames the `RecordPuns` type constructor inside `GHC.LanguageExtensions.Type.hs` to `NamedFieldPuns`. The rationale is that the `RecordPuns` language extension was deprecated a long time ago, but it was still present in the AST, introducing an annoying mismatch between what GHC suggested (i.e. "use NamedFieldPuns") and what that translated into in terms of Haskell types. - - - - - 535123e4 by Simon Peyton Jones at 2021-07-19T19:38:21-04:00 Don't duplicate constructors in the simplifier Ticket #20125 showed that the Simplifier could sometimes duplicate a constructor binding. CSE would often eliminate it later, but doing it in the first place was utterly wrong. See Note [Do not duplicate constructor applications] in Simplify.hs I also added a short-cut to Simplify.simplNonRecX for the case when the RHS is trivial. I don't think this will change anything, just make the compiler run a tiny bit faster. - - - - - 58b960d2 by Sylvain Henry at 2021-07-19T19:38:59-04:00 Make TmpFs independent of DynFlags This is small step towards #19877. We want to make the Loader/Linker interface more abstract to be easily reused (i.e. don't pass it DynFlags) but the system linker uses TmpFs which required a DynFlags value to get its temp directory. We explicitly pass the temp directory now. Similarly TmpFs was consulting the DynFlags to decide whether to clean or: this is now done by the caller in the driver code. - - - - - d706fd04 by Matthew Pickering at 2021-07-20T09:22:46+01:00 hadrian: Update docs targets documentation [skip ci] The README had got a little out of sync with the current state of affairs. - - - - - 9eb1641e by Matthew Pickering at 2021-07-21T02:45:39-04:00 driver: Fix recompilation for modules importing GHC.Prim The GHC.Prim module is quite special as there is no interface file, therefore it doesn't appear in ms_textual_imports, but the ghc-prim package does appear in the direct package dependencies. This confused the recompilation checking which couldn't find any modules from ghc-prim and concluded that the package was no longer a dependency. The fix is to keep track of whether GHC.Prim is imported separately in the relevant places. Fixes #20084 - - - - - 06d1ca85 by Alfredo Di Napoli at 2021-07-21T02:46:13-04:00 Refactor SuggestExtension constructor in GhcHint This commit refactors the SuggestExtension type constructor of the GhcHint to be more powerful and flexible. In particular, we can now embed extra user information (essentially "sugar") to help clarifying the suggestion. This makes the following possible: Suggested fix: Perhaps you intended to use GADTs or a similar language extension to enable syntax: data T where We can still give to IDEs and tools a `LangExt.Extension` they can use, but in the pretty-printed message we can tell the user a bit more on why such extension is needed. On top of that, we now have the ability to express conjuctions and disjunctons, for those cases where GHC suggests to enable "X or Y" and for the cases where we need "X and Y". - - - - - 5b157eb2 by Fendor at 2021-07-21T02:46:50-04:00 Use Ways API instead of Set specific functions - - - - - 10124b16 by Mario Blažević at 2021-07-21T02:47:25-04:00 template-haskell: Add support for default declarations Fixes #19373 - - - - - e8f7734d by John Ericson at 2021-07-21T22:51:41+00:00 Fix #19931 The issue was the renderer for x86 addressing modes assumes native size registers, but we were passing in a possibly-smaller index in conjunction with a native-sized base pointer. The easist thing to do is just extend the register first. I also changed the other NGC backends implementing jump tables accordingly. On one hand, I think PowerPC and Sparc don't have the small sub-registers anyways so there is less to worry about. On the other hand, to the extent that's true the zero extension can become a no-op. I should give credit where it's due: @hsyl20 really did all the work for me in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4717#note_355874, but I was daft and missed the "Oops" and so ended up spending a silly amount of time putting it all back together myself. The unregisterised backend change is a bit different, because here we are translating the actual case not a jump table, and the fix is to handle right-sized literals not addressing modes. But it makes sense to include here too because it's the same change in the subsequent commit that exposes both bugs. - - - - - 024020c3 by John Ericson at 2021-07-21T22:52:52+00:00 Use fix-sized equality primops for fixed size boxed types These are the last to be converted. - - - - - fd7e272e by Sylvain Henry at 2021-07-23T21:05:41-04:00 Perf: fix strictness in OccurAnal This patch enhances OccurAnal perf by using a dedicated WithUsageDetails datatype instead of a tuple (similarly to what has been done in demand-analysis) with strict fields. OccEnv is also passed strictly with more strict fields as it improves results even more. T9198 flukes isn't reproducible locally (cf https://gitlab.haskell.org/ghc/ghc/-/merge_requests/5667#note_364358) Metric Decrease: ManyConstructors T10421 T12150 T12425 T12707 T13056 T13253 T13253-spj T15164 T16577 T18282 T18698a T18698b T1969 T4801 T5642 T9020 T9233 T9630 T9675 T9961 WWRec T12227 T13035 T18304 T6048 T12234 T783 T20049 Metric Increase: T9198 - - - - - ba302877 by sheaf at 2021-07-23T21:06:18-04:00 Add nontrivial type-checking plugin tests Three new tests for type-checking plugins: - TcPlugin_Nullary, solving a nullary class constraint - TcPlugin_Args, providing evidence for a (unary) class constraint using arguments supplied to the plugin - TcPlugin_TyFam, solving an equality constraint to rewrite a type-family application More extensive descriptions of the plugins can be found in their respective defining modules. - - - - - 5d670abd by sheaf at 2021-07-23T21:06:56-04:00 Generalise reallyUnsafePtrEquality# and use it fixes #9192 and #17126 updates containers submodule 1. Changes the type of the primop `reallyUnsafePtrEquality#` to the most general version possible (heterogeneous as well as levity-polymorphic): > reallyUnsafePtrEquality# > :: forall {l :: Levity} {k :: Levity} > (a :: TYPE (BoxedRep l)) (b :: TYPE (BoxedRep k)) > . a -> b -> Int# 2. Adds a new internal module, `GHC.Ext.PtrEq`, which contains pointer equality operations that are now subsumed by `reallyUnsafePtrEquality#`. These functions are then re-exported by `GHC.Exts` (so that no function goes missing from the export list of `GHC.Exts`, which is user-facing). More specifically, `GHC.Ext.PtrEq` defines: - A new function: * reallyUnsafePtrEquality :: forall (a :: Type). a -> a -> Int# - Library definitions of ex-primops: * `sameMutableArray#` * `sameSmallMutableArray` * `sameMutableByteArray#` * `sameMutableArrayArray#` * `sameMutVar#` * `sameTVar#` * `sameMVar#` * `sameIOPort#` * `eqStableName#` - New functions for comparing non-mutable arrays: * `sameArray#` * `sameSmallArray#` * `sameByteArray#` * `sameArrayArray#` These were requested in #9192. Generally speaking, existing libraries that use `reallyUnsafePtrEquality#` will continue to work with the new, levity-polymorphic version. But not all! Some (`containers`, `unordered-containers`, `dependent-map`) contain the following: > unsafeCoerce# reallyUnsafePtrEquality# a b If we make `reallyUnsafePtrEquality#` levity-polymorphic, this code fails the current GHC representation-polymorphism checks. We agreed that the right solution here is to modify the library; in this case by deleting the call to `unsafeCoerce#`, since `reallyUnsafePtrEquality#` is now type-heterogeneous too. - - - - - 4beb12db by Matthew Pickering at 2021-07-23T21:07:31-04:00 Add test for #13157 Closes #13157 - - - - - 509445b5 by Matthew Pickering at 2021-07-23T21:08:05-04:00 Check the buffer size *before* calling the continuation in withEncodedCString This fixes a very subtle bug in withEncodedCString where a reference would be kept to the whole continuation until the continuation had finished executing. This was because the call to tryFillBufferAndCall could fail, if the buffer was already full and so the `go` helper would be recursively called on failure which necessitated keeping a reference to `act`. The failure could only happen during the initial checking phase of the function but not during the call to the continuation. Therefore the fix is to first perform the size check, potentially recursively and then finally calling tail calling the continuation. In the real world, this broke writing lazy bytestrings because a reference to the head of the bytestring would be retained in the continuation until the whole string had been written to a file. Fixes #20107 - - - - - 6c79981e by Fendor at 2021-07-23T21:08:42-04:00 Introduce FinderLocations for decoupling Finder from DynFlags - - - - - b26a7065 by Matthew Pickering at 2021-07-23T21:09:17-04:00 Fix a few retainer leaks of TcGblEnv Methodology: Create a -hi profile and then search for TcGblEnv then use ghc-debug to work out why they are being retained and remove the reason. Retaining TcGblEnv is dangerous because it contains pointers to things such as a TypeEnv which is updated throughout compilation. I found two places which were retaining a TcGblEnv unecessarily. Also fix a few places where an OccName was retaining an Id. - - - - - efaad7ad by Matthew Pickering at 2021-07-23T21:09:17-04:00 Stop ug_boring_info retaining a chain of old CoreExpr It was noticed in #20134 that each simplifier iteration used an increasing amount of memory and that a certain portion of memory was not released until the simplfier had completely finished. I profiled the program using `-hi` profiling and observed that there was a thunk arising in the computation of `ug_boring_ok`. On each iteration `ug_boring_ok` would be updated, but not forced, which would leave a thunk in the shape of ug_boring_ok = inlineBoringOk expr0 || inlineBoringOk expr2 || inlineBoringOk expr3 || ... which would retain all previous `expr` until `ug_boring_ok` was forced or discarded. Forcing this accumulator eagerly results in a flat profile over multiple simplifier runs. This reduces the maximum residency when compiling the test in #20134 from 2GB to 1.3G. ------------------------- Metric Decrease: T11545 ------------------------- - - - - - b6434ed3 by Ben Gamari at 2021-07-23T21:09:52-04:00 Cmm.Opt: Fix type of shift amount in constant folding Previously the `MO_S_Quot` constant folding rule would incorrectly pass the shift amount of the same width as the shifted value. However, the machop's type expects the shift amount to be a Word. Fixes #20142. - - - - - a31aa271 by Ben Gamari at 2021-07-23T21:09:52-04:00 testsuite: Add test for #20142 - - - - - 3801b35a by Moritz Angermann at 2021-07-25T09:41:46-04:00 [CI] absolutely no caching on darwin We failed at doing caching properly, so for now we won't do any caching at all. This is not safe in a concurrent setting, however all our darwin builders run with concurrency 1, and -j8, on 8 core m1 mac minis. - - - - - 1832676a by Moritz Angermann at 2021-07-25T09:41:46-04:00 [rts] Untag bq->bh prior to reading the info table In `checkBlockingQueues` we must always untag the `bh` field of an `StgBlockingQueue`. While at first glance it might seem a sensible assumption that `bh` will always be a blackhole and therefore never be tagged, the GC could shortcut the indirection and put a tagged pointer into the indirection. This blew up on aarch64-darwin with a misaligned access. `bh` pointed to an address that always ended in 0xa. On architectures that are a little less strict about alignment, this would have read a garbage info table pointer, which very, very unlikely would have been equal to `stg_BLACKHOLE_info` and therefore things accidentally worked. However, on AArch64, the read of the info table pointer resulted in a SIGBUS due to misaligned read. Fixes #20093. - - - - - 5b39a107 by Ben Gamari at 2021-07-25T17:30:52+00:00 hadrian: Don't add empty -I arguments Previously hadrian would add a -I$FfiIncludeDir flag to compiler invocations even if FfiIncludeDir was null, resulting in compilation errors. - - - - - 5f3991c7 by Sylvain Henry at 2021-07-26T04:55:03-04:00 RTS: try to fix timer races * Pthread based timer was initialized started while some other parts of the RTS assume it is initialized stopped, e.g. in hs_init_ghc: /* Start the "ticker" and profiling timer but don't start until the * scheduler is up. However, the ticker itself needs to be initialized * before the scheduler to ensure that the ticker mutex is initialized as * moreCapabilities will attempt to acquire it. */ * after a fork, don't start the timer before the IOManager is initialized: the timer handler (handle_tick) might call wakeUpRts to perform an idle GC, which calls wakeupIOManager/ioManagerWakeup Found while debugging #18033/#20132 but I couldn't confirm if it fixes them. - - - - - 0462750f by Fendor at 2021-07-27T04:46:42-04:00 Remove unused module GHC.Rename.Doc - - - - - 51ff0365 by Ben Gamari at 2021-07-27T04:47:16-04:00 rename: Avoid unnecessary map lookup Previously the -Wcompat-unqualified-imports warning would first check whether an import is of a covered module, incurring an map lookup, before checking the simple boolean predicate of whether it is qualified. This is more expensive than strictly necessary (although at the moment the warning is unused, so this will make little difference). - - - - - 167a01f7 by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Document CPP guards - - - - - 246f08ac by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Move libffi interfaces all to Adjustor Previously the libffi Adjustor implementation would use allocateExec to create executable mappings. However, allocateExec is also used elsewhere in GHC to allocate things other than ffi_closure, which is a use-case which libffi does not support. - - - - - 2ce48fe9 by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Break up adjustor logic - - - - - 3b07d827 by Ben Gamari at 2021-07-27T04:47:51-04:00 rts/adjustor: Drop redundant commments - - - - - 0e875c3f by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Introduce and use ExecPage abstraction Here we introduce a very thin abstraction for allocating, filling, and freezing executable pages to replace allocateExec. - - - - - f6e366c0 by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Drop allocateExec and friends All uses of these now use ExecPage. - - - - - dd3c9602 by Ben Gamari at 2021-07-27T04:47:51-04:00 hadrian: Always specify flag values explicitly Previously we would often allow cabal flags to default, making it harder than necessary to reason about the effective build configuration. - - - - - 63184a71 by Ben Gamari at 2021-07-27T04:47:51-04:00 rts: Don't declare libCffi as bundled when using system libffi Previously the rts's cabal file would claim that it bundled libffi, even if we are using the system's libffi. Fixes #19869. - - - - - 8c5c27f1 by Andreas Klebinger at 2021-07-27T04:48:26-04:00 Rename itimer to ticker in rts/posix for consistency. - - - - - 5457a124 by Andreas Klebinger at 2021-07-27T04:48:26-04:00 Use pthread if available on linux - - - - - b19f1a6a by Ben Gamari at 2021-07-27T04:49:00-04:00 rts/OSThreads: Ensure that we catch failures from pthread_mutex_lock Previously we would only catch EDEADLK errors. - - - - - 0090517a by Ben Gamari at 2021-07-27T04:49:00-04:00 rts/OSThreads: Improve error handling consistency Previously we relied on the caller to check the return value from broadcastCondition and friends, most of whom neglected to do so. Given that these functions should not fail anyways, I've opted to drop the return value entirely and rather move the result check into the OSThreads functions. This slightly changes the semantics of timedWaitCondition which now returns false only in the case of timeout, rather than any error as previously done. - - - - - 229b4e51 by Ben Gamari at 2021-07-27T04:49:36-04:00 rts: Fix inconsistent signatures for collect_pointers Fixes #20160. - - - - - c2893361 by Fraser Tweedale at 2021-07-27T04:50:13-04:00 doc: fix copy/paste error The `divInt#` implementation note has heading: See Note [divInt# implementation] This seems to be a copy/paste mistake. Remove "See" from the heading. - - - - - 4816d9b7 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: fix #18477, improve syntax & add if-else checks for test outcomes/validation paths ShellCheck(https://github.com/koalaman/shellcheck/wiki) has been used to check the script. - - - - - 575f1f2f by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: add flags using Hadrian's user settings for ignoring changes in performance tests - - - - - 421110b5 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: add a debug flag (in both Hadrian and legacy Make) for running tests - - - - - 9d8cb93e by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: update quick-validate flavour for validation with --fast - - - - - 07696269 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: change test ghc based on BINDIST value (YES/NO) - - - - - 83a88988 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: run stage1 tests using stage1 compiler when BINSTIST is false - - - - - 64b6bc23 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: check both stage1, stage2 test failures for deciding success of entire test run - - - - - 74b79191 by Alina Banerjee at 2021-07-27T12:01:15-04:00 validate: Add note for BINDIST variable, GitLab validation; clean up comments - - - - - 888eadb9 by Matthew Pickering at 2021-07-27T12:01:51-04:00 packaging: Be more precise about which executables to copy and wrappers to create Exes ---- Before: The whole bin/ folder was copied which could contain random old/stale/testsuite executables After: Be precise Wrappers -------- Before: Wrappers were created for everything in the bin folder, including internal executables such as "unlit" After: Only create wrappers for the specific things which we want to include in the user's path. This makes the hadrian bindists match up more closely with the make bindists. - - - - - e4c25261 by Matthew Pickering at 2021-07-27T12:01:51-04:00 packaging: Give ghc-pkg the same version as ProjectVersion - - - - - 8e43dc90 by Matthew Pickering at 2021-07-27T12:01:51-04:00 hadrian: Update hsc2hs wrapper to match current master - - - - - 172fd5d1 by Matthew Pickering at 2021-07-27T12:01:51-04:00 hadrian: Remove special haddock copying rule - - - - - f481c189 by Matthew Pickering at 2021-07-27T12:01:51-04:00 packaging: Create both versioned and unversioned executables Before we would just copy the unversioned executable into the bindist. Now the actual executable is copied into the bindist and a version suffix is added. Then a wrapper or symlink is added which points to the versioned executable. Fixes #20074 - - - - - acc47bd2 by Matthew Pickering at 2021-07-27T12:01:51-04:00 packaging: Add note about wrappers - - - - - 5412730e by Matthew Pickering at 2021-07-27T12:01:51-04:00 packaging: Don't include configure scripts in windows bindist Fixes #19868 - - - - - 22a16b0f by Matthew Pickering at 2021-07-27T12:01:51-04:00 hadrian: Install windows bindist by copying in test_hadrian - - - - - 45f05554 by Matthew Pickering at 2021-07-27T12:01:51-04:00 hadrian: Add exe suffix to executables in testsuite - - - - - 957fe359 by Matthew Pickering at 2021-07-27T12:01:51-04:00 hadrian: Call ghc-pkg recache after copying package database into bindist The package.cache needs to have a later mod-time than all of the .conf files. This invariant can be destroyed by `cp -r` and so we run `ghc-pkg recache` to ensure the package database which is distributed is consistent. If you are installing a relocatable bindist, for example, on windows, you should preserve mtimes by using cp -a or run ghc-pkg recache after installing. - - - - - 7b0ceafb by Matthew Pickering at 2021-07-27T12:01:51-04:00 testsuite: Add more debug output on failure to call ghc-pkg - - - - - 0c4a0c3b by Simon Peyton Jones at 2021-07-27T12:02:25-04:00 Make CallStacks work better with RebindableSyntax As #19918 pointed out, the CallStack mechanism didn't work well with RebindableSyntax. This patch improves matters. See GHC.Tc.Types.Evidence Note [Overview of implicit CallStacks] * New predicate isPushCallStackOrigin distinguishes when a CallStack constraint should be solved "directly" or by pushing an item on the stack. * The constructor EvCsPushCall now has a FastString, which can describe not only a function call site, but also things like "the literal 42" or "an if-then-else expression". * I also fixed #20126 thus: exprCtOrigin (HsIf {}) = IfThenElseOrigin (Previously it was "can't happen".) - - - - - 6d2846f7 by Simon Peyton Jones at 2021-07-27T12:02:25-04:00 Eta expand through CallStacks This patch fixes #20103, by treating HasCallStack constraints as cheap when eta-expanding. See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity - - - - - 9bf8d530 by Simon Peyton Jones at 2021-07-27T12:03:00-04:00 Eliminate unnecessary unsafeEqualityProof This patch addresses #20143, which wants to discard unused calls to unsafeEqualityProof. There are two parts: * In exprOkForSideEffects, we want to know that unsafeEqualityProof indeed terminates, without any exceptions etc * But we can only discard the case if we know that the coercion variable is not used, which means we have to gather accurate occurrence info for CoVars. Previously OccurAnal only did a half hearted job of doing so; this patch finishes the job. See Note [Gather occurrences of coercion variables] in OccurAnal. Because the occurrence analyser does more work, there is a small compile-time cost but it's pretty small. The compiler perf tests are usually 0.0% but occasionally up to 0.3% increase. I'm just going to accept this -- gathering accurate occurrence information really seems like the Right Thing to do. There is an increase in `compile_time/peak_megabytes_allocated`, for T11545, or around 14%; but I can't reproduce it on my machine (it's the same before and after), and the peak-usage stats are vulnerable to when exactly the GC takes place, so I'm just going to accept it. Metric Increase: T11545 - - - - - cca08c2c by Krzysztof Gogolewski at 2021-07-27T12:03:35-04:00 Parser: suggest TemplateHaskell on $$(...) (#20157) - - - - - 20b352eb by Andreas Abel at 2021-07-27T12:04:12-04:00 Doc: tabs to spaces - - - - - ebcdf3fa by Andreas Abel at 2021-07-27T12:04:12-04:00 Doc: warnings: since: remove minor version number for uniformity New warnings are only released in major versions, it seems. One way or the other, a .1 minor version can always be dropped. - - - - - 0b403319 by Andreas Abel at 2021-07-27T12:04:12-04:00 Issue #18087: :since: for warnings of ghc 6/7/8 Added :since: fields to users_guide on warning, for warnings introduced starting GHC 6.0. The data was extracted from the HTML docs on warnings, see https://gitlab.haskell.org/ghc/ghc/-/issues/18087 and partially verified by consulting the change logs. - - - - - f27dba8b by Andreas Abel at 2021-07-27T12:04:12-04:00 Re #18087 !6238 Empty line in front of :since: Ack. @monoidal - - - - - c7c0964c by Krzysztof Gogolewski at 2021-07-27T21:35:17-04:00 Simplify FFI code Remains of the dotnet FFI, see a7d8f43718 and 1fede4bc95 - - - - - 97e0837d by Krzysztof Gogolewski at 2021-07-27T21:35:17-04:00 Remove some unused names The comment about 'parError' was obsolete. - - - - - cab890f7 by Krzysztof Gogolewski at 2021-07-27T21:35:17-04:00 Add a regression test for #17697 - - - - - 9da20e3d by Krzysztof Gogolewski at 2021-07-27T21:35:17-04:00 Don't abort on representation polymorphism check This is reverting a change introduced in linear types commit 40fa237e1da. Previously, we had to abort early, but thanks to later changes, this is no longer needed. There's no test, but the behavior should be better. The plan is to remove levity polymorphism checking in the desugarer anyway. - - - - - cddafcf6 by Sylvain Henry at 2021-07-27T21:35:55-04:00 PIC: test for cross-module references - - - - - 323473e8 by Sylvain Henry at 2021-07-28T06:16:58-04:00 Hadrian: disable profiled RTS with no_profiled_libs flavour transformer Hadrian uses the RTS ways to determine which iserv programs to embed into bindist. But profiled iserv program (and any other code) can't be built without profiling libs and Hadrian fails. So we disable the profiling RTS way with the no_profiled_libs flavour transformer. - - - - - 10678945 by Ben Gamari at 2021-07-28T06:17:32-04:00 rts: Don't rely on configuration when CLEANING=YES The make build system doesn't source config.mk when CLEANING=YES, consequently we previously failed to identify an appropriate adjustor implementation to use during cleaning. Fixes #20166. - - - - - f3256769 by Krzysztof Gogolewski at 2021-07-28T13:18:31-04:00 Docs: use :default: and :ghc-ticket: - - - - - dabe6113 by Krzysztof Gogolewski at 2021-07-28T13:18:31-04:00 Document DerivingVia unsafety (#19786) - - - - - 2625d48e by Krzysztof Gogolewski at 2021-07-28T13:18:31-04:00 Improve docs of bang patterns (#19068) - - - - - a57e4a97 by Krzysztof Gogolewski at 2021-07-28T13:18:31-04:00 Functor docs: link to free theorem explanation (#19300) - - - - - d43a9029 by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Fix smallEnoughToInline I noticed that smallEnoughToInline said "no" to UnfWhen guidance, which seems quite wrong -- those functions are particularly small. - - - - - 4e4ca28c by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Print out module name in "bailing out" message - - - - - 9dbab4fd by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Improve postInlineUnconditionally See Note [Use occ-anald RHS in postInlineUnconditionally]. This explains how to eliminate an extra round of simplification, which can happen if postInlineUnconditionally uses a RHS that is no occurrence-analysed. This opportunity has been there for ages; I discovered it when looking at a compile-time perf regression that happened because the opportunity wasn't exploited. - - - - - 25ca0b5a by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Extend the in-scope set to silence substExpr warnings substExpr warns if it finds a LocalId that isn't in the in-scope set. This patch extends the in-scope set to silence the warnings. (It has no effect on behaviour.) - - - - - a67e6814 by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 White space, spelling, and a tiny refactor No change in behaviour - - - - - 05f54bb4 by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Make the occurrence analyser a bit stricter occAnalArgs and occAnalApp are very heavily used functions, so it pays to make them rather strict: fewer thunks constructed. All these thunks are ultimately evaluated anyway. This patch gives a welcome reduction compile time allocation of around 0.5% across the board. For T9961 it's a 2.2% reduction. Metric Decrease: T9961 - - - - - 2567d13b by Simon Peyton Jones at 2021-07-28T13:19:06-04:00 Inline less logging code When eyeballing calls of GHC.Core.Opt.Simplify.Monad.traceSmpl, I saw that lots of cold-path logging code was getting inlined into the main Simplifier module. So in GHC.Utils.Logger I added a NOINLINE on logDumpFile'. For logging, the "hot" path, up to and including the conditional, should be inlined, but after that we should inline as little as possible, to reduce code size in the caller. - - - - - a199d653 by Simon Peyton Jones at 2021-07-28T13:19:40-04:00 Simplify and improve the eta expansion mechanism Previously the eta-expansion would return lambdas interspersed with casts; now the cast is just pushed to the outside: #20153. This actually simplifies the code. I also improved mkNthCo to account for SymCo, so that mkNthCo n (SymCo (TyConAppCo tc cos)) would work well. - - - - - 299b7436 by Simon Peyton Jones at 2021-07-28T13:19:41-04:00 Improve performance of eta expansion Eta expansion was taking ages on T18223. This patch * Aggressively squash reflexive casts in etaInfoApp. See Note [Check for reflexive casts in eta expansion] These changes decreased compile-time allocation by 80%! * Passes the Simplifier's in-scope set to etaExpandAT, so we don't need to recompute it. (This alone saved 10% of compile time.) Annoyingly several functions in the Simplifier (namely makeTrivialBinding and friends) need to get SimplEnv, rather than SimplMode, but that is no big deal. Lots of small changes in compile-time allocation, less than 1% and in both directions. A couple of bigger changes, including the rather delicate T18223 T12425(optasm) ghc/alloc 98448216.0 97121224.0 -1.3% GOOD T18223(normal) ghc/alloc 5454689676.0 1138238008.0 -79.1% GOOD Metric Decrease: T12425 T18223 - - - - - 91eb1857 by Simon Peyton Jones at 2021-07-28T13:19:41-04:00 Fix a subtle scoping error in simplLazyBind In the call to prepareBinding (in simplLazyBind), I had failed to extend the in-scope set with the binders from body_floats1. As as result, when eta-expanding deep inside prepareBinding we made up an eta-binder that shadowed a variable free in body1. Yikes. It's hard to trigger this bug. It showed up when I was working on !5658, and I started using the in-scope set for eta-expansion, rather than taking free variables afresh. But even then it only showed up when compiling a module in Haddock utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs Sadly Haddock is compiled without Core Lint, so we ultimately got a seg-fault. Lint nailed it fast once I realised that it was off. There is some other tiny refactoring in this patch. - - - - - 7dc0dc99 by CarrieMY at 2021-07-28T13:20:17-04:00 Fix type check error message grammar (fixes #20122) Remove trailing spaces - - - - - 3382b3d6 by CarrieMY at 2021-07-28T13:20:17-04:00 Update expected stderr for affected tests, which are not under Tc directory - - - - - 4a2ef3dd by Alfredo Di Napoli at 2021-07-28T13:20:52-04:00 Port more DriverUnknownMessage into richer DriverMessage constructors In order: * Introduce the `PsErrUnknownOptionsPragma` diagnostic message This commit changes the diagnostic emitted inside `GHC.Parser.Header.checkProcessArgsResult` from an (erroneous) and unstructured `DriverUnknownMessage` to a `PsErrUnknownOPtionsPragma`, i.e. a new data constructor of a `PsHeaderMessage`. * Add the `DriverUserDefinedRuleIgnored` diagnostic message * Add `DriverUserDefinedRuleIgnored` data constructor This commit adds (and use) a new data constructor to the `DriverMessage` type, replacing a `DriverUnknownMessage` with it. * Add and use `DriverCannotLoadInterfaceFile` constructor This commit introduces the DriverCannotLoadInterfaceFile constructor for the `DriverMessage` type and it uses it to replace and occurrence of `DriverUnknownMessage`. * Add and use the `DriverInferredSafeImport` constructor This commit adds a new `DriverInferredSafeImport` constructor to the `DriverMessage` type, and uses it in `GHC.Driver.Main` to replace one occurrence of `DriverUnknownMessage`. * Add and use `DriverCannotImportUnsafeModule` constructor This commit adds the `DriverCannotImportUnsafeModule` constructor to the `DriverMessage` type, and later using it to replace one usage of `DriverUnknownMessage` in the `GHC.Driver.Main` module. * Add and use `DriverMissingSafeHaskellMode` constructor * Add and use `DriverPackageNotTrusted` constructor * Introduce and use `DriverInferredSafeModule` constructor * Add and use `DriverMarkedTrustworthyButInferredSafe` constructor * Add and use `DriverCannotImportFromUntrustedPackage` - - - - - de262930 by Peter Trommler at 2021-07-29T13:12:10-04:00 Delete ToDo about incorrect optimisation [skip ci] On big-endian systems a narrow after a load cannot be replaced with a narrow load. - - - - - 296ed739 by Daniel Gröber at 2021-07-29T13:12:47-04:00 rts: Allow building with ASSERTs on in non-DEBUG way We have a couple of places where the conditions in asserts depend on code ifdefed out when DEBUG is off. I'd like to allow compiling assertions into non-DEBUG RTSen so that won't do. Currently if we remove the conditional around the definition of ASSERT() the build will not actually work due to a deadlock caused by initMutex not initializing mutexes with PTHREAD_MUTEX_ERRORCHECK because DEBUG is off. - - - - - e6731578 by Daniel Gröber at 2021-07-29T13:12:47-04:00 Add configure flag to enable ASSERTs in all ways Running the test suite with asserts enabled is somewhat tricky at the moment as running it with a GHC compiled the DEBUG way has some hundred failures from the start. These seem to be unrelated to assertions though. So this provides a toggle to make it easier to debug failing assertions using the test suite. - - - - - 4d5b4ed2 by Ben Gamari at 2021-07-29T13:13:21-04:00 compiler: Name generated locals more descriptively Previously `GHC.Types.Id.Make.newLocal` would name all locals `dt`, making it unnecessarily difficult to determine their origin. Noticed while looking at #19557. - - - - - 20173629 by Sergei Trofimovich at 2021-07-29T13:13:59-04:00 UNREG: implement 64-bit mach ops for 32-bit targets Noticed build failures like ``` ghc-stage1: panic! (the 'impossible' happened) GHC version 9.3.20210721: pprCallishMachOp_for_C: MO_x64_Ne not supported! ``` on `--tagget=hppa2.0-unknown-linux-gnu`. The change does not fix all 32-bit unreg target problems, but at least allows linking final ghc binaries. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 9b916e81 by Matthew Pickering at 2021-07-29T13:14:33-04:00 Add test for #18567 Closes #18567 - - - - - f4aea1a2 by Krzysztof Gogolewski at 2021-07-29T13:15:09-04:00 Reject pattern synonyms with linear types (#18806) - - - - - 54d6b201 by Shayne Fletcher at 2021-07-29T13:15:43-04:00 Improve preprocessor error message - - - - - 266a7452 by Ben Gamari at 2021-08-02T04:10:18-04:00 ghc: Introduce --run mode As described in #18011, this mode provides similar functionality to the `runhaskell` command, but doesn't require that the user know the path of yet another executable, simplifying interactions with upstream tools. - - - - - 7e8c578e by Simon Jakobi at 2021-08-02T04:10:52-04:00 base: Document overflow behaviour of genericLength - - - - - b4d39adb by Peter Trommler at 2021-08-02T04:11:27-04:00 PrimOps: Add CAS op for all int sizes PPC NCG: Implement CAS inline for 32 and 64 bit testsuite: Add tests for smaller atomic CAS X86 NCG: Catch calls to CAS C fallback Primops: Add atomicCasWord[8|16|32|64]Addr# Add tests for atomicCasWord[8|16|32|64]Addr# Add changelog entry for new primops X86 NCG: Fix MO-Cmpxchg W64 on 32-bit arch ghc-prim: 64-bit CAS C fallback on all archs - - - - - a4ca6caa by Baldur Blöndal at 2021-08-02T04:12:04-04:00 Add Generically (generic Semigroup, Monoid instances) and Generically1 (generic Functor, Applicative, Alternative, Eq1, Ord1 instances) to GHC.Generics. - - - - - 2114a8ac by Julian Ospald at 2021-08-02T04:12:41-04:00 Improve documentation of openTempFile args https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamew Specifically: > The null-terminated prefix string. The function uses up to the first > three characters of this string as the prefix of the file name. This > string must consist of characters in the OEM-defined character set. - - - - - 4ae1e53c by Sylvain Henry at 2021-08-02T04:12:41-04:00 Fix spelling - - - - - 022c7945 by Moritz Angermann at 2021-08-02T04:13:15-04:00 [AArch64/Darwin] fix packed calling conv alignment Apparently we need some padding as well. Fixes #20137 - - - - - 2de8f031 by Ben Gamari at 2021-08-02T04:13:15-04:00 testsuite: Add test for #20137 - - - - - 2e0f4ca1 by Adam Sandberg Ericsson at 2021-08-02T04:13:50-04:00 docs: rename the "Running a compiled program" section in the users guide This hopefully makes it easier to find the right section when scanning the table of contents. - - - - - f454c0ea by Ben Gamari at 2021-08-02T04:14:25-04:00 rts/OSThreads: Fix reference clock of timedWaitCondition Previously `timedWaitCondition` assumed that timeouts were referenced against `CLOCK_MONOTONIC`. This is wrong; by default `pthread_cond_timedwait` references against `CLOCK_REALTIME`, although this can be overridden using `pthread_condattr_setclock`. Fix this and add support for using `CLOCK_MONOTONIC` whenever possible as it is more robust against system time changes and is likely cheaper to query. Unfortunately, this is complicated by the fact that older versions of Darwin did not provide `clock_gettime`, which means we also need to introduce a fallback path using `gettimeofday`. Fixes #20144. - - - - - 7bad93a2 by Sylvain Henry at 2021-08-02T04:15:03-04:00 Only create callstack in DEBUG builds - - - - - 3968cd0c by Sylvain Henry at 2021-08-02T04:15:41-04:00 Constant-fold unpackAppendCString (fix #20174) Minor renaming: since 1ed0409010afeaa318676e351b833aea659bf93a rules get an InScopeEnv arg (containing an IdUnfoldingFun) instead of an IdUnfoldingFun directly, hence I've renamed the parameter from "id_unf" to "env" for clarity. - - - - - 901c79d8 by Sylvain Henry at 2021-08-02T04:15:41-04:00 Lookup string literals in top-level thunks (fix #16373) - - - - - 3e93a370 by Ben Gamari at 2021-08-02T04:16:16-04:00 validate: Look for python3 executable in python detection Previously we would only look for a `python` executable, but in general we should prefer `python3` and sometimes `python` doesn't exist. - - - - - 8631ccf2 by Krzysztof Gogolewski at 2021-08-02T04:16:51-04:00 Remove Semigroup instance for UniqDFM (#19654) The (<>) operator was not associative. Fortunately, the instance is not used anywhere, except to derive another unused instance for UniqDSet. - - - - - 20ef67a3 by Ben Gamari at 2021-08-02T04:17:26-04:00 hadrian: Drop --configure support Hadrian's `--configure` support has long been a point of contention. While it's convenient, it also introduces a fair bit of implementation complexity and quite a few non-trivial failure modes (see #19804, 17883, and #15948). Moreover, the feature is actively misleading to the user: `./configure` is the primary means for the user to inform the build system about the system environment and in general will require input from the user. This commits removes the feature, replacing the flag with a stub message informing the user of the deprecation. Closes #20167. - - - - - 13af2fee by Krzysztof Gogolewski at 2021-08-02T04:18:00-04:00 Disallow nonlinear fields in Template Haskell (#18378) - - - - - e1538184 by Shayne Fletcher at 2021-08-02T04:18:35-04:00 Supply missing case for '.' in - - - - - 34e35217 by Simon Peyton Jones at 2021-08-02T04:19:09-04:00 Catch type-checker exceptions when splicing In GHC.Tc.Gen.Splice.tcTopSpliceExpr we were forgetting to catch exceptions. As a result we missed the kind error in the unsolved constraints. This patch has an easy fix, which cures #20179 - - - - - c248e7cc by Jens Petersen at 2021-08-03T10:14:36-04:00 include README in hadrian.cabal [skip ci] - - - - - bbee89dd by Zubin Duggal at 2021-08-03T10:15:11-04:00 Remove hschooks.c and -no-hs-main for ghc-bin - - - - - 9807350a by Zubin Duggal at 2021-08-03T10:15:11-04:00 Properly escape arguments in ghc-cabal - - - - - d22ec8a9 by Ben Gamari at 2021-08-03T10:15:46-04:00 Bump process submodule - - - - - 694ec53b by Matthew Pickering at 2021-08-03T10:16:20-04:00 Remove eager forcing of RuleInfo in substRuleInfo substRuleInfo updates the IdInfo for an Id, therefore it is important to not force said IdInfo whilst updating it, otherwise we end up in an infinite loop. This is what happened in #20112 where `mkTick` forced the IdInfo being updated by checking the arity in isSaturatedConApp. The fix is to stop the expression being forced so early by removing the call to seqRuleInfo. The call sequence looked something like: * `substRecBndrs` * `substIdBndr` * `substIdInfo` * `substRuleInfo` * `substRule` * `substExpr` * `mkTick` * `isSaturatedConApp` * Look at `IdInfo` for thing we are currently substituting because the rule is attached to `transpose` and mentions it in the `RHS` of the rule. Which arose because the `transpose` Id had a rule attached where the RHS of the rule also mentioned `transpose`. This call to seqRuleInfo was introduced in 4e7d56fde0f44d38bbb9a6fc72cf9c603264899d where it was explained > I think there are now *too many* seqs, and they waste work, but I don't have > time to find which ones. We also observe that there is the ominous note on `substRule` about making sure substExpr is called lazily. > {- Note [Substitute lazily] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > The functions that substitute over IdInfo must be pretty lazy, because > they are knot-tied by substRecBndrs. > > One case in point was #10627 in which a rule for a function 'f' > referred to 'f' (at a different type) on the RHS. But instead of just > substituting in the rhs of the rule, we were calling simpleOptExpr, which > looked at the idInfo for 'f'; result <<loop>>. > > In any case we don't need to optimise the RHS of rules, or unfoldings, > because the simplifier will do that. Before `seqRuleInfo` was removed, this note was pretty much ignored in the `substSpec` case because the expression was immediately forced after `substRule` was called. Unfortunately it's a bit tricky to add a test for this as the failure only manifested (for an unknown reason) with a dwarf enabled compiler *AND* compiling with -g3. Fortunatley there is currently a CI configuration which builds a dwarf compiler to test this. Also, for good measure, finish off the work started in 840df33685e8c746ade4b9d4d0eb7c764a773e48 which renamed SpecInfo to RuleInfo but then didn't rename 'substSpec' to 'substRuleInfo'. Fixes #20112 - - - - - c0e66524 by Krzysztof Gogolewski at 2021-08-03T10:16:55-04:00 Add "fast-ci" label, for skipping most builds (#19280) If "fast-ci" is present, only the following parts of full-build are run: - validate-x86_64-linux-deb9-debug - validate-x86_64-windows-hadrian - validate-x86_64-linux-deb9-unreg-hadrian - - - - - bd287400 by Andreas Klebinger at 2021-08-03T10:17:29-04:00 Improve documentation for HscTypes.usg_mod_hash - - - - - 5155eafa by Zubin Duggal at 2021-08-03T10:18:04-04:00 Handle OverloadedRecordDot in TH (#20185) - - - - - 9744c6f5 by Tito Sacchi at 2021-08-03T17:19:14-04:00 Correctly unload libs on GHCi with external iserv Fix #17669 `hostIsDynamic` is basically a compile-time constant embedded in the RTS. Therefore, GHCi didn't unload object files properly when used with an external interpreter built in a different way. - - - - - 3403c028 by Luite Stegeman at 2021-08-03T17:19:51-04:00 move bytecode preparation into the STG pipeline this makes it possible to combine passes to compute free variables more efficiently in a future change - - - - - 6ad25367 by Sylvain Henry at 2021-08-03T17:20:29-04:00 Fix ASSERTS_ENABLED CPP - - - - - 4f672677 by Sylvain Henry at 2021-08-03T17:21:07-04:00 Don't store tmpDir in Settings There was no point in doing this as indicated by the TODO. - - - - - 2c714f07 by Krzysztof Gogolewski at 2021-08-04T01:33:03-04:00 Disable -fdefer-type-errors for linear types (#20083) - - - - - 9b719549 by Krzysztof Gogolewski at 2021-08-04T01:33:38-04:00 Linear types: fix linting of multiplicities (#19165) The previous version did not substitute the type used in the scrutinee. - - - - - 1b6e646e by John Ericson at 2021-08-04T10:05:52-04:00 Make HsWrapper a Monoid See instance documentation for caviat. - - - - - ce7eeda5 by Matthew Pickering at 2021-08-04T10:06:26-04:00 hadrian: Create relative rather than absolute symlinks in binary dist folder The symlink structure now looks like: ``` lrwxrwxrwx 1 matt users 16 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc -> ghc-9.3.20210721 -rwxr-xr-x 1 matt users 1750336 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-9.3.20210721 lrwxrwxrwx 1 matt users 22 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-iserv -> ghc-iserv-9.3.20210721 -rwxr-xr-x 1 matt users 31703176 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-iserv-9.3.20210721 lrwxrwxrwx 1 matt users 26 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-iserv-dyn -> ghc-iserv-dyn-9.3.20210721 -rwxr-xr-x 1 matt users 40808 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-iserv-dyn-9.3.20210721 lrwxrwxrwx 1 matt users 20 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-pkg -> ghc-pkg-9.3.20210721 -rwxr-xr-x 1 matt users 634872 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/ghc-pkg-9.3.20210721 lrwxrwxrwx 1 matt users 14 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/haddock -> haddock-2.24.0 -rwxr-xr-x 1 matt users 4336664 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/haddock-2.24.0 lrwxrwxrwx 1 matt users 9 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hp2ps -> hp2ps-0.1 -rwxr-xr-x 1 matt users 49312 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hp2ps-0.1 lrwxrwxrwx 1 matt users 8 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hpc -> hpc-0.68 -rwxr-xr-x 1 matt users 687896 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hpc-0.68 lrwxrwxrwx 1 matt users 13 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hsc2hs -> hsc2hs-0.68.8 -rwxr-xr-x 1 matt users 729904 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/hsc2hs-0.68.8 lrwxrwxrwx 1 matt users 19 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/runghc -> runghc-9.3.20210721 -rwxr-xr-x 1 matt users 57672 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/runghc-9.3.20210721 lrwxrwxrwx 1 matt users 9 Aug 3 16:27 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/unlit -> unlit-0.1 -rwxr-xr-x 1 matt users 14896 Aug 3 15:00 _build/bindist/ghc-9.3.20210721-x86_64-unknown-linux/bin/unlit-0.1 ``` Fixes #20198 - - - - - 477bc2dd by Zubin Duggal at 2021-08-04T16:38:02-04:00 Fix GHCi completion (#20101) Updates haskeline submodule - - - - - 7a9d8803 by sheaf at 2021-08-04T16:38:40-04:00 Use Reductions to keep track of rewritings We define Reduction = Reduction Coercion !Type. A reduction of the form 'Reduction co new_ty' witnesses an equality ty ~co~> new_ty. That is, the rewriting happens left-to-right: the right-hand-side type of the coercion is the rewritten type, and the left-hand-side type the original type. Sticking to this convention makes the codebase more consistent, helping to avoid certain applications of SymCo. This replaces the parts of the codebase which represented reductions as pairs, (Coercion,Type) or (Type,Coercion). Reduction being strict in the Type argument improves performance in some programs that rewrite many type families (such as T9872). Fixes #20161 ------------------------- Metric Decrease: T5321Fun T9872a T9872b T9872c T9872d ------------------------- - - - - - 1f809093 by Andrew Lelechenko at 2021-08-05T07:14:04-04:00 Add Data.ByteArray, derived from primitive - - - - - 5d651c78 by Krzysztof Gogolewski at 2021-08-05T07:14:39-04:00 Minor fix to pretty-printing of linear types The function ppr_arrow_chain was not printing multiplicities. Also remove the Outputable instance: no longer used, and could cover bugs like those. - - - - - fb45e632 by Viktor Dukhovni at 2021-08-08T13:53:00-04:00 Rewrite of Traversable overview - - - - - 2bf417f6 by Viktor Dukhovni at 2021-08-08T13:53:00-04:00 Consistent use of coercion and TypeApplications This makes the implementations of: - mapAccumL - mapAccumR - fmapDefault - foldMapDefault more uniform and match the approach in the overview. - - - - - cf7e6c8d by Ben Gamari at 2021-08-09T08:10:11-04:00 testsuite: Add test for #20199 Ensures that Rts.h can be parsed as C++. - - - - - 080ffd4b by Ben Gamari at 2021-08-09T08:10:11-04:00 rts: Fix use of sized array in Heap.h Sized arrays cannot be used in headers that might be imported from C++. Fixes #20199. - - - - - b128a880 by Sylvain Henry at 2021-08-09T15:11:22-04:00 Ensure that newtype deriving strategy is used for CTypes - - - - - 74863638 by Sylvain Henry at 2021-08-09T15:11:23-04:00 Remove ad-hoc fromIntegral rules fromIntegral is defined as: {-# NOINLINE [1] fromIntegral #-} fromIntegral :: (Integral a, Num b) => a -> b fromIntegral = fromInteger . toInteger Before this patch, we had a lot of rewrite rules for fromIntegral, to avoid passing through Integer when there is a faster way, e.g.: "fromIntegral/Int->Word" fromIntegral = \(I# x#) -> W# (int2Word# x#) "fromIntegral/Word->Int" fromIntegral = \(W# x#) -> I# (word2Int# x#) "fromIntegral/Word->Word" fromIntegral = id :: Word -> Word Since we have added sized types and primops (Word8#, Int16#, etc.) and Natural, this approach didn't really scale as there is a combinatorial explosion of types. In addition, we really want these conversions to be optimized for all these types and in every case (not only when fromIntegral is explicitly used). This patch removes all those ad-hoc fromIntegral rules. Instead we rely on inlining and built-in constant-folding rules. There are not too many native conversions between Integer/Natural and fixed size types, so we can handle them all explicitly. Foreign.C.Types was using rules to ensure that fromIntegral rules "sees" through the newtype wrappers,e.g.: {-# RULES "fromIntegral/a->CSize" fromIntegral = \x -> CSize (fromIntegral x) "fromIntegral/CSize->a" fromIntegral = \(CSize x) -> fromIntegral x #-} But they aren't necessary because coercions due to newtype deriving are pushed out of the way. So this patch removes these rules (as fromIntegral is now inlined, they won't match anymore anyway). Summary: * INLINE `fromIntegral` * Add some missing constant-folding rules * Remove every fromIntegral ad-hoc rules (fix #19907) Fix #20062 (missing fromIntegral rules for sized primitives) Performance: - T12545 wiggles (tracked by #19414) Metric Decrease: T12545 T10359 Metric Increase: T12545 - - - - - db7098fe by John Ericson at 2021-08-09T15:11:58-04:00 Clean up whitespace in /includes I need to do this now or when I move these files the linter will be mad. - - - - - fc350dba by John Ericson at 2021-08-09T15:11:58-04:00 Make `PosixSource.h` installed and under `rts/` is used outside of the rts so we do this rather than just fish it out of the repo in ad-hoc way, in order to make packages in this repo more self-contained. - - - - - d5de970d by John Ericson at 2021-08-09T15:11:58-04:00 Move `/includes` to `/rts/include`, sort per package better In order to make the packages in this repo "reinstallable", we need to associate source code with a specific packages. Having a top level `/includes` dir that mixes concerns (which packages' includes?) gets in the way of this. To start, I have moved everything to `rts/`, which is mostly correct. There are a few things however that really don't belong in the rts (like the generated constants haskell type, `CodeGen.Platform.h`). Those needed to be manually adjusted. Things of note: - No symlinking for sake of windows, so we hard-link at configure time. - `CodeGen.Platform.h` no longer as `.hs` extension (in addition to being moved to `compiler/`) so as not to confuse anyone, since it is next to Haskell files. - Blanket `-Iincludes` is gone in both build systems, include paths now more strictly respect per-package dependencies. - `deriveConstants` has been taught to not require a `--target-os` flag when generating the platform-agnostic Haskell type. Make takes advantage of this, but Hadrian has yet to. - - - - - 8b9acc4d by Sylvain Henry at 2021-08-09T15:12:36-04:00 Hadrian: fix .cabal file `stack sdist` in the hadrian directory reported: Package check reported the following errors: To use the 'extra-doc-files' field the package needs to specify at least 'cabal-version: >= 1.18'. - - - - - 741fdf0e by David Simmons-Duffin at 2021-08-10T15:00:05-04:00 Add a Typeable constraint to fromStaticPtr, addressing #19729 - - - - - 130f94db by Artyom Kuznetsov at 2021-08-10T15:00:42-04:00 Refactor HsStmtContext and remove HsDoRn Parts of HsStmtContext were split into a separate data structure HsDoFlavour. Before this change HsDo used to have HsStmtContext inside, but in reality only parts of HsStmtContext were used and other cases were invariants handled with panics. Separating those parts into its own data structure helps us to get rid of those panics as well as HsDoRn type family. - - - - - 92b0037b by Sylvain Henry at 2021-08-10T15:01:20-04:00 Fix recomp021 locale `diff` uses the locale to print its message. - - - - - 7bff8bf5 by Sylvain Henry at 2021-08-10T15:01:58-04:00 Fix pprDeps Copy-paste error in 38faeea1a94072ffd9f459d9fe570f06bc1da84a - - - - - c65a7ffa by Moritz Angermann at 2021-08-11T06:49:38+00:00 Update HACKING.md - - - - - f5fdace5 by Sven Tennie at 2021-08-11T18:14:30-04:00 Optimize Info Table Provenance Entries (IPEs) Map creation and lookup Using a hash map reduces the complexity of lookupIPE(), making it non linear. On registration each IPE list is added to a temporary IPE lists buffer, reducing registration time. The hash map is built lazily on first lookup. IPE event output to stderr is added with tests. For details, please see Note [The Info Table Provenance Entry (IPE) Map]. A performance test for IPE registration and lookup can be found here: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/5724#note_370806 - - - - - 100ffe75 by Alina Banerjee at 2021-08-11T18:15:05-04:00 Modify InlineSpec data constructor (helps fix #18138) The inl_inline field of the InlinePragma record is modified to store pragma source text by adding a data constructor of type SourceText. This can help in tracking the actual text of pragma names. Add/modify functions, modify type instance for InlineSpec type Modify parser, lexer to handle InlineSpec constructors containing SourceText Modify functions with InlineSpec type Extract pragma source from InlineSpec for SpecSig, InlineSig types Modify cvtInline function to add SourceText to InlineSpec type Extract name for InlineSig, SpecSig from pragma, SpectInstSig from source (fixes #18138) Extract pragma name for SpecPrag pragma, SpecSig signature Add Haddock annotation for inlinePragmaName function Add Haddock annotations for using helper functions in hsSigDoc Remove redundant ppr in pragma name for SpecSig, InlineSig; update comment Rename test to T18138 for misplaced SPECIALIZE pragma testcase - - - - - 7ad813a4 by Gergő Érdi at 2021-08-13T07:53:53-04:00 Move `ol_witness` to `OverLitTc` We also add a new `ol_from_fun` field to renamed (but not yet typechecked) OverLits. This has the nice knock-on effect of making total some typechecker functions that used to be partial. Fixes #20151 - - - - - c367b39e by Sylvain Henry at 2021-08-13T07:54:32-04:00 Refactoring module dependencies * Make mkDependencies pure * Use Sets instead of sorted lists Notable perf changes: MultiLayerModules(normal) ghc/alloc 4130851520.0 2981473072.0 -27.8% T13719(normal) ghc/alloc 4313296052.0 4151647512.0 -3.7% Metric Decrease: MultiLayerModules T13719 - - - - - 9d4ba36f by sheaf at 2021-08-13T14:40:16+02:00 Add rewriting to typechecking plugins Type-checking plugins can now directly rewrite type-families. The TcPlugin record is given a new field, tcPluginRewrite. The plugin specifies how to rewrite certain type-families with a value of type `UniqFM TyCon TcPluginRewriter`, where: type TcPluginRewriter = RewriteEnv -- Rewriter environment -> [Ct] -- Givens -> [TcType] -- type family arguments -> TcPluginM TcPluginRewriteResult data TcPluginRewriteResult = TcPluginNoRewrite | TcPluginRewriteTo { tcPluginRewriteTo :: Reduction , tcRewriterNewWanteds :: [Ct] } When rewriting an exactly-saturated type-family application, GHC will first query type-checking plugins for possible rewritings before proceeding. Includes some changes to the TcPlugin API, e.g. removal of the EvBindsVar parameter to the TcPluginM monad. - - - - - 0bf8e73a by Matthew Pickering at 2021-08-13T21:47:26-04:00 Revert "hadrian: Make copyFileLinked a bit more robust" This reverts commit d45e3cda669c5822aa213d42bf7f7c551b9d1bbf. - - - - - 9700b9a8 by Matthew Pickering at 2021-08-13T21:47:26-04:00 Create absolute symlink for test executables This is necessary because the symlink needs to be created between two arbritary filepaths in the build tree, it's hard to compute how to get between them relatively. As this symlink doesn't end up in a bindist then it's fine for it to be absolute. - - - - - a975583c by Matthew Pickering at 2021-08-13T21:48:03-04:00 hadrian: Also produce versioned wrapper scripts Since !6133 we are more consistent about producing versioned executables but we still didn't produce versioned wrappers. This patch adds the corresponding versioned wrappers to match the versioned executables in the relocatable bindist. I also fixed the ghci wrapper so that it wasn't overwritten during installation. The final bindir looks like: ``` lrwxrwxrwx 1 matt users 16 Aug 12 11:56 ghc -> ghc-9.3.20210809 -rwxr-xr-x 1 matt users 674 Aug 12 11:56 ghc-9.3.20210809 lrwxrwxrwx 1 matt users 17 Aug 12 11:56 ghci -> ghci-9.3.20210809 -rwxr-xr-x 1 matt users 708 Aug 12 11:56 ghci-9.3.20210809 lrwxrwxrwx 1 matt users 20 Aug 12 11:56 ghc-pkg -> ghc-pkg-9.3.20210809 -rwxr-xr-x 1 matt users 734 Aug 12 11:56 ghc-pkg-9.3.20210809 lrwxrwxrwx 1 matt users 14 Aug 12 11:56 haddock -> haddock-2.24.0 -rwxr-xr-x 1 matt users 682 Aug 12 11:56 haddock-2.24.0 lrwxrwxrwx 1 matt users 9 Aug 12 11:56 hp2ps -> hp2ps-0.1 -rwxr-xr-x 1 matt users 648 Aug 12 11:56 hp2ps-0.1 lrwxrwxrwx 1 matt users 8 Aug 12 11:56 hpc -> hpc-0.68 -rwxr-xr-x 1 matt users 646 Aug 12 11:56 hpc-0.68 lrwxrwxrwx 1 matt users 13 Aug 12 11:56 hsc2hs -> hsc2hs-0.68.8 -rwxr-xr-x 1 matt users 1.4K Aug 12 11:56 hsc2hs-0.68.8 lrwxrwxrwx 1 matt users 19 Aug 12 11:56 runghc -> runghc-9.3.20210809 -rwxr-xr-x 1 matt users 685 Aug 12 11:56 runghc-9.3.20210809 ``` Fixes #20225 - - - - - 1e896b47 by sheaf at 2021-08-15T09:00:29-04:00 Detect TypeError when checking for insolubility We detect insoluble Givens by making getInertInsols take into account TypeError constraints, on top of insoluble equalities such as Int ~ Bool (which it already took into account). This allows pattern matches with insoluble contexts to be reported as redundant (tyOracle calls tcCheckGivens which calls getInertInsols). As a bonus, we get to remove a workaround in Data.Typeable.Internal: we can directly use a NotApplication type family, as opposed to needing to cook up an insoluble equality constraint. Fixes #11503 #14141 #16377 #20180 - - - - - 71130bf8 by sheaf at 2021-08-15T09:01:06-04:00 Update TcPlugin_RewritePerf performance test This test exhibited inconsistent behaviour, with different CI runs having a 98% decrease in allocations. This commit addresses this problem by ensuring that we measure allocations of the whole collection of modules used in the test. ------------------------- Metric Increase: TcPlugin_RewritePerf ------------------------- - - - - - 0f6fb7d3 by Simon Peyton Jones at 2021-08-15T14:18:52+01:00 TypeError is OK on the RHS of a type synonym We should not complain about TypeError in type T = TypeError blah This fixes #20181 The error message for T13271 changes, because that test did indeed have a type synonym with TypeError on the RHS - - - - - 149bce42 by Krzysztof Gogolewski at 2021-08-15T16:13:35-04:00 Fix lookupIdSubst call during RULE matching As #20200 showed, there was a call to lookupIdSubst during RULE matching, where the variable being looked up wasn't in the InScopeSet. This patch fixes the problem at source, by dealing separately with nested and non-nested binders. As a result we can change the trace call in lookupIdSubst to a proper panic -- if it happens, we really want to know. - - - - - 7f217429 by Simon Peyton Jones at 2021-08-15T16:13:35-04:00 Use the right InScopeSet for findBest This is the right thing to do, easy to do, and fixes a second not-in-scope crash in #20200 (see !6302) The problem occurs in the findBest test, which compares two RULES. Repro case in simplCore/should_compile/T20200a - - - - - 31dc013f by Greg Steuck at 2021-08-15T21:09:23+00:00 Fix iconv detection in configure on OpenBSD This regressed in 544414ba604b13e0992ad87e90b8bdf45c43011c causing configure: error: iconv is required on non-Windows platforms More details: https://gitlab.haskell.org/ghc/ghc/-/commit/544414ba604b13e0992ad87e90b8bdf45c43011c#3bae3b74ae866493bd6b79df16cb638a5f2e0f87_106_106 - - - - - acb188e0 by Matthew Pickering at 2021-08-17T08:05:34-04:00 ghci: Fix rec statements in interactive prompt We desugar a recursive Stmt to somethign like (a,_,c) <- mfix (\(a,b,_) -> do { ... ; return (a,b,c) }) ...stuff after the rec... The knot-tied tuple must contain * All the variables that are used before they are bound in the `rec` block * All the variables that are used after the entire `rec` block In the case of GHCi, however, we don't know what variables will be used after the `rec` (#20206). For example, we might have ghci> rec { x <- e1; y <- e2 } ghci> print x ghci> print y So we have to assume that *all* the variables bound in the `rec` are used afterwards. We use `Nothing` in the argument to segmentRecStmts to signal that all the variables are used. Fixes #20206 - - - - - b784a51e by John Ericson at 2021-08-17T20:58:33+00:00 Test non-native switch C-- with twos compliment We don't want regressions like e8f7734d8a052f99b03e1123466dc9f47b48c311 to regress. Co-Authored-By: Sylvain Henry <hsyl20 at gmail.com> - - - - - 5798357d by Sylvain Henry at 2021-08-17T21:01:44+00:00 StgToCmm: use correct bounds for switches on sized values StgToCmm was only using literals signedness to determine whether using Int and Word range in Cmm switches. Now that we have sized literals (Int8#, Int16#, etc.), it needs to take their ranges into account. - - - - - 0ba21dbe by Matthew Pickering at 2021-08-18T05:43:57-04:00 Fix parsing of rpaths which include spaces in runInjectRPaths The logic didn't account for the fact that the paths could contain spaces before which led to errors such as the following from install_name_tool. Stderr ( T14304 ): Warning: -rtsopts and -with-rtsopts have no effect with -shared. Call hs_init_ghc() from your main() function to set these options. error: /nix/store/a6j5761iy238pbckxq2xrhqr2d5kra4m-cctools-binutils-darwin-949.0.1/bin/install_name_tool: for: dist/build/libHSp-0.1-ghc8.10.6.dylib (for architecture arm64) option "-add_rpath /Users/matt/ghc/bindisttest/install dir/lib/ghc-8.10.6/ghc-prim-0.6.1" would duplicate path, file already has LC_RPATH for: /Users/matt/ghc/bindisttest/install dir/lib/ghc-8.10.6/ghc-prim-0.6.1 `install_name_tool' failed in phase `Install Name Tool'. (Exit code: 1) Fixes #20212 This apparently also fixes #20026, which is a nice surprise. - - - - - 5f0d2dab by Matthew Pickering at 2021-08-18T17:57:42-04:00 Driver rework pt3: the upsweep This patch specifies and simplifies the module cycle compilation in upsweep. How things work are described in the Note [Upsweep] Note [Upsweep] ~~~~~~~~~~~~~~ Upsweep takes a 'ModuleGraph' as input, computes a build plan and then executes the plan in order to compile the project. The first step is computing the build plan from a 'ModuleGraph'. The output of this step is a `[BuildPlan]`, which is a topologically sorted plan for how to build all the modules. ``` data BuildPlan = SingleModule ModuleGraphNode -- A simple, single module all alone but *might* have an hs-boot file which isn't part of a cycle | ResolvedCycle [ModuleGraphNode] -- A resolved cycle, linearised by hs-boot files | UnresolvedCycle [ModuleGraphNode] -- An actual cycle, which wasn't resolved by hs-boot files ``` The plan is computed in two steps: Step 1: Topologically sort the module graph without hs-boot files. This returns a [SCC ModuleGraphNode] which contains cycles. Step 2: For each cycle, topologically sort the modules in the cycle *with* the relevant hs-boot files. This should result in an acyclic build plan if the hs-boot files are sufficient to resolve the cycle. The `[BuildPlan]` is then interpreted by the `interpretBuildPlan` function. * `SingleModule nodes` are compiled normally by either the upsweep_inst or upsweep_mod functions. * `ResolvedCycles` need to compiled "together" so that the information which ends up in the interface files at the end is accurate (and doesn't contain temporary information from the hs-boot files.) - During the initial compilation, a `KnotVars` is created which stores an IORef TypeEnv for each module of the loop. These IORefs are gradually updated as the loop completes and provide the required laziness to typecheck the module loop. - At the end of typechecking, all the interface files are typechecked again in the retypecheck loop. This time, the knot-tying is done by the normal laziness based tying, so the environment is run without the KnotVars. * UnresolvedCycles are indicative of a proper cycle, unresolved by hs-boot files and are reported as an error to the user. The main trickiness of `interpretBuildPlan` is deciding which version of a dependency is visible from each module. For modules which are not in a cycle, there is just one version of a module, so that is always used. For modules in a cycle, there are two versions of 'HomeModInfo'. 1. Internal to loop: The version created whilst compiling the loop by upsweep_mod. 2. External to loop: The knot-tied version created by typecheckLoop. Whilst compiling a module inside the loop, we need to use the (1). For a module which is outside of the loop which depends on something from in the loop, the (2) version is used. As the plan is interpreted, which version of a HomeModInfo is visible is updated by updating a map held in a state monad. So after a loop has finished being compiled, the visible module is the one created by typecheckLoop and the internal version is not used again. This plan also ensures the most important invariant to do with module loops: > If you depend on anything within a module loop, before you can use the dependency, the whole loop has to finish compiling. The end result of `interpretBuildPlan` is a `[MakeAction]`, which are pairs of `IO a` actions and a `MVar (Maybe a)`, somewhere to put the result of running the action. This list is topologically sorted, so can be run in order to compute the whole graph. As well as this `interpretBuildPlan` also outputs an `IO [Maybe (Maybe HomeModInfo)]` which can be queried at the end to get the result of all modules at the end, with their proper visibility. For example, if any module in a loop fails then all modules in that loop will report as failed because the visible node at the end will be the result of retypechecking those modules together. Along the way we also fix a number of other bugs in the driver: * Unify upsweep and parUpsweep. * Fix #19937 (static points, ghci and -j) * Adds lots of module loop tests due to Divam. Also related to #20030 Co-authored-by: Divam Narula <dfordivam at gmail.com> ------------------------- Metric Decrease: T10370 ------------------------- - - - - - d9cf2ec8 by Matthew Pickering at 2021-08-18T17:57:42-04:00 recomp: Check backend type rather than -fwrite-interface to decide whether we need any objects This was a small oversight in the original patch which leads to spurious recompilation when using `-fno-code` but not `-fwrite-interface`, which you plausibly might do when using ghci. Fixes #20216 - - - - - 4a10f0ff by sheaf at 2021-08-18T17:58:19-04:00 Don't look for TypeError in type family arguments Changes checkUserTypeError to no longer look for custom type errors inside type family arguments. This means that a program such as foo :: F xyz (TypeError (Text "blah")) -> bar does not throw a type error at definition site. This means that more programs can be accepted, as the custom type error might disappear upon reducing the above type family F. This applies only to user-written type signatures, which are checked within checkValidType. Custom type errors in type family arguments continue to be reported when they occur in unsolved Wanted constraints. Fixes #20241 - - - - - cad5a141 by Viktor Dukhovni at 2021-08-19T01:19:29-04:00 Fix missing can_fail annotation on two CAS primops Also note why has_side_effects is needed with reads of mutable data, using text provided by Simon Peyton-Jones. - - - - - 4ff4d434 by Simon Peyton Jones at 2021-08-19T01:20:03-04:00 Get the in-scope set right during RULE matching There was a subtle error in the in-scope set during RULE matching, which led to #20200 (not the original report, but the reports of failures following an initial bug-fix commit). This patch fixes the problem, and simplifies the code a bit. In pariticular there was a very mysterious and ad-hoc in-scope set extension in rnMatchBndr2, which is now moved to the right place, namely in the Let case of match, where we do the floating. I don't have a small repro case, alas. - - - - - d43442cb by John Ericson at 2021-08-19T18:02:13-04:00 Make Int64#/Word64# unconditionally available This prepares us to actually use them when the native size is 64 bits too. I more than saitisfied my curiosity finding they were gated since 47774449c9d66b768a70851fe82c5222c1f60689. - - - - - ad28ae41 by Matthew Pickering at 2021-08-19T18:02:48-04:00 Add -Wl,-U,___darwin_check_fd_set_overflow to rts/package.conf.in The make build system apparently uses this special package.conf rather than generating it from the cabal file. Ticket: #19950 (cherry picked from commit e316a0f3e7a733fac0c30633767487db086c4cd0) - - - - - 69fb6f6a by Ben Gamari at 2021-08-23T13:33:41-04:00 users guide: Document -hpcdir flag Previously this was undocumented. - - - - - 27c27f7d by Matthew Pickering at 2021-08-23T13:34:16-04:00 hadrian: Include runhaskell in bindist Fixes #19571 bin folder now containers/ ``` ghc ghc-iserv-dyn-9.3.20210813 hp2ps hsc2hs-0.68.8 unlit ghc-9.3.20210813 ghc-pkg hp2ps-0.1 runghc unlit-0.1 ghc-iserv ghc-pkg-9.3.20210813 hpc runghc-9.3.20210813 ghc-iserv-9.3.20210813 haddock hpc-0.68 runhaskell ghc-iserv-dyn haddock-2.24.0 hsc2hs runhaskell-9.3.20210813 ``` which installed via wrappers looks like ``` lrwxrwxrwx 1 matt users 16 Aug 13 17:32 ghc -> ghc-9.3.20210813 -rwxr-xr-x 1 matt users 446 Aug 13 17:32 ghc-9.3.20210813 lrwxrwxrwx 1 matt users 17 Aug 13 17:32 ghci -> ghci-9.3.20210813 -rwxr-xr-x 1 matt users 480 Aug 13 17:32 ghci-9.3.20210813 lrwxrwxrwx 1 matt users 20 Aug 13 17:32 ghc-pkg -> ghc-pkg-9.3.20210813 -rwxr-xr-x 1 matt users 506 Aug 13 17:32 ghc-pkg-9.3.20210813 lrwxrwxrwx 1 matt users 14 Aug 13 17:32 haddock -> haddock-2.24.0 -rwxr-xr-x 1 matt users 454 Aug 13 17:32 haddock-2.24.0 lrwxrwxrwx 1 matt users 9 Aug 13 17:32 hp2ps -> hp2ps-0.1 -rwxr-xr-x 1 matt users 420 Aug 13 17:32 hp2ps-0.1 lrwxrwxrwx 1 matt users 8 Aug 13 17:32 hpc -> hpc-0.68 -rwxr-xr-x 1 matt users 418 Aug 13 17:32 hpc-0.68 lrwxrwxrwx 1 matt users 13 Aug 13 17:32 hsc2hs -> hsc2hs-0.68.8 -rwxr-xr-x 1 matt users 1.2K Aug 13 17:32 hsc2hs-0.68.8 lrwxrwxrwx 1 matt users 19 Aug 13 17:32 runghc -> runghc-9.3.20210813 -rwxr-xr-x 1 matt users 457 Aug 13 17:32 runghc-9.3.20210813 lrwxrwxrwx 1 matt users 23 Aug 13 17:32 runhaskell -> runhaskell-9.3.20210813 -rwxr-xr-x 1 matt users 465 Aug 13 17:32 runhaskell-9.3.20210813 ``` - - - - - 7dde84ad by Matthew Pickering at 2021-08-23T13:34:16-04:00 hadrian: Write version wrappers in C rather than Haskell This reduces the resulting binary size on windows where the executables were statically linked. - - - - - 6af7d127 by Matthew Pickering at 2021-08-23T13:34:16-04:00 hadrian: Use ghc version as suffix for all executables ``` [matt at nixos:~/ghc-unique-spin]$ ls _build/bindist/ghc-9.3.20210813-x86_64-unknown-linux/bin/ ghc haddock runghc ghc-9.3.20210813 haddock-ghc-9.3.20210813 runghc-9.3.20210813 ghc-iserv hp2ps runhaskell ghc-iserv-dyn hp2ps-ghc-9.3.20210813 runhaskell-9.3.20210813 ghc-iserv-dyn-ghc-9.3.20210813 hpc unlit ghc-iserv-ghc-9.3.20210813 hpc-ghc-9.3.20210813 unlit-ghc-9.3.20210813 ghc-pkg hsc2hs ghc-pkg-9.3.20210813 hsc2hs-ghc-9.3.20210813 [matt at nixos:~/ghc-unique-spin]$ ls _build/bindist/ghc-9.3.20210813-x86_64-unknown-linux/wrappers/ ghc ghc-pkg-9.3.20210813 hpc runghc-9.3.20210813 ghc-9.3.20210813 haddock hpc-ghc-9.3.20210813 runhaskell ghci haddock-ghc-9.3.20210813 hsc2hs runhaskell-9.3.20210813 ghci-9.3.20210813 hp2ps hsc2hs-ghc-9.3.20210813 ghc-pkg hp2ps-ghc-9.3.20210813 runghc ``` See the discussion on #19571 where we decided that it was most sensible to use the same version number as a suffix for all executables. For those whose version number is different to normal (for example, haddock as it's own versioning scheme) the additional "ghc" suffix is used. Cabal already knows to look for this suffix so should work nicely with existing tooling. - - - - - 06aa8da5 by Sebastian Graf at 2021-08-23T13:34:51-04:00 Pmc: Better SCC annotations and trace output While investigating #20106, I made a few refactorings to the pattern-match checker that I don't want to lose. Here are the changes: * Some key functions of the checker now have SCC annotations * Better `-ddump-ec-trace` diagnostics for easier debugging. I added 'traceWhenFailPm' to see *why* a particular `MaybeT` computation fails and made use of it in `instCon`. I also increased the acceptance threshold of T11545, which seems to fail randomly lately due to ghc/max flukes. - - - - - c1acfd21 by Matthew Pickering at 2021-08-23T13:35:26-04:00 driver: Only check for unused package warning in after succesful downsweep Before we would check for the unused package warning even if the module graph was compromised due to an error in downsweep. This is easily fixed by pushing warmUnusedPackages into depanalE, and then returning the errors like the other downsweep errors. Fixes #20242 - - - - - f3892b5f by Krzysztof Gogolewski at 2021-08-23T13:36:00-04:00 Convert lookupIdSubst panic back to a warning (#20200) - - - - - c0407538 by Andreas Abel at 2021-08-23T13:36:38-04:00 Doc fix #20259: suggest bang patterns instead of case in hints.rst - - - - - d94e7ebd by Andreas Abel at 2021-08-23T13:37:15-04:00 Doc fix #20226: formatting issues in 9.2.1 release notes RST is brittle... - - - - - 8a939b40 by sheaf at 2021-08-23T23:39:15-04:00 TcPlugins: solve and report contras simultaneously This changes the TcPlugin datatype to allow type-checking plugins to report insoluble constraints while at the same time solve some other constraints. This allows better error messages, as the plugin can still simplify constraints, even when it wishes to report a contradiction. Pattern synonyms TcPluginContradiction and TcPluginOk are provided for backwards compatibility: existing type-checking plugins should continue to work without modification. - - - - - 03fc0393 by Matthew Pickering at 2021-08-23T23:39:49-04:00 driver: Correctly pass custom messenger to logging function This was an oversight from !6718 - - - - - 64696202 by Matthew Pickering at 2021-08-23T23:39:49-04:00 driver: Initialise common plugins once, before starting the pipeline This fixes an error message regression and is a slight performance improvement. See #20250 - - - - - 886ecd31 by Matthew Pickering at 2021-08-23T23:39:49-04:00 Add plugin-recomp-change-2 test This test tests that if there are two modules which use a plugin specified on the command line then both are recompiled when the plugin changes. - - - - - 31752b55 by Matthew Pickering at 2021-08-24T11:03:01-04:00 hadrian: Use cp -RP rather than -P in install to copy symlinks For some inexplicable reason `-P` only takes effect on the mac version of p when you also pass `-R`. > Symbolic links are always followed unless the -R flag is set, in which case symbolic > links are not followed, by default. > -P If the -R option is specified, no symbolic links are followed. This is the > default. Fixes #20254 - - - - - fdb2bfab by Fendor at 2021-08-24T11:03:38-04:00 Export PreloadUnitClosure as it is part of the public API - - - - - 71e8094d by Matthew Pickering at 2021-08-24T17:23:58+01:00 Fix colourised output in error messages This fixes a small mistake in 4dc681c7c0345ee8ae268749d98b419dabf6a3bc which forced the dump rather than user style for error messages. In particular, this change replaced `defaultUserStyle` with `log_default_dump_context` rather than `log_default_user_context` which meant the PprStyle was PprDump rather than PprUser for error messages. https://gitlab.haskell.org/ghc/ghc/-/commit/4dc681c7c0345ee8ae268749d98b419dabf6a3bc?expanded=1&page=4#b62120081f64009b94c12d04ded5c68870d8c647_285_405 Fixes #20276 - - - - - 0759c069 by Ryan Scott at 2021-08-25T19:35:12-04:00 Desugarer: Bring existentials in scope when substituting into record GADTs This fixes an outright bug in which the desugarer did not bring the existentially quantified type variables of a record GADT into `in_subst`'s in-scope set, leading to #20278. It also addresses a minor inefficiency in which `out_subst` was made into a substitution when a simpler `TvSubstEnv` would suffice. Fixes #20278. - - - - - b3653351 by Sebastian Graf at 2021-08-26T13:39:34-04:00 CallArity: Consider shadowing introduced by case and field binders In #20283, we saw a regression in `simple` due to CallArity for a very subtle reason: It simply didn't handle shadowing of case binders and constructor field binders! The test case T20283 has a very interesting binding `n_X1` that we want to eta-expand and that has a Unique (on GHC HEAD) that is reused by the Simplifier for a case binder: ``` let { n_X1 = ... } in ... let { lvl_s1Ul = ... case x_a1Rg of wild_X1 { __DEFAULT -> f_s1Tx rho_value_awA (GHC.Types.I# wild_X1); 0# -> lvl_s1TN } ... } in letrec { go3_X3 = \ (x_X4 :: GHC.Prim.Int#) (v_a1P9 [OS=OneShot] :: Double) -> let { karg_s1Wu = ... case lvl_s1Ul of { GHC.Types.D# y_a1Qf -> ... } } in case GHC.Prim.==# x_X4 y_a1R7 of { __DEFAULT -> go3_X3 (GHC.Prim.+# x_X4 1#) karg_s1Wu; 1# -> n_X1 karg_s1Wu -- Here we will assume that karg calls n_X1! }; } in go3_X3 0#; ``` Since the Case case of CallArity doesn't delete `X1` from the set of variables it is interested in knowing the usages of, we leak a very boring usage (of the case binder!) into the co-call graph that we mistakenly take for a usage of `n_X1`. We conclude that `lvl_s1Ul` and transitively `karg_s1Wu` call `n_X1` when really they don't. That culminates in the conclusion that `n_X1 karg_s1Wu` calls `n_X1` more than once. Wrong! Fortunately, this bug (which has been there right from CallArity's inception, I suppose) will never lead to a CallArity that is too optimistic. So by fixing this bug, we get strictly more opportunities for CallArity and all of them should be sound to exploit. Fixes #20283. - - - - - d551199c by Simon Peyton Jones at 2021-08-26T13:40:09-04:00 Fix GHC.Core.Subst.substDVarSet substDVarSet looked up coercion variables in the wrong environment! The fix is easy. It is still a pretty strange looking function, but the bug is gone. This fixes another manifestation of #20200. - - - - - 14c80432 by Aaron Allen at 2021-08-27T17:37:42-04:00 GHC.Tc.Gen Diagnostics Conversion (Part 1) Converts uses of `TcRnUnknownMessage` in these modules: - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - - - - - e28773fc by David Feuer at 2021-08-27T17:38:19-04:00 Export Solo from Data.Tuple * The `Solo` type is intended to be the canonical lifted unary tuple. Up until now, it has only been available from `GHC.Tuple` in `ghc-prim`. Export it from `Data.Tuple` in `base`. I proposed this on the libraries list in December, 2020. https://mail.haskell.org/pipermail/libraries/2020-December/031061.html Responses from chessai https://mail.haskell.org/pipermail/libraries/2020-December/031062.html and George Wilson https://mail.haskell.org/pipermail/libraries/2021-January/031077.html were positive. There were no other responses. * Add Haddock documentation for Solo. * Give `Solo` a single field, `getSolo`, a custom `Show` instance that does *not* use record syntax, and a `Read` instance that accepts either record syntax or non-record syntax. - - - - - 38748530 by Aaron Allen at 2021-08-27T22:19:23-05:00 Convert IFace Rename Errors (#19927) Converts uses of TcRnUnknownMessage in GHC.Iface.Rename. Closes #19927 - - - - - 8057a350 by ARATA Mizuki at 2021-08-28T14:25:14-04:00 AArch64 NCG: Emit FABS instructions for fabsFloat# and fabsDouble# Closes #20275 - - - - - 922c6bc8 by ARATA Mizuki at 2021-08-28T14:25:14-04:00 Add a test for #20275 - - - - - af41496f by hainq at 2021-09-01T15:09:08+07:00 Convert diagnostics in GHC.Tc.Validity to proper TcRnMessage. - Add 19 new messages. Update test outputs accordingly. - Pretty print suggest-extensions hints: remove space before interspersed commas. - Refactor Rank's MonoType constructors. Each MonoType constructor should represent a specific case. With the Doc suggestion belonging to the TcRnMessage diagnostics instead. - Move Rank from Validity to its own `GHC.Tc.Types.Rank` module. - Remove the outdated `check_irred_pred` check. - Remove the outdated duplication check in `check_valid_theta`, which was subsumed by `redundant-constraints`. - Add missing test cases for quantified-constraints/T16474 & th/T12387a. - - - - - 5b413533 by Peter Lebbing at 2021-09-06T12:14:35-04:00 fromEnum Natural: Throw error for non-representable values Starting with commit fe770c21, an error was thrown only for the values 2^63 to 2^64-1 inclusive (on a 64-bit machine), but not for higher values. Now, errors are thrown for all non-representable values again. Fixes #20291 - - - - - 407d3b3a by Alan Zimmerman at 2021-09-06T22:57:55-04:00 EPA: order of semicolons and comments for top-level decls is wrong A comment followed by a semicolon at the top level resulted in the preceding comments being attached to the following declaration. Capture the comments as belonging to the declaration preceding the semicolon instead. Closes #20258 - - - - - 89820293 by Oleg Grenrus at 2021-09-06T22:58:32-04:00 Define returnA = id - - - - - 3fb1afea by Sylvain Henry at 2021-09-06T22:59:10-04:00 GHCi: don't discard plugins on reload (#20335) Fix regression introduced in ecfd0278 - - - - - f72aa31d by Sylvain Henry at 2021-09-07T08:02:28-04:00 Bignum: refactor conversion rules * make "passthrough" rules non built-in: they don't need to * enhance note about efficient conversions between numeric types * make integerFromNatural a little more efficient * fix noinline pragma for naturalToWordClamp# (at least with non built-in rules, we get warnings in cases like this) - - - - - 81975ef3 by Ben Gamari at 2021-09-07T08:03:03-04:00 hadrian: Ensure that settings is regenerated during bindist installation Previously Hadrian would simply install the settings file generated in the build environment during the binary distribution installation. This is wrong since these environments may differ (e.g. different `cc` versions). We noticed on Darwin when installation of a binary distribution produced on a newer Darwin release resulted in a broken compiler due to the installed `settings` file incorrectly claiming that `cc` supported `-no-pie`. Fixing this sadly requires a bit of code duplication since `settings` is produced by Hadrian and not `configure`. For now I have simply duplicated the `settings` generation logic used by the Make build system into Hadrian's bindist Makefile. Ultimately the solution will probably involve shipping a freestanding utility to replace `configure`'s toolchain probing logic and generate a toolchain description file (similar to `settings`) as described in #19877. Fixes #20253. - - - - - 2735f5a6 by Ben Gamari at 2021-09-07T08:03:03-04:00 gitlab-ci: Fix bash version-dependence in ci.sh As described in https://stackoverflow.com/questions/7577052, safely expanding bash arrays is very-nearly impossible. The previous incantation failed under the bash version shipped with Centos 7. - - - - - 7fa8c32c by Alfredo Di Napoli at 2021-09-07T12:24:12-04:00 Add and use new constructors to TcRnMessage This commit adds the following constructors to the TcRnMessage type and uses them to replace sdoc-based diagnostics in some parts of GHC (e.g. TcRnUnknownMessage). It includes: * Add TcRnMonomorphicBindings diagnostic * Convert TcRnUnknownMessage in Tc.Solver.Interact * Add and use the TcRnOrphanInstance constructor to TcRnMessage * Add TcRnFunDepConflict and TcRnDupInstanceDecls constructors to TcRnMessage * Add and use TcRnConflictingFamInstDecls constructor to TcRnMessage * Get rid of TcRnUnknownMessage from GHC.Tc.Instance.Family - - - - - 6ea9b3ee by ARATA Mizuki at 2021-09-07T12:24:49-04:00 Fix code example in the documentation of subsumption - - - - - beef6135 by John Ericson at 2021-09-08T02:57:55-04:00 Let LLVM and C handle > native size arithmetic NCG needs to call slow FFI functions where we "borrow" the C compiler's implementation, but there is no reason why we need to do that for LLVM, or the unregisterized backend where everything is via C anyways! - - - - - 5b5c2452 by Jens Petersen at 2021-09-08T02:58:33-04:00 base Data.Fixed: fix documentation typo: succ (0.000 :: Milli) /= 1.001 ie `succ (0000) == 0001` -- (not 1001) - - - - - 7a4bde22 by Joshua Price at 2021-09-08T02:59:10-04:00 Fix broken haddock @since fields in base - - - - - ebbb1fa2 by Guillaume Bouchard at 2021-09-08T02:59:47-04:00 base: Numeric: remove 'Show' constraint on 'showIntAtBase' The constraint was there in order to show the 'Integral' value in case of error. Instead we can show the result of `toInteger`, which will be close (i.e. it will still show the same integer except if the 'Show' instance was funky). This changes a bit runtime semantic (i.e. exception string may be a bit different). - - - - - fb1e0a5d by Matthew Pickering at 2021-09-08T03:00:22-04:00 ffi: Don't allow wrapper stub with CApi convention Fixes #20272 - - - - - dcc1599f by Krzysztof Gogolewski at 2021-09-08T03:00:57-04:00 Minor doc fixes - Fix markup in 9.4 release notes - Document -ddump-cs-trace - Mention that ImpredicativeTypes is really supported only since 9.2 - Remove "There are some restrictions on the use of unboxed tuples". This used to be a list, but all those restrictions were removed. - Mark -fimplicit-import-qualified as documented - Remove "The :main and :run command" - duplicated verbatim in options - Avoid calling "main" a function (cf. #7816) - Update System.getArgs: the old location was before hierarchical modules - Note that multiplicity multiplication is not supported (#20319) - - - - - 330e6e9c by Krzysztof Gogolewski at 2021-09-08T03:00:57-04:00 Documentation: use https links - - - - - 9fc0fe00 by Ben Gamari at 2021-09-08T03:01:32-04:00 rts: Factor out TRACE_ cache update logic Just a small refactoring to perhaps enable code reuse later. - - - - - 86e5a6c3 by Alan Zimmerman at 2021-09-08T16:58:51-04:00 EPA: Capture '+' location for NPlusKPat The location of the plus symbol was being discarded, we now capture it. Closes #20243 - - - - - 87d93745 by Sylvain Henry at 2021-09-08T16:59:29-04:00 Only dump Core stats when requested to do so (#20342) - - - - - 74a87aa3 by Ben Gamari at 2021-09-11T08:53:50-04:00 distrib: Drop FP_GMP from configure script None of the configure options defined by `FP_GMP` are applicable to binary distributions. - - - - - 089de88e by Sylvain Henry at 2021-09-11T08:54:29-04:00 Canonicalize bignum literals Before this patch Integer and Natural literals were desugared into "real" Core in Core prep. Now we desugar them directly into their final ConApp form in HsToCore. We only keep the double representation for BigNat# (literals larger than a machine Word/Int) which are still desugared in Core prep. Using the final form directly allows case-of-known-constructor to fire for bignum literals, fixing #20245. Slight increase (+2.3) in T4801 which is a pathological case with Integer literals. Metric Increase: T4801 T11545 - - - - - f987ec1a by nineonine at 2021-09-11T08:55:06-04:00 Add test for #18181 - - - - - 5615737a by Oleg Grenrus at 2021-09-11T08:55:43-04:00 Remove dubious Eq1 and Ord1 Fixed instances. Fixes #20309 - - - - - 88f871ef by nineonine at 2021-09-11T08:56:20-04:00 Add performance test for #19695 - - - - - c3776542 by Ben Gamari at 2021-09-11T08:56:55-04:00 Ensure that zapFragileUnfolding preseves evaluatedness As noted in #20324, previously we would drop the fact that an unfolding was evaluated, despite what the documentation claims. - - - - - 070ae69c by Ben Gamari at 2021-09-11T08:57:29-04:00 ncg: Kill incorrect unreachable code As noted in #18183, these cases were previously incorrect and unused. Closes #18183. - - - - - 2d151752 by Sebastian Graf at 2021-09-11T08:58:04-04:00 Break recursion in GHC.Float.roundingMode# (#20352) Judging from the Assumption, we should never call `roundingMode#` on a negative number. Yet the strange "dummy" conversion from `IN` to `IP` and the following recursive call where making the function recursive. Replacing the call by a panic makes `roundingMode#` non-recursive, so that we may be able to inline it. Fixes #20352. It seems we trigger #19414 on some jobs, hence Metric Decrease: T12545 - - - - - 7bfa8955 by CarrieMY at 2021-09-13T09:35:07-04:00 Fix #20203 improve constant fold for `and`/`or` This patch follows the rules specified in note [Constant folding through nested expressions]. Modifications are summarized below. - Added andFoldingRules, orFoldingRules to primOpRules under those xxxxAndOp, xxxxOrOp - Refactored some helper functions - Modify data NumOps to include two fields: numAnd and numOr Resolves: #20203 See also: #19204 - - - - - dda61f79 by Ben Gamari at 2021-09-13T09:35:44-04:00 Don't depend unconditionally on xattr in darwin_install Previously the Darwin installation logic would attempt to call xattr unconditionally. This would break on older Darwin releases where this utility did not exist. - - - - - 3c885880 by Ben Gamari at 2021-09-13T09:36:20-04:00 testsuite: Mark hDuplicateTo001 as fragile in concurrent ways As noted in #17568. - - - - - a2a16e4c by Ben Gamari at 2021-09-13T09:36:54-04:00 hadrian: Recommend use of +werror over explicit flavour modification As noted in #20327, the previous guidance was out-of-date. - - - - - 64923cf2 by Joshua Price at 2021-09-13T09:37:31-04:00 Add test for #17865 - - - - - 885f17c8 by Christiaan Baaij at 2021-09-17T09:35:18-04:00 Improve error messages involving operators from Data.Type.Ord Fixes #20009 - - - - - 4564f00f by Krzysztof Gogolewski at 2021-09-17T09:35:53-04:00 Improve pretty-printer defaulting logic (#19361) When determining whether to default a RuntimeRep or Multiplicity variable, use isMetaTyVar to distinguish between metavariables (which can be hidden) and skolems (which cannot). - - - - - 6a7ae5ed by Tito Sacchi at 2021-09-17T09:36:31-04:00 Emit warning if bang is applied to unlifted types GHC will trigger a warning similar to the following when a strictness flag is applied to an unlifted type (primitive or defined with the Unlifted* extensions) in the definition of a data constructor. Test.hs:7:13: warning: [-Wredundant-strictness-flags] • Strictness flag has no effect on unlifted type ‘Int#’ • In the definition of data constructor ‘TestCon’ In the data type declaration for ‘Test’ | 7 | data Test = TestCon !Int# | ^^^^^^^^^^^^^ Fixes #20187 - - - - - 0d996d02 by Ben Gamari at 2021-09-17T09:37:06-04:00 testsuite: Add test for #18382 - - - - - 9300c736 by Alan Zimmerman at 2021-09-17T09:37:41-04:00 EPA: correctly capture comments between 'where' and binds In the following foo = x where -- do stuff doStuff = do stuff The "-- do stuff" comment is captured in the HsValBinds. Closes #20297 - - - - - bce230c2 by Artem Pelenitsyn at 2021-09-17T09:38:19-04:00 driver: -M allow omitting the -dep-suffix (means empty) (fix #15483) - - - - - 01e07ab1 by Ziyang Liu at 2021-09-17T09:38:56-04:00 Ensure .dyn_hi doesn't overwrite .hi This commit fixes the following bug: when `outputHi` is set, and both `.dyn_hi` and `.hi` are needed, both would be written to `outputHi`, causing `.dyn_hi` to overwrite `.hi`. This causes subsequent `readIface` to fail - "mismatched interface file profile tag (wanted "", got "dyn")" - triggering unnecessary rebuild. - - - - - e7c2ff88 by Sven Tennie at 2021-09-17T09:39:31-04:00 Add compile_flags.txt for clangd (C IDE) support This file configures clangd (C Language Server for IDEs) for the GHC project. Please note that this only works together with Haskell Language Server, otherwise .hie-bios/stage0/lib does not exist. - - - - - aa6caab0 by Thomas M. DuBuisson at 2021-09-17T09:40:09-04:00 Update error message to suggest the user consider OOM over RTS bug. Fix #17039 - - - - - bfddee13 by Matthew Pickering at 2021-09-17T09:40:44-04:00 Stop leaking <defunct> llc processes We needed to wait for the process to exit in the clean-up script as otherwise the `llc` process will not be killed until compilation finishes. This leads to running out of process spaces on some OSs. Thanks to Edsko de Vries for suggesting this fix. Fixes #20305 - - - - - a6529ffd by Matthew Pickering at 2021-09-17T09:41:20-04:00 driver: Clean up temporary files after a module has been compiled The refactoring accidently removed these calls to eagerly remove temporary files after a module has been compiled. This caused some issues with tmpdirs getting filled up on my system when the project had a large number of modules (for example, Agda) Fixes #20293 - - - - - 4a7f8d5f by Matthew Pickering at 2021-09-17T09:41:55-04:00 Remove Cabal dependency from check-exact and check-ppr executables Neither uses anything from Cabal, so the dependency can just be removed. - - - - - 987180d4 by Ben Gamari at 2021-09-17T09:42:30-04:00 testsuite: Add broken testcase for #19350 - - - - - ef8a3fbf by Ben Gamari at 2021-09-17T09:42:30-04:00 ghc-boot: Fix metadata handling of writeFileAtomic Previously the implementation of writeFileAtomic (which was stolen from Cabal) failed to preserve file mode, user and group, resulting in #14017. Fixes #14017. - - - - - 18283be3 by Ben Gamari at 2021-09-17T09:43:05-04:00 compiler: Ensure that all CoreTodos have SCCs In #20365 we noticed that a significant amount of time is spend in the Core2Core cost-center, suggesting that some passes are likely missing SCC pragmas. Try to fix this. - - - - - 15a5b7a5 by Matthew Pickering at 2021-09-17T09:43:40-04:00 Add "ipe" flavour transformer to add support for building with IPE debug info The "ipe" transformer compilers everything in stage2 with `-finfo-table-map` and `-fdistinct-constructor-tables` to produce a compiler which is usable with `-hi` profiling and ghc-debug. - - - - - 053a5c2c by Ziyang Liu at 2021-09-17T09:44:18-04:00 Add doc for -dyno, -dynosuf, -dynhisuf - - - - - 9eff805a by Matthew Pickering at 2021-09-17T09:44:53-04:00 Code Gen: Use strict map rather than lazy map in loop analysis We were ending up with a big 1GB thunk spike as the `fmap` operation did not force the key values promptly. This fixes the high maximum memory consumption when compiling the mmark package. Compilation is still slow and allocates a lot more than previous releases. Related to #19471 - - - - - 44e7120d by Matthew Pickering at 2021-09-17T09:44:53-04:00 Code Gen: Replace another lazy fmap with strict mapMap - - - - - b041ea77 by Matthew Pickering at 2021-09-17T09:44:53-04:00 Code Gen: Optimise successors calculation in loop calculation Before this change, the whole map would be traversed in order to delete a node from the graph before calculating successors. This is quite inefficient if the CFG is big, as was the case in the mmark package. A more efficient alternative is to leave the CFG untouched and then just delete the node once after the lookups have been performed. Ticket: #19471 - - - - - 53dc8e41 by Matthew Pickering at 2021-09-17T09:44:53-04:00 Code Gen: Use more efficient block merging algorithm The previous algorithm scaled poorly when there was a large number of blocks and edges. The algorithm links together block chains which have edges between them in the CFG. The new algorithm uses a union find data structure in order to efficiently merge together blocks and calculate which block chain each block id belonds to. I copied the UnionFind data structure which already existed in Cabal into the GHC library rathert than reimplement it myself. This change results in a very significant reduction in allocations when compiling the mmark package. Ticket: #19471 - - - - - c480f8f2 by Matthew Pickering at 2021-09-17T09:44:53-04:00 Code Gen: Rewrite shortcutWeightMap more efficiently This function was one of the main sources of allocation in a ticky profile due to how it repeatedly deleted nodes from a large map. Now firstly the cuts are normalised, so that chains of cuts are elimated before any rewrites are applied. Then the CFG is traversed and reconstructed once whilst applying the necessary rewrites to remove shortcutted edges (based on the normalised cuts). Ticket: #19471 - - - - - da60e627 by Sylvain Henry at 2021-09-17T09:45:36-04:00 Fix annoying warning about Data.List unqualified import - - - - - c662ac7e by Sylvain Henry at 2021-09-17T09:45:36-04:00 Refactor module dependencies code * moved deps related code into GHC.Unit.Module.Deps * refactored Deps module to not export Dependencies constructor to help maintaining invariants - - - - - f6a69fb8 by Sylvain Henry at 2021-09-17T09:45:36-04:00 Use an ADT for RecompReason - - - - - d41cfdd4 by Sylvain Henry at 2021-09-17T09:46:15-04:00 Constant folding for ctz/clz/popCnt (#20376) - - - - - 20e6fec8 by Matthew Pickering at 2021-09-17T09:46:51-04:00 Testsuite: Mark T12903 as fragile on i386 Closes #20377 - - - - - 7bc16521 by David Feuer at 2021-09-18T12:01:10-04:00 Add more instances for Solo Oleg Grenrus pointed out that `Solo` was missing `Eq`, `Ord`, `Bounded`, `Enum`, and `Ix` instances, which were all apparently available for the `OneTuple` type (in the `OneTuple` package). Though only the first three really seem useful, there's no reason not to take them all. For `Ix`, `Solo` naturally fills a gap between `()` and `(,)`. - - - - - 4d245e54 by Sebastian Graf at 2021-09-18T12:01:44-04:00 WorkWrap: Update Note [Wrapper activation] (#15056) The last point of the Conclusion was wrong; we inline functions without pragmas after the initial phase. It also appears that #15056 was fixed, as there already is a test T15056 which properly does foldr/build fusion for the reproducer. I made sure that T15056's `foo` is just large enough for WW to happen (which it wasn't), but for the worker to be small enough to inline into `blam`. Fixes #15056. - - - - - 2c28919f by Sebastian Graf at 2021-09-18T12:01:44-04:00 CoreUtils: Make exprIsHNF return True for unlifted variables (#20140) Clearly, evaluating an unlifted variable will never perform any work. Fixes #20140. - - - - - e17a37df by Joaquin "Florius" Azcarate at 2021-09-18T12:02:21-04:00 Fix formatting of link in base/Type.Reflection - - - - - 78d27dd8 by Matthew Pickering at 2021-09-18T12:02:56-04:00 docs: Fix examples for (un)escapeArgs The examples were just missing the surrounding brackets. ghci> escapeArgs ["hello \"world\""] "hello\\ \\\"world\\\"\n" Fixes #20340 - - - - - 1350c220 by Matthew Pickering at 2021-09-18T12:03:31-04:00 deriving: Always use module prefix in dataTypeName This fixes a long standard bug where the module prefix was omitted from the data type name supplied by Data.Typeable instances. Instead of reusing the Outputable instance for TyCon, we now take matters into our own hands and explicitly print the module followed by the type constructor name. Fixes #20371 - - - - - 446ca8b9 by Ben Gamari at 2021-09-18T12:04:06-04:00 users-guide: Improve documentation of ticky events - - - - - d99fc250 by Matthew Pickering at 2021-09-18T12:04:41-04:00 hadrian: Disable verbose timing information Before the output contain a lot of verbose information about timining various things to do with shake which wasn't so useful for developers. ``` shakeArgsWith 0.000s 0% Function shake 0.010s 0% Database read 0.323s 12% === With database 0.031s 1% Running rules 2.301s 86% ========================= Pool finished (1786 threads, 5 max) 0.003s 0% Cleanup 0.000s 0% Total 2.669s 100% Build completed in 2.67s ``` Now the output just contains the last line ``` Build completed in 2.67s ``` Ticket #20381 - - - - - 104bf6bf by Oleg Grenrus at 2021-09-22T08:23:08-04:00 Clarify that malloc, free etc. are the ones from stdlib.h - - - - - bb37026e by Aaron Allen at 2021-09-22T08:23:45-04:00 Convert Diagnostics in GHC.Tc.Gen.* (Part 2) Converts diagnostics in: (#20116) - GHC.Tc.Gen.Default - GHC.Tc.Gen.Export - - - - - 92257abd by Sylvain Henry at 2021-09-22T08:24:23-04:00 Link with libm dynamically (#19877) The compiler should be independent of the target. - - - - - b47fafd9 by alirezaghey at 2021-09-22T08:25:00-04:00 Fix minor inconsistency in documentation fixes #20388 - - - - - 3d328eb5 by Benjamin Maurer at 2021-09-22T08:25:37-04:00 Remove unused, undocumented debug/dump flag `-ddump-vt-trace`. See 20403. - - - - - 65c837a3 by Matthew Pickering at 2021-09-23T10:44:19+01:00 Typo [skip ci] - - - - - 69b35afd by Sven Tennie at 2021-09-23T15:59:38-04:00 deriveConstants: Add hie.yaml - - - - - 022d9717 by Sven Tennie at 2021-09-23T15:59:38-04:00 base: Generalize newStablePtrPrimMVar Make it polymorphic in the type of the MVar's value. This simple generalization makes it usable for `MVar a` instead of only `MVar ()` values. - - - - - 6f7f5990 by Sven Tennie at 2021-09-23T15:59:38-04:00 Introduce stack snapshotting / cloning (#18741) Add `StackSnapshot#` primitive type that represents a cloned stack (StgStack). The cloning interface consists of two functions, that clone either the treads own stack (cloneMyStack) or another threads stack (cloneThreadStack). The stack snapshot is offline/cold, i.e. it isn't evaluated any further. This is useful for analyses as it prevents concurrent modifications. For technical details, please see Note [Stack Cloning]. Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 29717ecb by Sven Tennie at 2021-09-23T15:59:38-04:00 Use Info Table Provenances to decode cloned stack (#18163) Emit an Info Table Provenance Entry (IPE) for every stack represeted info table if -finfo-table-map is turned on. To decode a cloned stack, lookupIPE() is used. It provides a mapping between info tables and their source location. Please see these notes for details: - [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)] - [Mapping Info Tables to Source Positions] Metric Increase: T12545 - - - - - aafda13d by Ben Gamari at 2021-09-23T16:00:17-04:00 ci: Drop redundant `cabal update`s `cabal update` is already implied by `ci.sh setup`. - - - - - ca88d91c by Ben Gamari at 2021-09-23T16:00:17-04:00 ci: Consolidate handling of cabal cache Previously the cache persistence was implemented as various ad-hoc `cp` commands at the end of the individual CI scripts. Here we move all of this logic into `ci.sh`. - - - - - cbfc0e93 by Ben Gamari at 2021-09-23T16:00:17-04:00 ci: Isolate build from HOME - - - - - 55112fbf by Ben Gamari at 2021-09-23T16:00:17-04:00 ci: Move phase timing logic into ci.sh - - - - - be11120f by Ben Gamari at 2021-09-23T16:00:17-04:00 ci: More surgical use of nix in Darwin builds - - - - - f48d747d by Ben Gamari at 2021-09-23T16:00:17-04:00 configure: Move nm search logic to new file - - - - - ee7bdc5c by Ben Gamari at 2021-09-23T16:00:18-04:00 configure: Add check for whether CC supports --target - - - - - 68509e1c by Ben Gamari at 2021-09-23T16:00:18-04:00 ci: Add version to cache key - - - - - dae4a068 by Ben Gamari at 2021-09-23T16:00:18-04:00 gitlab-ci: Ensure that CABAL_DIR is a Windows path Otherwise cabal-install falls over. - - - - - 1c91e721 by Ben Gamari at 2021-09-23T16:00:18-04:00 gitlab-ci: Use correct CABAL executable - - - - - 8a6598c7 by Ben Gamari at 2021-09-23T16:00:18-04:00 Ensure that cabal update is invoked before building - - - - - d7ee5295 by Ben Gamari at 2021-09-23T16:00:18-04:00 gitlab-ci: bash fixes - - - - - 98a30147 by GHC GitLab CI at 2021-09-23T16:00:18-04:00 hadrian: Pass CFLAGS to gmp configure - - - - - 02827066 by Ben Gamari at 2021-09-23T16:00:18-04:00 configure: Fix copy/paste error Previously both the --with-system-libffi path and the non--with-system-libffi path set CabalUseSystemLibFFI=True. This was wrong. - - - - - 316ac68f by Ben Gamari at 2021-09-23T16:00:18-04:00 configure: Clarify meaning of CabalHaveLibffi Previously the meaning of this flag was unclear and as a result I suspect that CabalHaveLibffi could be incorrectly False. - - - - - 552b32f1 by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Pass CFLAGS to hsc2hs tests - - - - - 7e19cb1c by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Fix ipeMap ipeMap.c failed to #include <string.h> - - - - - c9a87dca by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Make unsigned_reloc_macho_x64 and section_alignment makefile_tests - - - - - b30f90c4 by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Don't use cc directly in section_alignment test - - - - - a940ba7f by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Fix gnu sed-ism The BSD sed implementation doesn't allow `sed -i COMMAND FILE`; one must rather use `sed -i -e COMMAND FILE`. - - - - - e78752df by Ben Gamari at 2021-09-23T16:00:18-04:00 rts: Ensure that headers don't refer to undefined __STDC_VERSION__ Previously the C/C++ language version check in STG could throw an undefined macro warning due to __STDC_VERSION__ when compiled with a C++ compiler. Fix this by defining __STDC_VERSION__==0 when compiling with a C++ compiler. Fixes #20394. - - - - - 6716a4bd by Ben Gamari at 2021-09-23T16:00:18-04:00 gitlab-ci: Unset MACOSX_DEPLOYMENT_TARGET in stage0 build Otherwise we may get warnings from the toolchain if the bootstrap compiler was built with a different deployment target. - - - - - ac378d3e by Ben Gamari at 2021-09-23T16:00:18-04:00 testsuite: Ensure that C++11 is used in T20199 Otherwise we are dependent upon the C++ compiler's default language. - - - - - 33eb4a4e by Sylvain Henry at 2021-09-23T16:01:00-04:00 Constant-folding for timesInt2# (#20374) - - - - - 4b7ba3ae by Ben Gamari at 2021-09-24T23:14:31-04:00 gitlab-ci: Don't rely on $HOME when pushing test metrics As of cbfc0e933660626c9f4eaf5480076b6fcd31dceb we set $HOME to a non-existent directory to ensure hermeticity. - - - - - 8127520e by Ben Gamari at 2021-09-27T16:06:04+00:00 gitlab-ci: Ensure that temporary home exists - - - - - 0da019be by Artyom Kuznetsov at 2021-09-28T01:51:48-04:00 Remove NoGhcTc usage from HsMatchContext NoGhcTc is removed from HsMatchContext. As a result of this, HsMatchContext GhcTc is now a valid type that has Id in it, instead of Name and tcMatchesFun now takes Id instead of Name. - - - - - e38facf8 by Matthew Pickering at 2021-09-28T01:52:23-04:00 driver: Fix Ctrl-C handling with -j1 Even in -j1 we now fork all the work into it's own thread so that Ctrl-C exceptions are thrown on the main thread, which is blocked waiting for the work thread to finish. The default exception handler then picks up Ctrl-C exception and the dangling thread is killed. Fixes #20292 - - - - - 45a674aa by Sylvain Henry at 2021-09-28T01:53:01-04:00 Add `-dsuppress-core-sizes` flag (#20342) This flag is used to remove the output of core stats per binding in Core dumps. - - - - - 1935c42f by Matthew Pickering at 2021-09-28T01:53:36-04:00 hadrian: Reduce default verbosity This change reduces the default verbosity of error messages to omit the stack trace information from the printed output. For example, before all errors would have a long call trace: ``` Error when running Shake build system: at action, called at src/Rules.hs:39:19 in main:Rules at need, called at src/Rules.hs:61:5 in main:Rules * Depends on: _build/stage1/lib/package.conf.d/ghc-9.3.conf * Depends on: _build/stage1/compiler/build/libHSghc-9.3.a * Depends on: _build/stage1/compiler/build/GHC/Tc/Solver/Rewrite.o * Depends on: _build/stage1/compiler/build/GHC/Tc/Solver/Rewrite.o _build/stage1/compiler/build/GHC/Tc/Solver/Rewrite.hi at cmd', called at src/Builder.hs:330:23 in main:Builder at cmd, called at src/Builder.hs:432:8 in main:Builder * Raised the exception: ``` Which can be useful but it confusing for GHC rather than hadrian developers. Ticket #20386 - - - - - 219f7f50 by Matthew Pickering at 2021-09-28T01:53:36-04:00 hadrian: Remove deprecated tracing functions - - - - - 28963690 by Matthew Pickering at 2021-09-28T01:53:36-04:00 hadrian: Rework the verbosity levels Before we really only had two verbosity levels, normal and verbose. There are now three levels: Normal: Commands show stderr (no stdout) and minimal build failure messages. Verbose (-V): Commands also show stdout, build failure message contains callstack and additional information Diagnostic (-VV): Very verbose output showing all command lines and passing -v3 to cabal commands. -V is similar to the default verbosity from before (but a little more verbose) - - - - - 66c85e2e by Matthew Pickering at 2021-09-28T01:53:36-04:00 ci: Increase default verbosity level to `-V` (Verbose) Given the previous commit, `-V` allows us to see some useful information in CI (such as the call stack on failure) which normally people don't want to see. As a result the $VERBOSE variable now tweaks the diagnostic level one level higher (to Diagnostic), which produces a lot of output. - - - - - 58fea28e by Matthew Pickering at 2021-09-28T01:53:36-04:00 hadrian: Update documentation for new verbosity options - - - - - 26f24aec by Matthew Pickering at 2021-09-28T01:53:36-04:00 hadrian: Update comments on verbosity handling - - - - - 62b4a89b by taylorfausak at 2021-09-28T09:57:37-04:00 Remove outdated note about pragma layout - - - - - 028abd5b by Benjamin Maurer at 2021-09-28T09:58:13-04:00 Documented yet undocumented dump flags #18641 - - - - - b8d98827 by Richard Eisenberg at 2021-09-29T09:40:14-04:00 Compare FunTys as if they were TyConApps. See Note [Equality on FunTys] in TyCoRep. Close #17675. Close #17655, about documentation improvements included in this patch. Close #19677, about a further mistake around FunTy. test cases: typecheck/should_compile/T19677 - - - - - be77a9e0 by Fabian Thorand at 2021-09-29T09:40:51-04:00 Remove special case for large objects in allocateForCompact allocateForCompact() is called when the current allocation for the compact region does not fit in the nursery. It previously had a special case for objects exceeding the large object threshold. In that case, it would allocate a new compact region block just for that object. That led to a lot of small blocks being allocated in compact regions with a larger default block size (`autoBlockW`). This commit removes this special case because having a lot of small compact region blocks contributes significantly to memory fragmentation. The removal should be valid because - a more generic case for allocating a new compact region block follows at the end of allocateForCompact(), and that one takes `autoBlockW` into account - the reason for allocating separate blocks for large objects in the main heap seems to be to avoid copying during GCs, but once inside the compact region, the object will never be copied anyway. Fixes #18757. A regression test T18757 was added. - - - - - cd603062 by Kirill Zaborsky at 2021-09-29T09:41:27-04:00 Fix comment typos - - - - - 162492ea by Alexander Kjeldaas at 2021-09-29T09:41:27-04:00 Document interaction between unsafe FFI and GC In the multi-threaded RTS this can lead to hard to debug performance issues. - - - - - 361da88a by Kamil Dworakowski at 2021-09-29T09:42:04-04:00 Add a regression test for #17912 - - - - - 5cc4bd57 by Benjamin Maurer at 2021-09-29T09:42:41-04:00 Rectifying COMMENT and `mkComment` across platforms to work with SDoc and exhibit similar behaviors. Issue 20400 - - - - - a2be9f34 by Ziyang Liu at 2021-09-29T09:43:19-04:00 Document that `eqType`/`coreView` do not look through type families This isn't clear from the existing doc. - - - - - c668fd2c by Andrea Condoluci at 2021-09-29T09:44:04-04:00 TH stage restriction check for constructors, selectors, and class methods Closes ticket #17820. - - - - - d46e34d0 by Andrea Condoluci at 2021-09-29T09:44:04-04:00 Add tests for T17820 - - - - - 770fcac8 by Ben Gamari at 2021-09-29T09:44:40-04:00 GHC: Drop dead packageDbModules It was already commented out and contained a reference to the non-deterministic nameEnvElts so let's just drop it. - - - - - 42492b76 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Reimplement seqEltsUFM in terms of fold Rather than nonDetEltsUFM; this should eliminate some unnecessary list allocations. - - - - - 97ffd6d9 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Rewrite all eltsUFM occurrences to nonDetEltsUFM And remove the former. - - - - - df8c5961 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Fix name of GHC.Core.TyCon.Env.nameEnvElts Rename to nonDetTyConEnvElts. - - - - - 1f2ba67a by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Make nubAvails deterministic Surprisingly this previously didn't appear to introduce any visible non-determinism but it seems worth avoiding non-determinism here. - - - - - 7c90a180 by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Rename nameEnvElts -> nonDetNameEnvElts - - - - - 2e68d4fa by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: Use seqEltsNameEnv rather that nameEnvElts - - - - - f66eaefd by Ben Gamari at 2021-09-29T09:44:40-04:00 compiler: occEnvElts -> nonDetOccEnvElts - - - - - 594ee2f4 by Matthew Pickering at 2021-09-30T00:56:30-04:00 testsuite: Make cabal01 more robust to large environments Sebastian unfortunately wrote a very long commit message in !5667 which caused `xargs` to fail on windows because the environment was too big. Fortunately `xargs` and `rm` don't need anything from the environment so just run those commands in an empty environment (which is what env -i achieves). - - - - - c261f220 by Sebastian Graf at 2021-09-30T00:56:30-04:00 Nested CPR light unleashed (#18174) This patch enables worker/wrapper for nested constructed products, as described in `Note [Nested CPR]`. The machinery for expressing Nested CPR was already there, since !5054. Worker/wrapper is equipped to exploit Nested CPR annotations since !5338. CPR analysis already handles applications in batches since !5753. This patch just needs to flip a few more switches: 1. In `cprTransformDataConWork`, we need to look at the field expressions and their `CprType`s to see whether the evaluation of the expressions terminates quickly (= is in HNF) or if they are put in strict fields. If that is the case, then we retain their CPR info and may unbox nestedly later on. More details in `Note [Nested CPR]`. 2. Enable nested `ConCPR` signatures in `GHC.Types.Cpr`. 3. In the `asConCpr` call in `GHC.Core.Opt.WorkWrap.Utils`, pass CPR info of fields to the `Unbox`. 4. Instead of giving CPR signatures to DataCon workers and wrappers, we now have `cprTransformDataConWork` for workers and treat wrappers by analysing their unfolding. As a result, the code from GHC.Types.Id.Make went away completely. 5. I deactivated worker/wrappering for recursive DataCons and wrote a function `isRecDataCon` to detect them. We really don't want to give `repeat` or `replicate` the Nested CPR property. See Note [CPR for recursive data structures] for which kind of recursive DataCons we target. 6. Fix a couple of tests and their outputs. I also documented that CPR can destroy sharing and lead to asymptotic increase in allocations (which is tracked by #13331/#19326) in `Note [CPR for data structures can destroy sharing]`. Nofib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- ben-raytrace -3.1% -0.4% binary-trees +0.8% -2.9% digits-of-e2 +5.8% +1.2% event +0.8% -2.1% fannkuch-redux +0.0% -1.4% fish 0.0% -1.5% gamteb -1.4% -0.3% mkhprog +1.4% +0.8% multiplier +0.0% -1.9% pic -0.6% -0.1% reptile -20.9% -17.8% wave4main +4.8% +0.4% x2n1 -100.0% -7.6% -------------------------------------------------------------------------------- Min -95.0% -17.8% Max +5.8% +1.2% Geometric Mean -2.9% -0.4% ``` The huge wins in x2n1 (loopy list) and reptile (see #19970) are due to refraining from unboxing (:). Other benchmarks like digits-of-e2 or wave4main regress because of that. Ultimately there are no great improvements due to Nested CPR alone, but at least it's a win. Binary sizes decrease by 0.6%. There are a significant number of metric decreases. The most notable ones (>1%): ``` ManyAlternatives(normal) ghc/alloc 771656002.7 762187472.0 -1.2% ManyConstructors(normal) ghc/alloc 4191073418.7 4114369216.0 -1.8% MultiLayerModules(normal) ghc/alloc 3095678333.3 3128720704.0 +1.1% PmSeriesG(normal) ghc/alloc 50096429.3 51495664.0 +2.8% PmSeriesS(normal) ghc/alloc 63512989.3 64681600.0 +1.8% PmSeriesV(normal) ghc/alloc 62575424.0 63767208.0 +1.9% T10547(normal) ghc/alloc 29347469.3 29944240.0 +2.0% T11303b(normal) ghc/alloc 46018752.0 47367576.0 +2.9% T12150(optasm) ghc/alloc 81660890.7 82547696.0 +1.1% T12234(optasm) ghc/alloc 59451253.3 60357952.0 +1.5% T12545(normal) ghc/alloc 1705216250.7 1751278952.0 +2.7% T12707(normal) ghc/alloc 981000472.0 968489800.0 -1.3% GOOD T13056(optasm) ghc/alloc 389322664.0 372495160.0 -4.3% GOOD T13253(normal) ghc/alloc 337174229.3 341954576.0 +1.4% T13701(normal) ghc/alloc 2381455173.3 2439790328.0 +2.4% BAD T14052(ghci) ghc/alloc 2162530642.7 2139108784.0 -1.1% T14683(normal) ghc/alloc 3049744728.0 2977535064.0 -2.4% GOOD T14697(normal) ghc/alloc 362980213.3 369304512.0 +1.7% T15164(normal) ghc/alloc 1323102752.0 1307480600.0 -1.2% T15304(normal) ghc/alloc 1304607429.3 1291024568.0 -1.0% T16190(normal) ghc/alloc 281450410.7 284878048.0 +1.2% T16577(normal) ghc/alloc 7984960789.3 7811668768.0 -2.2% GOOD T17516(normal) ghc/alloc 1171051192.0 1153649664.0 -1.5% T17836(normal) ghc/alloc 1115569746.7 1098197592.0 -1.6% T17836b(normal) ghc/alloc 54322597.3 55518216.0 +2.2% T17977(normal) ghc/alloc 47071754.7 48403408.0 +2.8% T17977b(normal) ghc/alloc 42579133.3 43977392.0 +3.3% T18923(normal) ghc/alloc 71764237.3 72566240.0 +1.1% T1969(normal) ghc/alloc 784821002.7 773971776.0 -1.4% GOOD T3294(normal) ghc/alloc 1634913973.3 1614323584.0 -1.3% GOOD T4801(normal) ghc/alloc 295619648.0 292776440.0 -1.0% T5321FD(normal) ghc/alloc 278827858.7 276067280.0 -1.0% T5631(normal) ghc/alloc 586618202.7 577579960.0 -1.5% T5642(normal) ghc/alloc 494923048.0 487927208.0 -1.4% T5837(normal) ghc/alloc 37758061.3 39261608.0 +4.0% T9020(optasm) ghc/alloc 257362077.3 254672416.0 -1.0% T9198(normal) ghc/alloc 49313365.3 50603936.0 +2.6% BAD T9233(normal) ghc/alloc 704944258.7 685692712.0 -2.7% GOOD T9630(normal) ghc/alloc 1476621560.0 1455192784.0 -1.5% T9675(optasm) ghc/alloc 443183173.3 433859696.0 -2.1% GOOD T9872a(normal) ghc/alloc 1720926653.3 1693190072.0 -1.6% GOOD T9872b(normal) ghc/alloc 2185618061.3 2162277568.0 -1.1% GOOD T9872c(normal) ghc/alloc 1765842405.3 1733618088.0 -1.8% GOOD TcPlugin_RewritePerf(normal) ghc/alloc 2388882730.7 2365504696.0 -1.0% WWRec(normal) ghc/alloc 607073186.7 597512216.0 -1.6% T9203(normal) run/alloc 107284064.0 102881832.0 -4.1% haddock.Cabal(normal) run/alloc 24025329589.3 23768382560.0 -1.1% haddock.base(normal) run/alloc 25660521653.3 25370321824.0 -1.1% haddock.compiler(normal) run/alloc 74064171706.7 73358712280.0 -1.0% ``` The biggest exception to the rule is T13701 which seems to fluctuate as usual (not unlike T12545). T14697 has a similar quality, being a generated multi-module test. T5837 is small enough that it similarly doesn't measure anything significant besides module loading overhead. T13253 simply does one additional round of Simplification due to Nested CPR. There are also some apparent regressions in T9198, T12234 and PmSeriesG that we (@mpickering and I) were simply unable to reproduce locally. @mpickering tried to run the CI script in a local Docker container and actually found that T9198 and PmSeriesG *improved*. In MRs that were rebased on top this one, like !4229, I did not experience such increases. Let's not get hung up on these regression tests, they were meant to test for asymptotic regressions. The build-cabal test improves by 1.2% in -O0. Metric Increase: T10421 T12234 T12545 T13035 T13056 T13701 T14697 T18923 T5837 T9198 Metric Decrease: ManyConstructors T12545 T12707 T13056 T14683 T16577 T18223 T1969 T3294 T9203 T9233 T9675 T9872a T9872b T9872c T9961 TcPlugin_RewritePerf - - - - - 205f0f92 by Andrea Condoluci at 2021-09-30T00:57:09-04:00 Trees That Grow refactor for HsTick and HsBinTick Move HsTick and HsBinTick to XExpr, the extension tree of HsExpr. Part of #16830 . - - - - - e0923b98 by Ben Gamari at 2021-09-30T00:57:44-04:00 ghc-boot: Eliminate unnecessary use of getEnvironment Previously we were using `System.Environment.getEnvironment`, which decodes all environment variables into Haskell `String`s, where a simple environment lookup would do. This made the compiler's allocations unnecessarily dependent on the environment. Fixes #20431. - - - - - 941d3792 by Sylvain Henry at 2021-09-30T19:41:09-04:00 Rules for sized conversion primops (#19769) Metric Decrease: T12545 - - - - - adc41a77 by Matthew Pickering at 2021-09-30T19:41:44-04:00 driver: Fix -E -XCPP, copy output from CPP ouput rather than .hs output Fixes #20416 I thought about adding a test for this case but I struggled to think of something robust. Grepping -v3 will include different paths on different systems and the structure of the result file depends on which preprocessor you are using. - - - - - 94f3ce7e by Matthew Pickering at 2021-09-30T19:42:19-04:00 Recompilation: Handle -plugin-package correctly If a plugins was specified using the -plugin-package-(id) flag then the module it applied to was always recompiled. The recompilation checker was previously using `findImportedModule`, which looked for packages in the HPT and then in the package database but only for modules specified using `-package`. The correct lookup function for plugins is `findPluginModule`, therefore we check normal imports with `findImportedModule` and plugins with `findPluginModule`. Fixes #20417 - - - - - ef92a009 by Andreas Klebinger at 2021-09-30T19:42:54-04:00 NCG: Linear-reg-alloc: A few small implemenation tweaks. Removed an intermediate list via a fold. realRegsAlias: Manually inlined the list functions to get better code. Linear.hs added a bang somewhere. - - - - - 9606774d by Aaron Allen at 2021-10-01T09:04:10-04:00 Convert Diagnostics GHC.Tc.Gen.* (Part 3) Converts all diagnostics in the `GHC.Tc.Gen.Expr` module. (#20116) - - - - - 9600a5fb by Matthew Pickering at 2021-10-01T09:04:46-04:00 code gen: Improve efficiency of findPrefRealReg Old strategy: For each variable linearly scan through all the blocks and check to see if the variable is any of the block register mappings. This is very slow when you have a lot of blocks. New strategy: Maintain a map from virtual registers to the first real register the virtual register was assigned to. Consult this map in findPrefRealReg. The map is updated when the register mapping is updated and is hidden behind the BlockAssigment abstraction. On the mmark package this reduces compilation time from about 44s to 32s. Ticket: #19471 - - - - - e3701815 by Matthew Pickering at 2021-10-01T09:05:20-04:00 ci: Unset CI_* variables before run_hadrian and test_make The goal here is to somewhat sanitize the environment so that performance tests don't fluctuate as much as they have been doing. In particular the length of the commit message was causing benchmarks to increase because gitlab stored the whole commit message twice in environment variables. Therefore when we used `getEnvironment` it would cause more allocation because more string would be created. See #20431 ------------------------- Metric Decrease: T10421 T13035 T18140 T18923 T9198 T12234 T12425 ------------------------- - - - - - e401274a by Ben Gamari at 2021-10-02T05:18:03-04:00 gitlab-ci: Bump docker images To install libncurses-dev on Debian targets. - - - - - 42f49c4e by Ben Gamari at 2021-10-02T05:18:03-04:00 Bump terminfo submodule to 0.4.1.5 Closes #20307. - - - - - cb862ecf by Andreas Schwab at 2021-10-02T05:18:40-04:00 CmmToLlvm: Sign/Zero extend parameters for foreign calls on RISC-V Like S390 and PPC64, RISC-V requires parameters for foreign calls to be extended to full words. - - - - - 0d455a18 by Richard Eisenberg at 2021-10-02T05:19:16-04:00 Use eqType, not tcEqType, in metavar kind check Close #20356. See addendum to Note [coreView vs tcView] in GHC.Core.Type for the details. Also killed old Note about metaTyVarUpdateOK, which has been gone for some time. test case: typecheck/should_fail/T20356 - - - - - 4264e74d by Ben Gamari at 2021-10-02T05:19:51-04:00 rts: Add missing write barriers in MVar wake-up paths Previously PerformPut failed to respect the non-moving collector's snapshot invariant, hiding references to an MVar and its new value by overwriting a stack frame without dirtying the stack. Fix this. PerformTake exhibited a similar bug, failing to dirty (and therefore mark) the blocked stack before mutating it. Closes #20399. - - - - - 040c347e by Ben Gamari at 2021-10-02T05:19:51-04:00 rts: Unify stack dirtiness check This fixes an inconsistency where one dirtiness check would not mask out the STACK_DIRTY flag, meaning it may also be affected by the STACK_SANE flag. - - - - - 4bdafb48 by Sylvain Henry at 2021-10-02T05:20:29-04:00 Add (++)/literal rule When we derive the Show instance of the big record in #16577, I get the following compilation times (with -O): Before: 0.91s After: 0.77s Metric Decrease: T19695 - - - - - 8b3d98ff by Sylvain Henry at 2021-10-02T05:21:07-04:00 Don't use FastString for UTF-8 encoding only - - - - - f4554f1d by Ben Gamari at 2021-10-03T14:23:36-04:00 ci: Use https:// transport and access token to push perf notes Previously we would push perf notes using a standard user and SSH key-based authentication. However, configuring SSH is unnecessarily fiddling. We now rather use HTTPS and a project access token. - - - - - 91cd1248 by Ben Gamari at 2021-10-03T14:23:45-04:00 ci/test-metrics: Clean up various bash quoting issues - - - - - ed0e29f1 by Ben Gamari at 2021-10-03T23:24:37-04:00 base: Update Unicode database to 14.0 Closes #20404. - - - - - e8693713 by Ben Gamari at 2021-10-03T23:25:11-04:00 configure: Fix redundant-argument warning from -no-pie check Modern clang versions are quite picky when it comes to reporting redundant arguments. In particular, they will warn when -no-pie is passed when no linking is necessary. Previously the configure script used a `$CC -Werror -no-pie -E` invocation to test whether `-no-pie` is necessary. Unfortunately, this meant that clang would throw a redundant argument warning, causing configure to conclude that `-no-pie` was not supported. We now rather use `$CC -Werror -no-pie`, ensuring that linking is necessary and avoiding this failure mode. Fixes #20463. - - - - - b3267fad by Sylvain Henry at 2021-10-04T08:28:23+00:00 Constant folding for negate (#20347) Only for small integral types for now. - - - - - 2308a130 by Vladislav Zavialov at 2021-10-04T18:44:07-04:00 Clean up HiePass constraints - - - - - 40c81dd2 by Matthew Pickering at 2021-10-04T23:45:11-04:00 ci: Run hadrian builds verbosely, but not tests This reduces the output from the testsuite to a more manageable level. Fixes #20432 - - - - - 347537a5 by Ben Gamari at 2021-10-04T23:45:46-04:00 compiler: Improve Haddocks of atomic MachOps - - - - - a0f44ceb by Ben Gamari at 2021-10-04T23:45:46-04:00 compiler: Fix racy ticker counter registration Previously registration of ticky entry counters was racy, performing a read-modify-write to add the new counter to the ticky_entry_ctrs list. This could result in the list becoming cyclic if multiple threads entered the same closure simultaneously. Fixes #20451. - - - - - a7629334 by Vladislav Zavialov at 2021-10-04T23:46:21-04:00 Bespoke TokenLocation data type The EpaAnnCO we were using contained an Anchor instead of EpaLocation, making it harder to work with. At the same time, using EpaLocation by itself isn't possible either, as we may have tokens without location information. Hence the new data type: data TokenLocation = NoTokenLoc | TokenLoc !EpaLocation - - - - - a14d0e63 by sheaf at 2021-10-04T23:46:58-04:00 Bump TcLevel of failing kind equality implication Not bumping the TcLevel meant that we could end up trying to add evidence terms for the implication constraint created to wrap failing kind equalities (to avoid their deferral). fixes #20043 - - - - - 48b0f17a by sheaf at 2021-10-04T23:47:35-04:00 Add a regression test for #17723 The underlying bug was fixed by b8d98827, see MR !2477 - - - - - 5601b9e2 by Matthías Páll Gissurarson at 2021-10-05T03:18:39-04:00 Speed up valid hole-fits by adding early abort and checks. By adding an early abort flag in `TcSEnv`, we can fail fast in the presence of insoluble constraints. This helps us avoid a lot of work in valid hole-fits, and we geta massive speed-up by avoiding a lot of useless work solving constraints that never come into play. Additionally, we add a simple check for degenerate hole types, such as when the type of the hole is an immutable type variable (as is the case when the hole is completely unconstrained). Then the only valid fits are the locals, so we can ignore the global candidates. This fixes #16875 - - - - - 298df16d by Krzysztof Gogolewski at 2021-10-05T03:19:14-04:00 Reject type family equation with wrong name (#20260) We should reject "type family Foo where Bar = ()". This check was done in kcTyFamInstEqn but not in tcTyFamInstEqn. I factored out arity checking, which was duplicated. - - - - - 643b6f01 by Sebastian Graf at 2021-10-05T14:32:51-04:00 WorkWrap: Nuke CPR signatures of join points (#18824) In #18824 we saw that the Simplifier didn't nuke a CPR signature of a join point when it pushed a continuation into it when it better should have. But join points are local, mostly non-exported bindings. We don't use their CPR signature anyway and would discard it at the end of the Core pipeline. Their main purpose is to propagate CPR info during CPR analysis and by the time worker/wrapper runs the signature will have served its purpose. So we zap it! Fixes #18824. - - - - - b4c0cc36 by Sebastian Graf at 2021-10-05T14:32:51-04:00 Simplifier: Get rid of demand zapping based on Note [Arity decrease] The examples in the Note were inaccurate (`$s$dm` has arity 1 and that seems OK) and the code didn't actually nuke the demand *signature* anyway. Specialise has to nuke it, but it starts from a clean IdInfo anyway (in `newSpecIdM`). So I just deleted the code. Fixes #20450. - - - - - cd1b016f by Sebastian Graf at 2021-10-05T14:32:51-04:00 CprAnal: Activate Sum CPR for local bindings We've had Sum CPR (#5075) for top-level bindings for a couple of years now. That begs the question why we didn't also activate it for local bindings, and the reasons for that are described in `Note [CPR for sum types]`. Only that it didn't make sense! The Note said that Sum CPR would destroy let-no-escapes, but that should be a non-issue since we have syntactic join points in Core now and we don't WW for them (`Note [Don't w/w join points for CPR]`). So I simply activated CPR for all bindings of sum type, thus fixing #5075 and \#16570. NoFib approves: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- comp_lab_zift -0.0% +0.7% fluid +1.7% +0.7% reptile +0.1% +0.1% -------------------------------------------------------------------------------- Min -0.0% -0.2% Max +1.7% +0.7% Geometric Mean +0.0% +0.0% ``` There were quite a few metric decreases on the order of 1-4%, but T6048 seems to regress significantly, by 26.1%. WW'ing for a `Just` constructor and the nested data type meant additional Simplifier iterations and a 30% increase in term sizes as well as a 200-300% in type sizes due to unboxed 9-tuples. There's not much we can do about it, I'm afraid: We're just doing much more work there. Metric Decrease: T12425 T18698a T18698b T20049 T9020 WWRec Metric Increase: T6048 - - - - - 000f2a30 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Address some Foldable documentation nits - Add link to laws from the class head - Simplify wording of left/right associativity intro paragraph - Avoid needless mention of "endomorphisms" - - - - - 7059a729 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Add laws link and tweak Traversable class text - - - - - 43358ab9 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Note linear `elem` cost This is a writeup of the state of play for better than linear `elem` via a helper type class. - - - - - 56899c8d by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Note elem ticket 20421 - - - - - fb6b772f by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Minor wording tweaks/fixes - - - - - f49c7012 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Adopt David Feuer's explantion of foldl' via foldr - - - - - 5282eaa1 by Viktor Dukhovni at 2021-10-05T14:33:29-04:00 Explain Endo, Dual, ... in laws - - - - - f52df067 by Alfredo Di Napoli at 2021-10-05T14:34:04-04:00 Make GHC.Utils.Error.Validity type polymorphic This commit makes the `Validity` type polymorphic: ``` data Validity' a = IsValid -- ^ Everything is fine | NotValid a -- ^ A problem, and some indication of why -- | Monomorphic version of @Validity'@ specialised for 'SDoc's. type Validity = Validity' SDoc ``` The type has been (provisionally) renamed to Validity' to not break existing code, as the monomorphic `Validity` type is quite pervasive in a lot of signatures in GHC. Why having a polymorphic Validity? Because it carries the evidence of "what went wrong", but the old type carried an `SDoc`, which clashed with the new GHC diagnostic infrastructure (#18516). Having it polymorphic it means we can carry an arbitrary, richer diagnostic type, and this is very important for things like the `checkOriginativeSideConditions` function, which needs to report the actual diagnostic error back to `GHC.Tc.Deriv`. It also generalises Validity-related functions to be polymorphic in @a at . - - - - - ac275f42 by Alfredo Di Napoli at 2021-10-05T14:34:04-04:00 Eradicate TcRnUnknownMessage from GHC.Tc.Deriv This (big) commit finishes porting the GHC.Tc.Deriv module to support the new diagnostic infrastructure (#18516) by getting rid of the legacy calls to `TcRnUnknownMessage`. This work ended up being quite pervasive and touched not only the Tc.Deriv module but also the Tc.Deriv.Utils and Tc.Deriv.Generics module, which needed to be adapted to use the new infrastructure. This also required generalising `Validity`. More specifically, this is a breakdown of the work done: * Add and use the TcRnUselessTypeable data constructor * Add and use TcRnDerivingDefaults data constructor * Add and use the TcRnNonUnaryTypeclassConstraint data constructor * Add and use TcRnPartialTypeSignatures * Add T13324_compile2 test to test another part of the TcRnPartialTypeSignatures diagnostic * Add and use TcRnCannotDeriveInstance data constructor, which introduces a new data constructor to TcRnMessage called TcRnCannotDeriveInstance, which is further sub-divided to carry a `DeriveInstanceErrReason` which explains the reason why we couldn't derive a typeclass instance. * Add DerivErrSafeHaskellGenericInst data constructor to DeriveInstanceErrReason * Add DerivErrDerivingViaWrongKind and DerivErrNoEtaReduce * Introduce the SuggestExtensionInOrderTo Hint, which adds (and use) a new constructor to the hint type `LanguageExtensionHint` called `SuggestExtensionInOrderTo`, which can be used to give a bit more "firm" recommendations when it's obvious what the required extension is, like in the case for the `DerivingStrategies`, which automatically follows from having enabled both `DeriveAnyClass` and `GeneralizedNewtypeDeriving`. * Wildcard-free pattern matching in mk_eqn_stock, which removes `_` in favour of pattern matching explicitly on `CanDeriveAnyClass` and `NonDerivableClass`, because that determine whether or not we can suggest to the user `DeriveAnyClass` or not. - - - - - 52400ebb by Simon Peyton Jones at 2021-10-05T14:34:39-04:00 Ensure top-level binders in scope in SetLevels Ticket #20200 (the Agda failure) showed another case in which lookupIdSubst would fail to find a local Id in the InScopeSet. This time it was because SetLevels was given a program in which the top-level bindings were not in dependency order. The Simplifier (see Note [Glomming] in GHC.Core.Opt.Occuranal) and the specialiser (see Note [Top level scope] in GHC.Core.Opt.Specialise) may both produce top-level bindings where an early binding refers to a later one. One solution would be to run the occurrence analyser again to put them all in the right order. But a simpler one is to make SetLevels OK with this input by bringing all top-level binders into scope at the start. That's what this patch does. - - - - - 11240b74 by Sylvain Henry at 2021-10-05T14:35:17-04:00 Constant folding for (.&.) maxBound (#20448) - - - - - 29ee04f3 by Zubin Duggal at 2021-10-05T14:35:52-04:00 docs: Clarify documentation of `getFileSystemEncoding` (#20344) It may not always be a Unicode encoding - - - - - 435ff398 by Mann mit Hut at 2021-10-06T00:11:07-04:00 Corrected types of thread ids obtained from the RTS While the thread ids had been changed to 64 bit words in e57b7cc6d8b1222e0939d19c265b51d2c3c2b4c0 the return type of the foreign import function used to retrieve these ids - namely 'GHC.Conc.Sync.getThreadId' - was never updated accordingly. In order to fix that this function returns now a 'CUULong'. In addition to that the types used in the thread labeling subsystem were adjusted as well and several format strings were modified throughout the whole RTS to display thread ids in a consistent and correct way. Fixes #16761 - - - - - 89e98bdf by Alan Zimmerman at 2021-10-06T00:11:42-04:00 EPA: Remove duplicate AnnOpenP/AnnCloseP in DataDecl The parens EPAs were added in the tyvars where they belong, but also at the top level of the declaration. Closes #20452 - - - - - fc4c7ffb by Ryan Scott at 2021-10-06T00:12:17-04:00 Remove the Maybe in primRepName's type There's no need for this `Maybe`, as it will always be instantiated to `Just` in practice. Fixes #20482. - - - - - 4e91839a by sheaf at 2021-10-06T00:12:54-04:00 Add a regression test for #13233 This test fails on GHC 8.0.1, only when profiling is enabled, with the error: ghc: panic! (the 'impossible' happened) kindPrimRep.go a_12 This was fixed by commit b460d6c9. - - - - - 7fc986e1 by Sebastian Graf at 2021-10-06T00:13:29-04:00 CprAnal: Two regression tests For #16040 and #2387. - - - - - 9af29e7f by Matthew Pickering at 2021-10-06T10:57:24-04:00 Disable -dynamic-too if -dynamic is also passed Before if you passed both options then you would generate two identical hi/dyn_hi and o/dyn_o files, both in the dynamic way. It's better to warn this is happening rather than duplicating the work and causing potential confusion. -dynamic-too should only be used with -static. Fixes #20436 - - - - - a466b024 by sheaf at 2021-10-06T10:58:03-04:00 Improve overlap error for polykinded constraints There were two problems around `mkDictErr`: 1. An outdated call to `flattenTys` meant that we missed out on some instances. As we no longer flatten type-family applications, the logic is obsolete and can be removed. 2. We reported "out of scope" errors in a poly-kinded situation because `BoxedRep` and `Lifted` were considered out of scope. We fix this by using `pretendNameIsInScope`. fixes #20465 - - - - - b041fc6e by Ben Gamari at 2021-10-07T03:40:49-04:00 hadrian: Generate ghcii.sh in binary distributions Technically we should probably generate this in the in-place build tree as well, but I am not bothering to do so here as ghcii.sh will be removed in 9.4 when WinIO becomes the default anyways (see #12720). Fixes #19339. - - - - - 75a766a3 by Ben Gamari at 2021-10-07T03:40:49-04:00 hadrian: Fix incorrect ticket reference This was supposed to refer to #20253. - - - - - 62157287 by Teo Camarasu at 2021-10-07T03:41:27-04:00 fix non-moving gc heap space requirements estimate The space requirements of the non-moving gc are comparable to the compacting gc, not the copying gc. The copying gc requires a much larger overhead. Fixes #20475 - - - - - e82c8dd2 by Joachim Breitner at 2021-10-07T03:42:01-04:00 Fix rst syntax mistakes in release notes - - - - - 358f6222 by Benjamin Maurer at 2021-10-07T03:42:36-04:00 Removed left-over comment from `nonDetEltsUFM`-removal in `seqEltsUFM`. - - - - - 0cf23263 by Alan Zimmerman at 2021-10-07T03:43:11-04:00 EPA: Add comments to EpaDelta The EpaDelta variant of EpaLocation cannot be sorted by location. So we capture any comments that need to be printed between the prior output and this location, when creating an EpaDelta offset in ghc-exactprint. And make the EpaLocation fields strict. - - - - - e1d02fb0 by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow naturalEq#/Ne# to inline (#20361) We now perform constant folding on bigNatEq# instead. - - - - - 44886aab by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow inlining of naturalEq/Ne/Gt/Lt/Ge/Le/Compare (#20361) Perform constant folding on bigNatCompare instead. Some functions of the Enum class for Natural now need to be inlined explicitly to be specialized at call sites (because `x > lim` for Natural is inlined and the resulting function is a little too big to inline). If we don't do this, T17499 runtime allocations regresses by 16%. - - - - - 3a5a5c85 by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: allow naturalToWordClamp/Negate/Signum to inline (#20361) We don't need built-in rules now that bignum literals (e.g. 123 :: Natural) match with their constructors (e.g. NS 123##). - - - - - 714568bb by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: remove outdated comment - - - - - 4d44058d by Sylvain Henry at 2021-10-07T20:20:01-04:00 Bignum: transfer NOINLINE from Natural to BigNat - - - - - 01f5324f by Joachim Breitner at 2021-10-07T20:20:36-04:00 Recover test case for T11547 commit 98c7749 has reverted commit 59d7ee53, including the test that that file added. That test case is still valuable, so I am re-adding it. I add it with it’s current (broken) behavior so that whoever fixes it intentionally or accidentially will notice and then commit the actual desired behavior (which is kinda unspecified, see https://gitlab.haskell.org/ghc/ghc/-/issues/20455#note_382030) - - - - - 3d31f11e by Sylvain Henry at 2021-10-08T13:08:16-04:00 Don't link plugins' units with target code (#20218) Before this patch, plugin units were linked with the target code even when the unit was passed via `-plugin-package`. This is an issue to support plugins in cross-compilers (plugins are definitely not ABI compatible with target code). We now clearly separate unit dependencies for plugins and unit dependencies for target code and only link the latter ones. We've also added a test to ensure that plugin units passed via `-package` are linked with target code so that `thNameToGhcName` can still be used in plugins that need it (see T20218b). - - - - - 75aea732 by Joachim Breitner at 2021-10-08T13:08:51-04:00 New test case: Variant of T14052 with data type definitions previous attempts at fixing #11547 and #20455 were reverted because they showed some quadratic behaviour, and the test case T15052 was added to catch that. I believe that similar quadratic behavor can be triggered with current master, by using type definitions rather than value definitions, so this adds a test case similar to T14052. I have hopes that my attempts at fixing #11547 will lead to code that avoid the quadratic increase here. Or not, we will see. In any case, having this in `master` and included in future comparisons will be useful. - - - - - 374a718e by Teo Camarasu at 2021-10-08T18:09:56-04:00 Fix nonmoving gen label in gc stats report The current code assumes the non-moving generation is always generation 1, but this isn't the case if the amount of generations is greater than 2 Fixes #20461 - - - - - a37275a3 by Matthew Pickering at 2021-10-08T18:10:31-04:00 ci: Remove BROKEN_TESTS for x86 darwin builds The tests Capi_Ctype_001 Capi_Ctype_002 T12010 pass regularly on CI so let's mark them unbroken and hopefully then we can fix #20013. - - - - - e6838872 by Matthew Pickering at 2021-10-08T18:10:31-04:00 ci: Expect x86-darwin to pass Closes #20013 - - - - - 1f160cd9 by Matthew Pickering at 2021-10-08T18:10:31-04:00 Normalise output of T20199 test - - - - - 816d2561 by CarrieMY at 2021-10-08T18:11:08-04:00 Fix -E -fno-code undesirable interactions #20439 - - - - - 55a6377a by Matthew Pickering at 2021-10-08T18:11:43-04:00 code gen: Disable dead code elimination when -finfo-table-map is enabled It's important that when -finfo-table-map is enabled that we generate IPE entries just for those info tables which are actually used. To this end, the info tables which are used are collected just before code generation starts and entries only created for those tables. Not accounted for in this scheme was the dead code elimination in the native code generator. When compiling GHC this optimisation removed an info table which had an IPE entry which resulting in the following kind of linker error: ``` /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sS_info' /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sH_info' /home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sm_info' collect2: error: ld returned 1 exit status `cc' failed in phase `Linker'. (Exit code: 1) Development.Shake.cmd, system command failed ``` Unfortunately, by the time this optimisation happens the structure of the CmmInfoTable has been lost, we only have the generated code for the info table to play with so we can no longer just collect all the used info tables and generate the IPE map. This leaves us with two options: 1. Return a list of the names of the discarded info tables and then remove them from the map. This is awkward because we need to do code generation for the map as well. 2. Just disable this small code size optimisation when -finfo-table-map is enabled. The option produces very big object files anyway. Option 2 is much easier to implement and means we don't have to thread information around awkwardly. It's at the cost of slightly larger object files (as dead code is not eliminated). Disabling this optimisation allows an IPE build of GHC to complete successfully. Fixes #20428 - - - - - a76409c7 by Andrei Barbu at 2021-10-08T19:45:29-04:00 Add defaulting plugins. Like the built-in type defaulting rules these plugins can propose candidates to resolve ambiguous type variables. Machine learning and other large APIs like those for game engines introduce new numeric types and other complex typed APIs. The built-in defaulting mechanism isn't powerful enough to resolve ambiguous types in these cases forcing users to specify minutia that they might not even know how to do. There is an example defaulting plugin linked in the documentation. Applications include defaulting the device a computation executes on, if a gradient should be computed for a tensor, or the size of a tensor. See https://github.com/ghc-proposals/ghc-proposals/pull/396 for details. - - - - - 31983ab4 by sheaf at 2021-10-09T04:46:05-04:00 Reject GADT pattern matches in arrow notation Tickets #20469 and #20470 showed that the current implementation of arrows is not at all up to the task of supporting GADTs: GHC produces ill-scoped Core programs because it doesn't propagate the evidence introduced by a GADT pattern match. For the time being, we reject GADT pattern matches in arrow notation. Hopefully we are able to add proper support for GADTs in arrows in the future. - - - - - a356bd56 by Matthew Pickering at 2021-10-10T15:07:52+02:00 driver: Fix assertion failure on self-import Fixes #20459 - - - - - 245ab166 by Ben Gamari at 2021-10-10T17:55:10-04:00 hadrian: Include Cabal flags in verbose configure output - - - - - 9f9d6280 by Zejun Wu at 2021-10-12T01:39:53-04:00 Derive Eq instance for the HieTypeFix type We have `instance Eq a => Eq (HieType a)` already. This instance can be handy when we want to impement a function to find all `fromIntegral :: a -> a` using `case ty of { Roll (HFunTy _ a b) -> a == b; _ -> False }`. - - - - - 8d6de541 by Ben Gamari at 2021-10-12T01:40:29-04:00 nonmoving: Fix and factor out mark_trec_chunk We need to ensure that the TRecChunk itself is marked, in addition to the TRecs it contains. - - - - - aa520ba1 by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/nonmoving: Rename mark_* to trace_* These functions really do no marking; they merely trace pointers. - - - - - 2c02ea8d by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/primops: Fix write barrier in stg_atomicModifyMutVarzuzh Previously the call to dirty_MUT_VAR in stg_atomicModifyMutVarzuzh was missing its final argument. Fixes #20414. - - - - - 2e0c13ab by Ben Gamari at 2021-10-12T01:40:29-04:00 rts/nonmoving: Enable selector optimisation by default - - - - - 2c06720e by GHC GitLab CI at 2021-10-12T01:41:04-04:00 rts/Linker: Fix __dso_handle handling Previously the linker's handling of __dso_handle was quite wrong. Not only did we claim that __dso_handle could be NULL when statically linking (which it can not), we didn't even implement this mislead theory faithfully and instead resolved the symbol to a random pointer. This lead to the failing relocations on AArch64 noted in #20493. Here we try to implement __dso_handle as a dynamic linker would do, choosing an address within the loaded object (specifically its start address) to serve as the object's handle. - - - - - 58223dfa by Carrie Xu at 2021-10-12T01:41:41-04:00 Add Hint to "Empty 'do' block" Error Message#20147 - - - - - 8e88ef36 by Carrie Xu at 2021-10-12T01:41:41-04:00 Change affected tests stderr - - - - - 44384696 by Zubin Duggal at 2021-10-12T01:42:15-04:00 driver: Share the graph of dependencies We want to share the graph instead of recomputing it for each key. - - - - - e40feab0 by Matthew Pickering at 2021-10-12T01:42:50-04:00 Make ms_ghc_prim_import field strict If you don't promptly force this field then it ends up retaining a lot of data structures related to parsing. For example, the following retaining chain can be observed when using GHCi. ``` PState 0x4289365ca0 0x4289385d68 0x4289385db0 0x7f81b37a7838 0x7f81b3832fd8 0x4289365cc8 0x4289365cd8 0x4289365cf0 0x4289365cd8 0x4289365d08 0x4289385e48 0x7f81b4e4c290 0x7f818f63f440 0x7f818f63f440 0x7f81925ccd18 0x7f81b4e41230 0x7f818f63f440 0x7f81925ccd18 0x7f818f63f4a8 0x7f81b3832fd8 0x7f81b3832fd8 0x4289365d20 0x7f81b38233b8 0 19 <PState:GHC.Parser.Lexer:_build-ipe/stage1/compiler/build/GHC/Parser/Lexer.hs:3779:46> _thunk( ) 0x4289384230 0x4289384160 <([LEpaComment], [LEpaComment]):GHC.Parser.Lexer:> _thunk( ) 0x4289383250 <EpAnnComments:GHC.Parser.Lexer:compiler/GHC/Parser/Lexer.x:2306:19-40> _thunk( ) 0x4289399850 0x7f818f63f440 0x4289399868 <SrcSpanAnnA:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12527:13-30> L 0x4289397600 0x42893975a8 <GenLocated:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12527:32> 0x4289c4e8c8 : 0x4289c4e8b0 <[]:GHC.Parser.Header:compiler/GHC/Parser/Header.hs:104:36-54> (0x4289c4da70,0x7f818f63f440) <(,):GHC.Parser.Header:compiler/GHC/Parser/Header.hs:104:36-54> _thunk( ) 0x4289c4d030 <Bool:GHC.Parser.Header:compiler/GHC/Parser/Header.hs:(112,22)-(115,27)> ExtendedModSummary 0x422e9c8998 0x7f81b617be78 0x422e9c89b0 0x4289c4c0c0 0x7f81925ccd18 0x7f81925ccd18 0x7f81925ccd18 0x7f81925ccd18 0x7f818f63f440 0x4289c4c0d8 0x4289c4c0f0 0x7f81925ccd18 0x422e9c8a20 0x4289c4c108 0x4289c4c730 0x7f818f63f440 <ExtendedModSummary:GHC.Driver.Make:compiler/GHC/Driver/Make.hs:2041:30-38> ModuleNode 0x4289c4b850 <ModuleGraphNode:GHC.Unit.Module.Graph:compiler/GHC/Unit/Module/Graph.hs:139:14-36> 0x4289c4b590 : 0x4289c4b578 <[]:GHC.Unit.Module.Graph:compiler/GHC/Unit/Module/Graph.hs:139:31-36> ModuleGraph 0x4289c4b2f8 0x4289c4b310 0x4289c4b340 0x7f818f63f4a0 <ModuleGraph:GHC.Driver.Make:compiler/GHC/Driver/Make.hs:(242,19)-(244,40)> HscEnv 0x4289d9a4a8 0x4289d9aad0 0x4289d9aae8 0x4217062a88 0x4217060b38 0x4217060b58 0x4217060b68 0x7f81b38a7ce0 0x4217060b78 0x7f818f63f440 0x7f818f63f440 0x4217062af8 0x4289d9ab10 0x7f81b3907b60 0x4217060c00 114 <HscEnv:GHC.Runtime.Eval:compiler/GHC/Runtime/Eval.hs:790:31-44> ``` - - - - - 5c266b59 by Ben Gamari at 2021-10-12T19:16:40-04:00 hadrian: Introduce `static` flavour - - - - - 683011c7 by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Introduce static Alpine job - - - - - 9257abeb by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Drop :set from ghci scripts The ghci scripts for T9293 and ghci057 used `:set` to print the currently-set options. However, in neither case was this necessary to the correctness of the test and moreover it would introduce spurious platform-dependence (e.g. since `-fexternal-dynamic-refs` is set by default only on platforms that support dynamic linking). - - - - - 82a89df7 by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/linker: Define _DYNAMIC when necessary Usually the dynamic linker would define _DYNAMIC. However, when dynamic linking is not supported (e.g. on musl) it is safe to define it to be NULL. - - - - - fcd970b5 by GHC GitLab CI at 2021-10-12T19:16:40-04:00 rts/linker: Resolve __fini_array_* symbols to NULL If the __fini_array_{start,end} symbols are not defined (e.g. as is often the case when linking against musl) then resolve them to NULL. - - - - - 852ec4f5 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark T13702 as requiring share libraries It fails on statically-built Alpine with ``` T13702.hs:1:1: error: Could not find module ‘Prelude’ Perhaps you haven't installed the "dyn" libraries for package ‘base-4.15.0.0’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. | 1 | {-# LANGUAGE ForeignFunctionInterface #-} | ^ ``` - - - - - b604bfd9 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark ghcilink00[25] as requiring dynamic linking - - - - - d709a133 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark all ghci/linking/dyn tests as requiring dynamic linking - - - - - 99b8177a by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Mark T14931 as requiring dynamic linking - - - - - 2687f65e by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Compile safeInfered tests with -v0 This eliminates some spurious platform-dependence due to static linking (namely in UnsafeInfered02 due to dynamic-too). - - - - - 587d7e66 by Brian Jaress at 2021-10-12T19:16:40-04:00 documentation: flavours.md static details - - - - - 91cfe121 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Make recomp021 less environment-sensitive Suppress output from diff to eliminate unnecessary environmental-dependence. - - - - - dc094597 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Make T12600 more robust Previously we would depend upon `grep ... | head -n1`. In principle this should work, but on Alpine Linux `grep` complains when its stdout stream has been closed. - - - - - cdd45a61 by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Mark more broken tests on Alpine - - - - - 9ebda74e by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: Add environ - - - - - 08aa7a1d by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/linker: Introduce a notion of strong symbols - - - - - 005b1848 by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: Declare atexit as a strong symbol - - - - - 5987357b by Ben Gamari at 2021-10-12T19:16:40-04:00 rts/RtsSymbols: fini array - - - - - 9074b748 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Move big-obj test from ghci/linking/dyn to ghci/linking There was nothing dynamic about this test. - - - - - 3b1c12d3 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Fix overzealous command-line mangling Previously this attempt at suppressing make's -s flag would mangle otherwise valid arguments. - - - - - 05303f68 by Ben Gamari at 2021-10-12T19:16:40-04:00 testsuite: Clean up dynlib support predicates Previously it was unclear whether req_shared_libs should require: * that the platform supports dynamic library loading, * that GHC supports dynamic linking of Haskell code, or * that the dyn way libraries were built Clarify by splitting the predicate into two: * `req_dynamic_lib_support` demands that the platform support dynamic linking * `req_dynamic_hs` demands that the GHC support dynamic linking of Haskell code on the target platform Naturally `req_dynamic_hs` cannot be true unless `req_dynamic_lib_support` is also true. - - - - - 9859eede by Ben Gamari at 2021-10-12T19:16:40-04:00 gitlab-ci: Bump docker images Bumps bootstrap compiler to GHC 9.0.1. - - - - - af5ed156 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make the OccName field of NotOrphan strict In GHCi, by default the ModIface is not written to disk, this can leave a thunk which retains a TyCon which ends up retaining a great deal more on the heap. For example, here is the retainer trace from ghc-debug. ``` ... many other closures ... <TyCon:GHC.Core.TyCon:compiler/GHC/Core/TyCon.hs:1755:34-97> Just 0x423162aaa8 <Maybe:GHC.Core.TyCon:compiler/GHC/Core/TyCon.hs:(1936,11)-(1949,13)> FamilyTyCon 0x4231628318 0x4210e06260 0x4231628328 0x4231628340 0x421730a398 0x4231628358 0x4231628380 0x4231628390 0x7f0f5a171d18 0x7f0f7b1d7850 0x42316283a8 0x7f0f7b1d7830 <TyCon:GHC.Core.TyCon:compiler/GHC/Cor e/TyCon.hs:1948:30-32> _thunk( ) 0x4231624000 <OccName:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:724:22-43> NotOrphan 0x42357d8ed8 <IsOrphan:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:724:12-43> IfaceFamInst 0x4210e06260 0x42359aed10 0x4210e0c6b8 0x42359aed28 <IfaceFamInst:GHC.Iface.Make:> ``` Making the field strict squashes this retainer leak when using GHCi. - - - - - 0c5d9ca8 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Be more careful about retaining KnotVars It is quite easy to end up accidently retaining a KnotVars, which contains pointers to a stale TypeEnv because they are placed in the HscEnv. One place in particular we have to be careful is when loading a module into the EPS in `--make` mode, we have to remove the reference to KnotVars as otherwise the interface loading thunks will forever retain reference to the KnotVars which are live at the time the interface was loaded. These changes do not go as far as to enforce the invariant described in Note [KnotVar invariants] * At the end of upsweep, there should be no live KnotVars but at least improve the situation. This is left for future work (#20491) - - - - - 105e2711 by Matthew Pickering at 2021-10-12T19:17:15-04:00 driver: Pass hsc_env with empty HPT into upsweep Otherwise you end up retaining the whole old HPT when reloading in GHCi. - - - - - 7215f6de by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make fields of Linkable strict The Module field can end up retaining part of a large structure and is always calculated by projection. - - - - - 053d9deb by Matthew Pickering at 2021-10-12T19:17:15-04:00 Make the fields of MakeEnv strict There's no reason for them to be lazy, and in particular we would like to make sure the old_hpt field is evaluated. - - - - - 0d711791 by Matthew Pickering at 2021-10-12T19:17:15-04:00 More strictness around HomePackageTable This patch makes some operations to do with HomePackageTable stricter * Adding a new entry into the HPT would not allow the old HomeModInfo to be collected because the function used by insertWith wouldn't be forced. * We're careful to force the new MVar value before it's inserted into the global MVar as otherwise we retain references to old entries. - - - - - ff0409d0 by Matthew Pickering at 2021-10-12T19:17:15-04:00 driver: Filter out HPT modules **before** typecheck loop It's better to remove the modules first before performing the typecheckLoop as otherwise you can end up with thunks which reference stale HomeModInfo which are difficult to force due to the knot-tie. - - - - - c2ce1b17 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Add GHCi recompilation performance test - - - - - 82938981 by Matthew Pickering at 2021-10-12T19:17:15-04:00 Force name_exe field to avoid retaining entire UnitEnv (including whole HPT) Not forcing this one place will result in GHCi using 2x memory on a reload. - - - - - 90f06a0e by Haochen Tong at 2021-10-12T19:17:53-04:00 Check for libatomic dependency for atomic operations Some platforms (e.g. RISC-V) require linking against libatomic for some (e.g. sub-word-sized) atomic operations. Fixes #19119. - - - - - 234bf368 by Haochen Tong at 2021-10-12T19:17:53-04:00 Move libatomic check into m4/fp_gcc_supports_atomics.m4 - - - - - 4cf43b2a by Haochen Tong at 2021-10-12T19:17:53-04:00 Rename fp_gcc_supports__atomics to fp_cc_supports__atomics - - - - - 0aae1b4e by Joachim Breitner at 2021-10-13T01:07:45+00:00 shadowNames: Accept an OccName, not a GreName previously, the `shadowNames` function would take `[GreName]`. This has confused me for two reasons: * Why `GreName` and not `Name`? Does the difference between a normal name and a field name matter? The code of `shadowNames` shows that it does not, but really its better if the type signatures says so. * Why `Name` and not `OccName`? The point of `shadowNames` is to shadow _unqualified names_, at least in the two use cases I am aware of (names defined on the GHCI prompt or in TH splices). The code of `shadowNames` used to have cases that peek at the module of the given name and do something if that module appears in the `GlobalRdrElt`, but I think these cases are dead code, I don’t see how they could occur in the above use cases. Also, I replaced them with `errors` and GHC would still validate. Hence removing this code (yay!) This change also allows `shadowNames` to accept an `OccSet` instead, which allows for a faster implemenation; I’ll try that separately. This in stead might help with !6703. - - - - - 19cd403b by Norman Ramsey at 2021-10-13T03:32:21-04:00 Define and export Outputable instance for StgOp - - - - - 58bd0cc1 by Zubin Duggal at 2021-10-13T13:50:10+05:30 ci: build validate-x86_64-linux-deb9-debug with hyperlinked source (#20067) - - - - - 4536e8ca by Zubin Duggal at 2021-10-13T13:51:00+05:30 hadrian, testsuite: Teach Hadrian to query the testsuite driver for dependencies Issues #19072, #17728, #20176 - - - - - 60d3e33d by Zubin Duggal at 2021-10-13T13:51:03+05:30 hadrian: Fix location for haddocks in installed pkgconfs - - - - - 337a31db by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: Run haddock tests on out of tree compiler - - - - - 8c224b6d by Zubin Duggal at 2021-10-13T13:51:03+05:30 ci: test in-tree compiler in hadrian - - - - - 8d5a5ecf by Zubin Duggal at 2021-10-13T13:51:03+05:30 hadrian: avoid building check-{exact,ppr} and count-deps when the tests don't need them hadrian: build optional dependencies with test compiler - - - - - d0e87d0c by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: remove 'req_smp' from testwsdeque - - - - - 3c0e60b8 by Zubin Duggal at 2021-10-13T13:51:03+05:30 testsuite: strip windows line endings for haddock haddock: deterministic SCC Updates haddock submodule Metric Increase: haddock.Cabal haddock.base haddock.compiler - - - - - 64460b20 by Ben Gamari at 2021-10-13T18:44:12-04:00 distrib/configure: Add AC_CONFIG_MACRO_DIRS Sadly, autoconf cannot warn when it encounters an undefined macro and therefore this bug went unnoticed for altogether far too long. - - - - - e46edfcf by sheaf at 2021-10-13T18:44:49-04:00 Set logger flags in --backpack mode Backpack used to initialise the logger before obtaining the DynFlags. This meant that logging options (such as dump flags) were not set. Initialising the logger after the session flags have been set fixes the issue. fixes #20396 - - - - - df016e4e by Matthew Pickering at 2021-10-14T08:41:17-04:00 Make sure paths are quoted in install Makefile Previously it would fail with this error: ``` if [ -L wrappers/ghc ]; then echo "ghc is a symlink"; fi ghc is a symlink cp: target 'dir/bin/ghc' is not a directory make: *** [Makefile:197: install_wrappers] Error 1 ``` which is because the install path contains a space. Fixes #20506 - - - - - 7f2ce0d6 by Joachim Breitner at 2021-10-14T08:41:52-04:00 Move BreakInfo into own module while working on GHCi stuff, e.g. `GHC.Runtime.Eval.Types`, I observed a fair amount of modules being recompiled that I didn’t expect to depend on this, from byte code interpreters to linkers. Turns out that the rather simple `BreakInfo` type is all these modules need from the `GHC.Runtime.Eval.*` hierarchy, so by moving that into its own file we make the dependency tree wider and shallower, which is probably worth it. - - - - - 557d26fa by Ziyang Liu at 2021-10-14T14:32:57-04:00 Suggest -dynamic-too in failNonStd when applicable I encountered an error that says ``` Cannot load -dynamic objects when GHC is built the normal way To fix this, either: (1) Use -fexternal-interpreter, or (2) Build the program twice: once the normal way, and then with -dynamic using -osuf to set a different object file suffix. ``` Or it could say ``` (2) Use -dynamic-too ``` - - - - - f450e948 by Joachim Breitner at 2021-10-14T14:33:32-04:00 fuzzyLookup: More deterministic order else the output may depend on the input order, which seems it may depend on the concrete Uniques, which is causing headaches when including test cases about that. - - - - - 8b7f5424 by Alan Zimmerman at 2021-10-14T14:34:07-04:00 EPA: Preserve semicolon order in annotations Ensure the AddSemiAnn items appear in increasing order, so that if they are converted to delta format they are still in the correct order. Prior to this the exact printer sorted by Span, which is meaningless for EpaDelta locations. - - - - - 481e6b54 by Matthew Pickering at 2021-10-14T14:34:42-04:00 Some extra strictness in annotation fields Locations can be quite long-lived so it's important that things which live in locations, such as annotations are forced promptly. Otherwise they end up retaining the entire PState, as evidenced by this retainer trace: ``` PState 0x4277ce6cd8 0x4277ce6d00 0x7f61f12d37d8 0x7f61f12d37d8 0x7f61f135ef78 0x4277ce6d48 0x4277ce6d58 0x4277ce6d70 0x4277ce6d58 0x4277ce6d88 0x4277ce6da0 0x7f61f29782f0 0x7f61cd16b440 0x7f61cd16b440 0x7f61d00f8d18 0x7f61f296d290 0x7f61cd16b440 0x7f61d00f8d18 0x7f61cd16b4a8 0x7f61f135ef78 0x4277ce6db8 0x4277ce6dd0 0x7f61f134f358 0 3 <PState:GHC.Parser.Lexer:_build-ipe/stage1/compiler/build/GHC/Parser/Lexer.hs:3779:46> _thunk( ) 0x4277ce6280 0x4277ce68a0 <([LEpaComment], [LEpaComment]):GHC.Parser.Lexer:> _thunk( ) 0x4277ce6568 <EpAnnComments:GHC.Parser.Lexer:compiler/GHC/Parser/Lexer.x:2306:19-40> _thunk( ) 0x4277ce62b0 0x4277ce62c0 0x4277ce6280 0x7f61f287fc58 <EpAnn AnnList:GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12664:13-32> SrcSpanAnn 0x4277ce6060 0x4277ce6048 <SrcSpanAnn':GHC.Parser:_build-ipe/stage1/compiler/build/GHC/Parser.hs:12664:3-35> L 0x4277ce4e70 0x428f8c9158 <GenLocated:GHC.Data.BooleanFormula:compiler/GHC/Data/BooleanFormula.hs:40:23-29> 0x428f8c8318 : 0x428f8c8300 <[]:GHC.Base:libraries/base/GHC/Base.hs:1316:16-29> Or 0x428f8c7890 <BooleanFormula:GHC.Data.BooleanFormula:compiler/GHC/Data/BooleanFormula.hs:40:23-29> IfConcreteClass 0x7f61cd16b440 0x7f61cd16b440 0x428f8c7018 0x428f8c7030 <IfaceClassBody:GHC.Iface.Make:compiler/GHC/Iface/Make.hs:(640,12)-(645,13)> ``` Making these few places strict is sufficient for now but there are perhaps more places which will need strictifying in future. ------------------------- Metric Increase: parsing001 ------------------------- - - - - - 7a8171bc by Tom Sydney Kerckhove at 2021-10-15T06:51:18+00:00 Insert warnings in the documentation of dangerous functions - - - - - 1cda768c by Joachim Breitner at 2021-10-15T18:15:36-04:00 GHC.Builtin.Uniques: Remove unused code a number of functions exported by this module are (no longer) used, so let’s remove them. In particular, it no longer seems to be the case that type variables have tag `'t'`, so removed the special handling when showing them. * the use of `initTyVarUnique` was removed in 7babb1 (with the notable commit message of "Before merging to HEAD we need to tidy up and write a proper commit message.") * `mkPseudoUniqueD`and `mkPseudoUniqueH` were added in 423d477, but never ever used? * `mkCoVarUnique` was added in 674654, but never ever used? - - - - - 88e913d4 by Oleg Grenrus at 2021-10-15T18:16:14-04:00 Null eventlog writer - - - - - bbb1f6da by Sylvain Henry at 2021-10-15T18:16:51-04:00 Hadrian: display command line above errors (#20490) - - - - - b6954f0c by Joachim Breitner at 2021-10-15T18:17:26-04:00 shadowNames: Use OccEnv a, not [OccName] this allows us to use a smarter implementation based on `Data.IntSet.differenceWith`, which should do less work. Also, it will unblock improvements to !6703. The `OccEnv a` really denotes a set of `OccName`s. We are not using `OccSet`, though, because that is an `OccEnv OccName`, and we in !6703 we want to use this with differently-valued `OccEnv`s. But `OccSet`s are readily and safely coerced into `OccEnv`s. There is no other use of `delLocalRdrEnvList` remaining, so removing that. - - - - - c9922a8e by Matthew Pickering at 2021-10-15T18:18:00-04:00 hadrian: Document lint targets Fixes #20508 - - - - - 65bf3992 by Matthew Pickering at 2021-10-17T14:06:08-04:00 ghci: Explicitly store and restore interface file cache In the old days the old HPT was used as an interface file cache when using ghci. The HPT is a `ModuleEnv HomeModInfo` and so if you were using hs-boot files then the interface file from compiling the .hs file would be present in the cache but not the hi-boot file. This used to be ok, because the .hi file used to just be a better version of the .hi-boot file, with more information so it was fine to reuse it. Now the source hash of a module is kept track of in the interface file and the source hash for the .hs and .hs-boot file are correspondingly different so it's no longer safe to reuse an interface file. I took the decision to move the cache management of interface files to GHCi itself, and provide an API where `load` can be provided with a list of interface files which can be used as a cache. An alternative would be to manage this cache somewhere in the HscEnv but it seemed that an API user should be responsible for populating and suppling the cache rather than having it managed implicitly. Fixes #20217 - - - - - 81740ce8 by sheaf at 2021-10-17T14:06:46-04:00 Introduce Concrete# for representation polymorphism checks PHASE 1: we never rewrite Concrete# evidence. This patch migrates all the representation polymorphism checks to the typechecker, using a new constraint form Concrete# :: forall k. k -> TupleRep '[] Whenever a type `ty` must be representation-polymorphic (e.g. it is the type of an argument to a function), we emit a new `Concrete# ty` Wanted constraint. If this constraint goes unsolved, we report a representation-polymorphism error to the user. The 'FRROrigin' datatype keeps track of the context of the representation-polymorphism check, for more informative error messages. This paves the way for further improvements, such as allowing type families in RuntimeReps and improving the soundness of typed Template Haskell. This is left as future work (PHASE 2). fixes #17907 #20277 #20330 #20423 #20426 updates haddock submodule ------------------------- Metric Decrease: T5642 ------------------------- - - - - - 19d1237e by Koz Ross at 2021-10-19T03:29:40-04:00 Fix infelicities in docs for lines, unlines, words, unwords - - - - - 3035d1a2 by Matthew Pickering at 2021-10-19T03:30:16-04:00 tests: Remove $(CABAL_MINIMAL_CONFIGURATION) from T16219 There is a latent issue in T16219 where -dynamic-too is enabled when compiling a signature file which causes us to enter the DT_Failed state because library-a-impl doesn't generate dyn_o files. Somehow this used to work in 8.10 (that also entered the DT_Failed state) We don't need dynamic object files when compiling a signature file but the code loads interfaces, and if dynamic-too is enabled then it will also try to load the dyn_hi file and check the two are consistent. There is another hack to do with this in `GHC.Iface.Recomp`. The fix for this test is to remove CABAL_MINIMAL_CONFIGURATION, which stops cabal building shared libraries by default. I'm of the opinion that the DT_Failed state indicates an error somewhere so we should hard fail rather than this confusing (broken) rerun logic. Whether this captures the original intent of #16219 is debateable, but it's not clear how it was supposed to work in the first place if the libraries didn't build dynamic object files. Module C imports module A, which is from a library where shared objects are not built so the test would never have worked anyway (if anything from A was used in a TH splice). - - - - - d25868b6 by Matthew Pickering at 2021-10-19T03:30:16-04:00 dynamic-too: Expand GHC.Iface.Recomp comment about the backpack hack - - - - - 837ce6cf by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Check the correct flag to see if dynamic-too is enabled. We just need to check the flag here rather than read the variable which indicates whether dynamic-too compilation has failed. - - - - - 981f2c74 by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Update cached DynFlags in ModSummary if we are enabling -dynamic-too - - - - - 1bc77a85 by Matthew Pickering at 2021-10-19T03:30:16-04:00 dynamic-too: Check the dynamic-too status in hscPipeline This "fixes" DT_Failed in --make mode, but only "fixes" because I still believe DT_Failed is pretty broken. - - - - - 51281e81 by Matthew Pickering at 2021-10-19T03:30:16-04:00 Add test for implicit dynamic too This test checks that we check for missing dynamic objects if dynamic-too is enabled implicitly by the driver. - - - - - 8144a92f by Matthew Pickering at 2021-10-19T03:30:16-04:00 WW: Use module name rather than filename for absent error messages WwOpts in WorkWrap.Utils initialised the wo_output_file field with the result of outputFile dflags. This is misguided because outputFile is only set when -o is specified, which is barely ever (and never in --make mode). It seems this is just used to add more context to an error message, a more appropriate thing to use I think would be a module name. Fixes #20438 - - - - - df419c1a by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Cleanups related to ModLocation ModLocation is the data type which tells you the locations of all the build products which can affect recompilation. It is now computed in one place and not modified through the pipeline. Important locations will now just consult ModLocation rather than construct the dynamic object path incorrectly. * Add paths for dynamic object and dynamic interface files to ModLocation. * Always use the paths from mod location when looking for where to find any interface or object file. * Always use the paths in a ModLocation when deciding where to write an interface and object file. * Remove `dynamicOutputFile` and `dynamicOutputHi` functions which *calculated* (incorrectly) the location of `dyn_o` and `dyn_hi` files. * Don't set `outputFile_` and so-on in `enableCodeGenWhen`, `-o` and hence `outputFile_` should not affect the location of object files in `--make` mode. It is now sufficient to just update the ModLocation with the temporary paths. * In `hscGenBackendPipeline` don't recompute the `ModLocation` to account for `-dynamic-too`, the paths are now accurate from the start of the run. * Rename `getLocation` to `mkOneShotModLocation`, as that's the only place it's used. Increase the locality of the definition by moving it close to the use-site. * Load the dynamic interface from ml_dyn_hi_file rather than attempting to reconstruct it in load_dynamic_too. * Add a variety of tests to check how -o -dyno etc interact with each other. Some other clean-ups * DeIOify mkHomeModLocation and friends, they are all pure functions. * Move FinderOpts into GHC.Driver.Config.Finder, next to initFinderOpts. * Be more precise about whether we mean outputFile or outputFile_: there were many places where outputFile was used but the result shouldn't have been affected by `-dyno` (for example the filename of the resulting executable). In these places dynamicNow would never be set but it's still more precise to not allow for this possibility. * Typo fixes suffices -> suffixes in the appropiate places. - - - - - 3d6eb85e by Matthew Pickering at 2021-10-19T03:30:16-04:00 driver: Correct output of -fno-code and -dynamic-too Before we would print [1 of 3] Compiling T[boot] ( T.hs-boot, nothing, T.dyn_o ) Which was clearly wrong for two reasons. 1. No dynamic object file was produced for T[boot] 2. The file would be called T.dyn_o-boot if it was produced. Fixes #20300 - - - - - 753b921d by Matthew Pickering at 2021-10-19T03:30:16-04:00 Remove DT_Failed state At the moment if `-dynamic-too` fails then we rerun the whole pipeline as if we were just in `-dynamic` mode. I argue this is a misfeature and we should remove the so-called `DT_Failed` mode. In what situations do we fall back to `DT_Failed`? 1. If the `dyn_hi` file corresponding to a `hi` file is missing completely. 2. If the interface hash of `dyn_hi` doesn't match the interface hash of `hi`. What happens in `DT_Failed` mode? * The whole compiler pipeline is rerun as if the user had just passed `-dynamic`. * Therefore `dyn_hi/dyn_o` files are used which don't agree with the `hi/o` files. (As evidenced by `dynamicToo001` test). * This is very confusing as now a single compiler invocation has produced further `hi`/`dyn_hi` files which are different to each other. Why should we remove it? * In `--make` mode, which is predominately used `DT_Failed` does not work (#19782), there can't be users relying on this functionality. * In `-c` mode, the recovery doesn't fix the root issue, which is the `dyn_hi` and `hi` files are mismatched. We should instead produce an error and pass responsibility to the build system using `-c` to ensure that the prerequisites for `-dynamic-too` (dyn_hi/hi) files are there before we start compiling. * It is a misfeature to support use cases like `dynamicToo001` which allow you to mix different versions of dynamic/non-dynamic interface files. It's more likely to lead to subtle bugs in your resulting programs where out-dated build products are used rather than a deliberate choice. * In practice, people are usually compiling with `-dynamic-too` rather than separately with `-dynamic` and `-static`, so the build products always match and `DT_Failed` is only entered due to compiler bugs (see !6583) What should we do instead? * In `--make` mode, for home packages check during recompilation checking that `dyn_hi` and `hi` are both present and agree, recompile the modules if they do not. * For package modules, when loading the interface check that `dyn_hi` and `hi` are there and that they agree but fail with an error message if they are not. * In `--oneshot` mode, fail with an error message if the right files aren't already there. Closes #19782 #20446 #9176 #13616 - - - - - 7271bf78 by Joachim Breitner at 2021-10-19T03:30:52-04:00 InteractiveContext: Smarter caching when rebuilding the ic_rn_gbl_env The GlobalRdrEnv of a GHCI session changes in odd ways: New bindings are not just added "to the end", but also "in the middle", namely when changing the set of imports: These are treated as if they happened before all bindings from the prompt, even those that happened earlier. Previously, this meant that the `ic_rn_gbl_env` is recalculated from the `ic_tythings`. But this wasteful if `ic_tythings` has many entries that define the same unqualified name. By separately keeping track of a `GlobalRdrEnv` of all the locally defined things we can speed this operation up significantly. This change improves `T14052Type` by 60% (It used to be 70%, but it looks that !6723 already reaped some of the rewards). But more importantly, it hopefully unblocks #20455, becaues with this smarter caching, the change needed to fix that issue will no longer make `T14052` explode. I hope. It does regress `T14052` by 30%; caching isn’t free. Oh well. Metric Decrease: T14052Type Metric Increase: T14052 - - - - - 53c0e771 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Add test for T20509 This test checks to see whether a signature can depend on another home module. Whether it should or not is up for debate, see #20509 for more details. - - - - - fdfb3b03 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Make the fields of Target and TargetId strict Targets are long-lived through GHC sessions so we don't want to end up retaining In particular in 'guessTarget', the call to `unitIdOrHomeUnit` was retaining reference to an entire stale HscEnv, which in turn retained reference to a stale HomePackageTable. Making the fields strict forces that place promptly and helps ensure that mistakes like this don't happen again. - - - - - 877e6685 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Temporary fix for leak with -fno-code (#20509) This hack inserted for backpack caused a very bad leak when using -fno-code where EPS entries would end up retaining stale HomePackageTables. For any interactive user, such as HLS, this is really bad as once the entry makes it's way into the EPS then it's there for the rest of the session. This is a temporary fix which "solves" the issue by filtering the HPT to only the part which is needed for the hack to work, but in future we want to separate out hole modules from the HPT entirely to avoid needing to do this kind of special casing. ------------------------- Metric Decrease: MultiLayerModulesDefsGhci ------------------------- - - - - - cfacac68 by Matthew Pickering at 2021-10-19T03:31:27-04:00 Add performance test for ghci, -fno-code and reloading (#20509) This test triggers the bad code path identified by #20509 where an entry into the EPS caused by importing Control.Applicative will retain a stale HomePackageTable. - - - - - 12d74ef7 by Richard Eisenberg at 2021-10-19T13:36:36-04:00 Care about specificity in pattern type args Close #20443. - - - - - 79c9c816 by Zubin Duggal at 2021-10-19T13:37:12-04:00 Don't print Shake Diagnostic messages (#20484) - - - - - f8ce38e6 by Emily Martins at 2021-10-19T22:21:26-04:00 Fix #19884: add warning to tags command, drop T10989 - - - - - d73131b9 by Ben Gamari at 2021-10-19T22:22:02-04:00 hadrian: Fix quoting in binary distribution installation Makefile Previously we failed to quote various paths in Hadrian's installation Makefile, resulting in #20506. - - - - - 949d7398 by Matthew Pickering at 2021-10-20T14:05:23-04:00 Add note about heap invariants [skip ci] At the moment the note just covers three important invariants but now there is a place to add more to if we think of them. - - - - - 2f75ffac by Ben Gamari at 2021-10-20T14:06:00-04:00 hadrian/doc: Add margin to staged-compilation figure - - - - - 5f274fbf by Ben Gamari at 2021-10-20T14:06:00-04:00 hadrian: Fix binary-dist support for cross-compilers Previously the logic which called ghc-pkg failed to account for the fact that the executable name may be prefixed with a triple. Moreover, the call must occur before we delete the settings file as ghc-pkg needs the latter. Fixes #20267. - - - - - 3e4b51ff by Matthew Pickering at 2021-10-20T14:06:36-04:00 Fix perf-nofib CI job The main change is to install the necessary build dependencies into an environment file using `caball install --lib`. Also updates the nofib submodule with a few fixes needed for the job to work. - - - - - ef92d889 by Matthew Pickering at 2021-10-20T14:07:12-04:00 Distribute HomeModInfo cache before starting upsweep This change means the HomeModInfo cache isn't retained until the end of upsweep and each cached interface can be collected immediately after its module is compiled. The result is lower peak memory usage when using GHCi. For Agda it reduced peak memory usage from about 1600M to 1200M. - - - - - 05b8a218 by Matthew Pickering at 2021-10-20T14:07:49-04:00 Make fields of GlobalRdrElt strict In order to do this I thought it was prudent to change the list type to a bag type to avoid doing a lot of premature work in plusGRE because of ++. Fixes #19201 - - - - - 0b575899 by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: constant folding for bigNatCompareWord# (#20361) - - - - - 758e0d7b by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: allow Integer predicates to inline (#20361) T17516 allocations increase by 48% because Integer's predicates are inlined in some Ord instance methods. These methods become too big to be inlined while they probably should: this is tracked in #20516. Metric Increase: T17516 - - - - - a901a1ae by Sylvain Henry at 2021-10-20T17:49:07-04:00 Bignum: allow Integer's signum to inline (#20361) Allow T12545 to increase because it only happens on CI with dwarf enabled and probably not related to this patch. Metric Increase: T12545 - - - - - 9ded1b17 by Matthew Pickering at 2021-10-20T17:49:42-04:00 Make sure ModIface values are still forced even if not written When we are not writing a ModIface to disk then the result can retain a lot of stuff. For example, in the case I was debugging the DocDeclsMap field was holding onto the entire HomePackageTable due to a single unforced thunk. Therefore, now if we're not going to write the interface then we still force deeply it in order to remove these thunks. The fields in the data structure are not made strict because when we read the field from the interface we don't want to load it immediately as there are parts of an interface which are unused a lot of the time. Also added a note to explain why not all the fields in a ModIface field are strict. The result of this is being able to load Agda in ghci and not leaking information across subsequent reloads. - - - - - 268857af by Matthew Pickering at 2021-10-20T17:50:19-04:00 ci: Move hlint jobs from quick-built into full-build This somewhat fixes the annoyance of not getting any "useful" feedback from a CI pipeline if you have a hlint failure. Now the hlint job runs in parallel with the other CI jobs so the feedback is recieved at the same time as other testsuite results. Fixes #20507 - - - - - f6f24515 by Joachim Breitner at 2021-10-20T17:50:54-04:00 instance Ord Name: Do not repeat default methods it is confusing to see what looks like it could be clever code, only to see that it does precisely the same thing as the default methods. Cleaning this up, to spare future readers the confusion. - - - - - 56b2b04f by Ziyang Liu at 2021-10-22T10:57:28-04:00 Document that `InScopeSet` is a superset of currently in-scope variables - - - - - 7f4e0e91 by Moritz Angermann at 2021-10-22T10:58:04-04:00 Do not sign extend CmmInt's unless negative. Might fix #20526. - - - - - 77c6f3e6 by sheaf at 2021-10-22T10:58:44-04:00 Use tcEqType in GHC.Core.Unify.uVar Because uVar used eqType instead of tcEqType, it was possible to accumulate a substitution that unified Type and Constraint. For example, a call to `tc_unify_tys` with arguments tys1 = [ k, k ] tys2 = [ Type, Constraint ] would first add `k = Type` to the substitution. That's fine, but then the second call to `uVar` would claim that the substitution also unifies `k` with `Constraint`. This could then be used to cause trouble, as per #20521. Fixes #20521 - - - - - fa5870d3 by Sylvain Henry at 2021-10-22T19:20:05-04:00 Add test for #19641 Now that Bignum predicates are inlined (!6696), we only need to add a test. Fix #19641 - - - - - 6fd7da74 by Sylvain Henry at 2021-10-22T19:20:44-04:00 Remove Indefinite We no longer need it after previous IndefUnitId refactoring. - - - - - 806e49ae by Sylvain Henry at 2021-10-22T19:20:44-04:00 Refactor package imports Use an (Raw)PkgQual datatype instead of `Maybe FastString` to represent package imports. Factorize the code that renames RawPkgQual into PkgQual in function `rnPkgQual`. Renaming consists in checking if the FastString is the magic "this" keyword, the home-unit unit-id or something else. Bump haddock submodule - - - - - 47ba842b by Haochen Tong at 2021-10-22T19:21:21-04:00 Fix compilerConfig stages Fix the call to compilerConfig because it accepts 1-indexed stage numbers. Also fixes `make stage=3`. - - - - - 621608c9 by Matthew Pickering at 2021-10-22T19:21:56-04:00 driver: Don't use the log queue abstraction when j = 1 This simplifies the code path for -j1 by not using the log queue queue abstraction. The result is that trace output isn't interleaved with other dump output like it can be with -j<N>. - - - - - dd2dba80 by Sebastian Graf at 2021-10-22T19:22:31-04:00 WorkWrap: `isRecDataCon` should not eta-reduce NewTyCon field tys (#20539) In #20539 we had a type ```hs newtype Measured a = Measured { unmeasure :: () -> a } ``` and `isRecDataCon Measured` recursed into `go_arg_ty` for `(->) ()`, because `unwrapNewTyConEtad_maybe` eta-reduced it. That triggered an assertion error a bit later. Eta reducing the field type is completely wrong to do here! Just call `unwrapNewTyCon_maybe` instead. Fixes #20539 and adds a regression test T20539. - - - - - 8300ca2e by Ben Gamari at 2021-10-24T01:26:11-04:00 driver: Export wWarningFlagMap A new feature requires Ghcide to be able to convert warnings to CLI flags (WarningFlag -> String). This is most easily implemented in terms of the internal function flagSpecOf, which uses an inefficient implementation based on linear search through a linked list. This PR derives Ord for WarningFlag, and replaces that list with a Map. Closes #19087. - - - - - 3bab222c by Sebastian Graf at 2021-10-24T01:26:46-04:00 DmdAnal: Implement Boxity Analysis (#19871) This patch fixes some abundant reboxing of `DynFlags` in `GHC.HsToCore.Match.Literal.warnAboutOverflowedLit` (which was the topic of #19407) by introducing a Boxity analysis to GHC, done as part of demand analysis. This allows to accurately capture ad-hoc unboxing decisions previously made in worker/wrapper in demand analysis now, where the boxity info can propagate through demand signatures. See the new `Note [Boxity analysis]`. The actual fix for #19407 is described in `Note [No lazy, Unboxed demand in demand signature]`, but `Note [Finalising boxity for demand signature]` is probably a better entry-point. To support the fix for #19407, I had to change (what was) `Note [Add demands for strict constructors]` a bit (now `Note [Unboxing evaluated arguments]`). In particular, we now take care of it in `finaliseBoxity` (which is only called from demand analaysis) instead of `wantToUnboxArg`. I also had to resurrect `Note [Product demands for function body]` and rename it to `Note [Unboxed demand on function bodies returning small products]` to avoid huge regressions in `join004` and `join007`, thereby fixing #4267 again. See the updated Note for details. A nice side-effect is that the worker/wrapper transformation no longer needs to look at strictness info and other bits such as `InsideInlineableFun` flags (needed for `Note [Do not unbox class dictionaries]`) at all. It simply collects boxity info from argument demands and interprets them with a severely simplified `wantToUnboxArg`. All the smartness is in `finaliseBoxity`, which could be moved to DmdAnal completely, if it wasn't for the call to `dubiousDataConInstArgTys` which would be awkward to export. I spent some time figuring out the reason for why `T16197` failed prior to my amendments to `Note [Unboxing evaluated arguments]`. After having it figured out, I minimised it a bit and added `T16197b`, which simply compares computed strictness signatures and thus should be far simpler to eyeball. The 12% ghc/alloc regression in T11545 is because of the additional `Boxity` field in `Poly` and `Prod` that results in more allocation during `lubSubDmd` and `plusSubDmd`. I made sure in the ticky profiles that the number of calls to those functions stayed the same. We can bear such an increase here, as we recently improved it by -68% (in b760c1f). T18698* regress slightly because there is more unboxing of dictionaries happening and that causes Lint (mostly) to allocate more. Fixes #19871, #19407, #4267, #16859, #18907 and #13331. Metric Increase: T11545 T18698a T18698b Metric Decrease: T12425 T16577 T18223 T18282 T4267 T9961 - - - - - 691c450f by Alan Zimmerman at 2021-10-24T01:27:21-04:00 EPA: Use LocatedA for ModuleName This allows us to use an Anchor with a DeltaPos in it when exact printing. - - - - - 3417a81a by Joachim Breitner at 2021-10-24T01:27:57-04:00 undefined: Neater CallStack in error message Users of `undefined` don’t want to see ``` files.hs: Prelude.undefined: CallStack (from HasCallStack): error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err undefined, called at file.hs:151:19 in main:Main ``` but want to see ``` files.hs: Prelude.undefined: CallStack (from HasCallStack): undefined, called at file.hs:151:19 in main:Main ``` so let’s make that so. The function for that is `withFrozenCallStack`, but that is not usable here (module dependencies, and also not representation-polymorphic). And even if it were, it could confuse GHC’s strictness analyzer, leading to big regressions in some perf tests (T10421 in particular). So after shuffling modules and definitions around, I eventually noticed that the easiest way is to just not call `error` here. Fixes #19886 - - - - - 98aa29d3 by John Ericson at 2021-10-24T01:28:33-04:00 Fix dangling reference to RtsConfig.h It hasn't existed since a2a67cd520b9841114d69a87a423dabcb3b4368e -- in 2009! - - - - - 9cde38a0 by John Ericson at 2021-10-25T17:45:15-04:00 Remove stray reference to `dist-ghcconstants` I think this hasn't been a thing since 86054b4ab5125a8b71887b06786d0a428539fb9c, almost 10 years ago! - - - - - 0f7541dc by Viktor Dukhovni at 2021-10-25T17:45:51-04:00 Tweak descriptions of lines and unlines It seems more clear to think of lines as LF-terminated rather than LF-separated. - - - - - 0255ef38 by Zubin Duggal at 2021-10-26T12:36:24-04:00 Warn if unicode bidirectional formatting characters are found in the source (#20263) - - - - - 9cc6c193 by sheaf at 2021-10-26T12:37:02-04:00 Don't default type variables in type families This patch removes the following defaulting of type variables in type and data families: - type variables of kind RuntimeRep defaulting to LiftedRep - type variables of kind Levity defaulting to Lifted - type variables of kind Multiplicity defaulting to Many It does this by passing "defaulting options" to the `defaultTyVars` function; when calling from `tcTyFamInstEqnGuts` or `tcDataFamInstHeader` we pass options that avoid defaulting. This avoids wildcards being defaulted, which caused type families to unexpectedly fail to reduce. Note that kind defaulting, applicable only with -XNoPolyKinds, is not changed by this patch. Fixes #17536 ------------------------- Metric Increase: T12227 ------------------------- - - - - - cc113616 by Artyom Kuznetsov at 2021-10-26T20:27:33+00:00 Change CaseAlt and LambdaExpr to FunRhs in deriving Foldable and Traversable (#20496) - - - - - 9bd6daa4 by John Ericson at 2021-10-27T13:29:39-04:00 Make build system: Generalize and/or document distdirs `manual-package-config` should not hard-code the distdir, and no longer does Elsewhere, we must continue to hard-code due to inconsitent distdir names across stages, so we document this referring to the existing note "inconsistent distdirs". - - - - - 9d577ea1 by John Ericson at 2021-10-27T13:30:15-04:00 Compiler dosen't need to know about certain settings from file - RTS and libdw - SMP - RTS ways I am leaving them in the settings file because `--info` currently prints all the fields in there, but in the future I do believe we should separate the info GHC actually needs from "extra metadata". The latter could go in `+RTS --info` and/or a separate file that ships with the RTS for compile-time inspection instead. - - - - - ed9ec655 by Ben Gamari at 2021-10-27T13:30:55-04:00 base: Note export of Data.Tuple.Solo in changelog - - - - - 638f6548 by Ben Gamari at 2021-10-27T13:30:55-04:00 hadrian: Turn the `static` flavour into a transformer This turns the `static` flavour into the `+fully_static` flavour transformer. - - - - - 522eab3f by Ziyang Liu at 2021-10-29T05:01:50-04:00 Show family TyCons in mk_dict_error in the case of a single match - - - - - 71700526 by Sebastian Graf at 2021-10-29T05:02:25-04:00 Add more INLINABLE and INLINE pragmas to `Enum Int*` instances Otherwise the instances aren't good list producers. See Note [Stable Unfolding for list producers]. - - - - - 925c47b4 by Sebastian Graf at 2021-10-29T05:02:25-04:00 WorkWrap: Update Unfolding with WW'd body prior to `tryWW` (#20510) We have a function in #20510 that is small enough to get a stable unfolding in WW: ```hs small :: Int -> Int small x = go 0 x where go z 0 = z * x go z y = go (z+y) (y-1) ``` But it appears we failed to use the WW'd RHS as the stable unfolding. As a result, inlining `small` would expose the non-WW'd version of `go`. That appears to regress badly in #19727 which is a bit too large to extract a reproducer from that is guaranteed to reproduce across GHC versions. The solution is to simply update the unfolding in `certainlyWillInline` with the WW'd RHS. Fixes #20510. - - - - - 7b67724b by John Ericson at 2021-10-29T16:57:48-04:00 make build system: RTS should use dist-install not dist This is the following find and replace: - `rts/dist` -> `rts/dist-install` # for paths - `rts_dist` -> `rts_dist-install` # for make rules and vars - `,dist` -> `,dist-install` # for make, just in rts/ghc.mk` Why do this? Does it matter when the RTS is just built once? The answer is, yes, I think it does, because I want the distdir--stage correspondence to be consistent. In particular, for #17191 and continuing from d5de970dafd5876ef30601697576167f56b9c132 I am going to make the headers (`rts/includes`) increasingly the responsibility of the RTS (hence their new location). However, those headers are current made for multiple stages. This will probably become unnecessary as work on #17191 progresses and the compiler proper becomes more of a freestanding cabal package (e.g. a library that can be downloaded from Hackage and built without any autoconf). However, until that is finished, we have will transitional period where the RTS and headers need to agree on dirs for multiple stages. I know the make build system is going away, but it's not going yet, so I need to change it to unblock things :). - - - - - b0a1ed55 by Sylvain Henry at 2021-10-29T16:58:35-04:00 Add test for T15547 (#15547) Fix #15547 - - - - - c8d89f62 by Sylvain Henry at 2021-10-29T16:58:35-04:00 Bignum: add missing rule Add missing "Natural -> Integer -> Word#" rule. - - - - - 2a4581ff by sheaf at 2021-10-29T16:59:13-04:00 User's guide: data family kind-inference changes Explain that the kind of a data family instance must now be fully determined by the header of the instance, and how one might migrate code to account for this change. Fixes #20527 - - - - - ea862ef5 by Ben Gamari at 2021-10-30T15:43:28-04:00 ghci: Make getModBreaks robust against DotO Unlinked Previously getModBreaks assumed that an interpreted linkable will have only a single `BCOs` `Unlinked` entry. However, in general an object may also contain `DotO`s; ignore these. Fixes #20570. - - - - - e4095c0c by John Ericson at 2021-10-31T09:04:41-04:00 Make build system: Put make generated include's in RTS distdirs These are best thought of as being part of the RTS. - After !6791, `ghcautoconf.h` won't be used by the compiler inappropriately. - `ghcversion.h` is only used once outside the RTS, which is `compiler/cbits/genSym.c`. Except we *do* mean the RTS GHC is built against there, so it's better if we always get get the installed version. - `ghcplatform.h` alone is used extensively outside the RTS, but since we no longer have a target platform it is perfectly safe/correct to get the info from the previous RTS. All 3 are exported from the RTS currently and in the bootstrap window. This commit just swaps directories around, such that the new headers may continue to be used in stage 0 despite the reasoning above, but the idea is that we can subsequently make more interesting changes doubling down on the reasoning above. In particular, in !6803 we'll start "morally" moving `ghcautonconf.h` over, introducing an RTS configure script and temporary header of its `AC_DEFINE`s until the top-level configure script doesn't define any more. Progress towards #17191 - - - - - f5471c0b by John Ericson at 2021-10-31T09:05:16-04:00 Modularize autoconf platform detection This will allow better reuse of it, such as in the upcoming RTS configure script. Progress towards #17191 - - - - - 6b38c8a6 by Ben Gamari at 2021-10-31T09:05:52-04:00 ghc: Bump Cabal-Version to 1.22 This is necessary to use reexported-modules - - - - - 6544446d by Ben Gamari at 2021-10-31T09:05:52-04:00 configure: Hide error output from --target check - - - - - 7445bd71 by Andreas Klebinger at 2021-11-01T12:13:45+00:00 Update comment in Lint.hs mkWwArgs has been renamed to mkWorkerArgs. - - - - - f1a782dd by Vladislav Zavialov at 2021-11-02T01:36:32-04:00 HsToken for let/in (#19623) One more step towards the new design of EPA. - - - - - 37a37139 by John Ericson at 2021-11-02T01:37:08-04:00 Separate some AC_SUBST / AC_DEFINE Eventually, the RTS configure alone will need the vast majority of AC_DEFINE, and the top-level configure will need the most AC_SUBST. By removing the "side effects" of the macros like this we make them more reusable so they can be shared between the two configures without doing too much. - - - - - 2f69d102 by John Ericson at 2021-11-02T01:37:43-04:00 Remove `includes_GHCCONSTANTS` from make build system It is dead code. - - - - - da1a8e29 by John Ericson at 2021-11-02T01:37:43-04:00 Treat generated RTS headers in a more consistent manner We can depend on all of them at once the same way. - - - - - a7e1be3d by Ryan Scott at 2021-11-02T01:38:53-04:00 Fix #20590 with another application of mkHsContextMaybe We were always converting empty GADT contexts to `Just []` in `GHC.ThToHs`, which caused the pretty-printer to always print them as `() => ...`. This is easily fixed by using the `mkHsContextMaybe` function when converting GADT contexts so that empty contexts are turned to `Nothing`. This is in the same tradition established in commit 4c87a3d1d14f9e28c8aa0f6062e9c4201f469ad7. In the process of fixing this, I discovered that the `Cxt` argument to `mkHsContextMaybe` is completely unnecessary, as we can just as well check if the `LHsContext GhcPs` argument is empty. Fixes #20590. - - - - - 39eed84c by Alan Zimmerman at 2021-11-02T21:39:32+00:00 EPA: Get rid of bare SrcSpan's in the ParsedSource The ghc-exactPrint library has had to re-introduce the relatavise phase. This is needed if you change the length of an identifier and want the layout to be preserved afterwards. It is not possible to relatavise a bare SrcSpan, so introduce `SrcAnn NoEpAnns` for them instead. Updates haddock submodule. - - - - - 9f42a6dc by ARATA Mizuki at 2021-11-03T09:19:17-04:00 hadrian: Use $bindir instead of `dirname $0` in ghci wrapper `dirname $0` doesn't work when the wrapper is called via a symbolic link. Fix #20589 - - - - - bf6f96a6 by Vladislav Zavialov at 2021-11-03T16:35:50+03:00 Generalize the type of wrapLocSndMA - - - - - 1419fb16 by Matthew Pickering at 2021-11-04T00:36:09-04:00 ci: Don't run alpine job in fast-ci - - - - - 6020905a by Takenobu Tani at 2021-11-04T09:40:42+00:00 Correct load_load_barrier for risc-v This patch corrects the instruction for load_load_barrier(). Current load_load_barrier() incorrectly uses `fence w,r`. It means a store-load barrier. See also linux-kernel's smp_rmb() implementation: https://github.com/torvalds/linux/blob/v5.14/arch/riscv/include/asm/barrier.h#L27 - - - - - 086e288c by Richard Eisenberg at 2021-11-04T13:04:44-04:00 Tiny renamings and doc updates Close #20433 - - - - - f0b920d1 by CarrieMY at 2021-11-05T05:30:13-04:00 Fix deferOutOfScopeVariables for qualified #20472 - - - - - 59dfb005 by Simon Peyton Jones at 2021-11-05T05:30:48-04:00 Remove record field from Solo Ticket #20562 revealed that Solo, which is a wired-in TyCon, had a record field that wasn't being added to the type env. Why not? Because wired-in TyCons don't have record fields. It's not hard to change that, but it's tiresome for this one use-case, and it seems easier simply to make `getSolo` into a standalone function. On the way I refactored the handling of Solo slightly, to put it into wiredInTyCons (where it belongs) rather than only in knownKeyNames - - - - - be3750a5 by Matthew Pickering at 2021-11-05T10:12:16-04:00 Allow CApi FFI calls in GHCi At some point in the past this started working. I noticed this when working on multiple home units and couldn't load GHC's dependencies into the interpreter. Fixes #7388 - - - - - d96ce59d by John Ericson at 2021-11-05T10:12:52-04:00 make: Futher systematize handling of generated headers This will make it easier to add and remove generated headers, as we will do when we add a configure script for the RTS. - - - - - 3645abac by John Ericson at 2021-11-05T20:25:32-04:00 Avoid GHC_STAGE and other include bits We should strive to make our includes in terms of the RTS as much as possible. One place there that is not possible, the llvm version, we make a new tiny header Stage numbers are somewhat arbitrary, if we simple need a newer RTS, we should say so. - - - - - 4896a6a6 by Matthew Pickering at 2021-11-05T20:26:07-04:00 Fix boolean confusion with Opt_NoLlvmMangler flag I accidently got the two branches of the if expression the wrong way around when refactoring. Fixes #20567 - - - - - d74cc01e by Ziyang Liu at 2021-11-06T07:53:06-04:00 Export `withTcPlugins` and `withHoleFitPlugins` - - - - - ecd6d142 by Sylvain Henry at 2021-11-06T07:53:42-04:00 i386: fix codegen of 64-bit comparisons - - - - - e279ea64 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Add missing Int64/Word64 constant-folding rules - - - - - 4c86df25 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Fix Int64ToInt/Word64ToWord rules on 32-bit architectures When the input literal was larger than 32-bit it would crash in a compiler with assertion enabled because it was creating an out-of-bound word-sized literal (32-bit). - - - - - 646c3e21 by Sylvain Henry at 2021-11-06T07:53:42-04:00 CI: allow perf-nofib to fail - - - - - 20956e57 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Remove target dependent CPP for Word64/Int64 (#11470) Primops types were dependent on the target word-size at *compiler* compilation time. It's an issue for multi-target as GHC may not have the correct primops types for the target. This patch fixes some primops types: if they take or return fixed 64-bit values they now always use `Int64#/Word64#`, even on 64-bit architectures (where they used `Int#/Word#` before). Users of these primops may now need to convert from Int64#/Word64# to Int#/Word# (a no-op at runtime). This is a stripped down version of !3658 which goes the all way of changing the underlying primitive types of Word64/Int64. This is left for future work. T12545 allocations increase ~4% on some CI platforms and decrease ~3% on AArch64. Metric Increase: T12545 Metric Decrease: T12545 - - - - - 2800eee2 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Make Word64 use Word64# on every architecture - - - - - be9d7862 by Sylvain Henry at 2021-11-06T07:53:42-04:00 Fix Int64/Word64's Enum instance fusion Performance improvement: T15185(normal) run/alloc 51112.0 41032.0 -19.7% GOOD Metric Decrease: T15185 - - - - - 6f2d6a5d by Nikolay Yakimov at 2021-11-06T11:24:50-04:00 Add regression test for #20568 GHC produced broken executables with rebindable if and -fhpc if `ifThenElse` expected non-Bool condition until GHC 9.0. This adds a simple regression test. - - - - - 7045b783 by Vladislav Zavialov at 2021-11-06T11:25:25-04:00 Refactor HdkM using deriving via * No more need for InlineHdkM, mkHdkM * unHdkM is now just a record selector * Update comments - - - - - 0d8a883e by Andreas Klebinger at 2021-11-07T12:54:30-05:00 Don't undersaturate join points through eta-reduction. In #20599 I ran into an issue where the unfolding for a join point was eta-reduced removing the required lambdas. This patch adds guards that should prevent this from happening going forward. - - - - - 3d7e3d91 by Vladislav Zavialov at 2021-11-07T12:55:05-05:00 Print the Type kind qualified when ambiguous (#20627) The Type kind is printed unqualified: ghci> :set -XNoStarIsType ghci> :k (->) (->) :: Type -> Type -> Type This is the desired behavior unless the user has defined their own Type: ghci> data Type Then we want to resolve the ambiguity by qualification: ghci> :k (->) (->) :: GHC.Types.Type -> GHC.Types.Type -> GHC.Types.Type - - - - - 184f6bc6 by John Ericson at 2021-11-07T16:26:10-05:00 Factor out unregisterised and tables next to code m4 macros These will be useful for upcoming RTS configure script. - - - - - 56705da8 by Sebastian Graf at 2021-11-07T16:26:46-05:00 Pmc: Do inhabitation test for unlifted vars (#20631) Although I thought we were already set to handle unlifted datatypes correctly, it appears we weren't. #20631 showed that it's wrong to assume `vi_bot=IsNotBot` for `VarInfo`s of unlifted types from their inception if we don't follow up with an inhabitation test to see if there are any habitable constructors left. We can't trigger the test from `emptyVarInfo`, so now we instead fail early in `addBotCt` for variables of unlifted types. Fixed #20631. - - - - - 28334b47 by sheaf at 2021-11-08T13:40:05+01:00 Default kind vars in tyfams with -XNoPolyKinds We should still default kind variables in type families in the presence of -XNoPolyKinds, to avoid suggesting enabling -XPolyKinds just because the function arrow introduced kind variables, e.g. type family F (t :: Type) :: Type where F (a -> b) = b With -XNoPolyKinds, we should still default `r :: RuntimeRep` in `a :: TYPE r`. Fixes #20584 - - - - - 3f103b1a by John Ericson at 2021-11-08T19:35:12-05:00 Factor out GHC_ADJUSTORS_METHOD m4 macro - - - - - ba9fdc51 by John Ericson at 2021-11-08T19:35:12-05:00 Factor out FP_FIND_LIBFFI and use in RTS configure too - - - - - 2929850f by Sylvain Henry at 2021-11-09T10:02:06-05:00 RTS: open timerfd synchronously (#20618) - - - - - bc498fdf by Sylvain Henry at 2021-11-09T10:02:46-05:00 Bignum: expose backendName (#20495) - - - - - 79a26df1 by Sylvain Henry at 2021-11-09T10:02:46-05:00 Don't expose bignum backend in ghc --info (#20495) GHC is bignum backend agnostic and shouldn't report this information as in the future ghc-bignum will be reinstallable potentially with a different backend that GHC is unaware of. Moreover as #20495 shows the returned information may be wrong currently. - - - - - e485f4f2 by Andreas Klebinger at 2021-11-09T19:54:31-05:00 SpecConstr - Attach evaldUnfolding to known evaluated arguments. - - - - - 983a99f0 by Ryan Scott at 2021-11-09T19:55:07-05:00 deriving: infer DatatypeContexts from data constructors, not type constructor Previously, derived instances that use `deriving` clauses would infer `DatatypeContexts` by using `tyConStupidTheta`. But this sometimes causes redundant constraints to be included in the derived instance contexts, as the constraints that appear in the `tyConStupidTheta` may not actually appear in the types of the data constructors (i.e., the `dataConStupidTheta`s). For instance, in `data Show a => T a = MkT deriving Eq`, the type of `MkT` does not require `Show`, so the derived `Eq` instance should not require `Show` either. This patch makes it so with some small tweaks to `inferConstraintsStock`. Fixes #20501. - - - - - bdd7b2be by Ryan Scott at 2021-11-09T19:55:07-05:00 Flesh out Note [The stupid context] and reference it `Note [The stupid context]` in `GHC.Core.DataCon` talks about stupid contexts from `DatatypeContexts`, but prior to this commit, it was rather outdated. This commit spruces it up and references it from places where it is relevant. - - - - - 95563259 by Li-yao Xia at 2021-11-10T09:16:21-05:00 Fix rendering of Applicative law - - - - - 0f852244 by Viktor Dukhovni at 2021-11-10T09:16:58-05:00 Improve ZipList section of Traversable overview - Fix cut/paste error by adding missing `c` pattern in `Vec3` traversable instance. - Add a bit of contextual prose above the Vec2/Vec3 instance sample code. - - - - - c4cd13b8 by Richard Eisenberg at 2021-11-10T18:18:19-05:00 Fix Note [Function types] Close #19938. - - - - - dfb9913c by sheaf at 2021-11-10T18:18:59-05:00 Improvements to rank_polymorphism.rst - rename the function f4 to h1 for consistency with the naming convention - be more explicit about the difference between `Int -> (forall a. a -> a)` and `forall a. Int -> (a -> a)` - reorder the section to make it flow better Fixes #20585 - - - - - 1540f556 by sheaf at 2021-11-10T18:19:37-05:00 Clarify hs-boot file default method restrictions The user guide wrongly stated that default methods should not be included in hs-boot files. In fact, if the class is not left abstract (no methods, no superclass constraints, ...) then the defaults must be provided and match with those given in the .hs file. We add some tests for this, as there were no tests in the testsuite that gave rise to the "missing default methods" error. Fixes #20588 - - - - - 8c0aec38 by Sylvain Henry at 2021-11-10T18:20:17-05:00 Hadrian: fix building/registering of .dll libraries - - - - - 11c9a469 by Matthew Pickering at 2021-11-11T07:21:28-05:00 testsuite: Convert hole fit performance tests into proper perf tests Fixes #20621 - - - - - c2ed85cb by Matthew Pickering at 2021-11-11T07:22:03-05:00 driver: Cache the transitive dependency calculation in ModuleGraph Two reasons for this change: 1. Avoid computing the transitive dependencies when compiling each module, this can save a lot of repeated work. 2. More robust to forthcoming changes to support multiple home units. - - - - - 4230e4fb by Matthew Pickering at 2021-11-11T07:22:03-05:00 driver: Use shared transitive dependency calculation in hptModulesBelow This saves a lot of repeated work on big dependency graphs. ------------------------- Metric Decrease: MultiLayerModules T13719 ------------------------- - - - - - af653b5f by Matthew Bauer at 2021-11-11T07:22:39-05:00 Only pass -pie, -no-pie when linking Previously, these flags were passed when both compiling and linking code. However, `-pie` and `-no-pie` are link-time-only options. Usually, this does not cause issues, but when using Clang with `-Werror` set results in errors: clang: error: argument unused during compilation: '-nopie' [-Werror,-Wunused-command-line-argument] This is unused by Clang because this flag has no effect at compile time (it’s called `-nopie` internally by Clang but called `-no-pie` in GHC for compatibility with GCC). Just passing these flags at linking time resolves this. Additionally, update #15319 hack to look for `-pgml` instead. Because of the main change, the value of `-pgmc` does not matter when checking for the workaround of #15319. However, `-pgml` *does* still matter as not all `-pgml` values support `-no-pie`. To cover all potential values, we assume that no custom `-pgml` values support `-no-pie`. This means that we run the risk of not using `-no-pie` when it is otherwise necessary for in auto-hardened toolchains! This could be a problem at some point, but this workaround was already introduced in 8d008b71 and we might as well continue supporting it. Likewise, mark `-pgmc-supports-no-pie` as deprecated and create a new `-pgml-supports-no-pie`. - - - - - 7cc6ebdf by Sebastian Graf at 2021-11-11T07:23:14-05:00 Add regression test for #20598 Fixes #20598, which is mostly a duplicate of #18824 but for GHC 9.2. - - - - - 7b44c816 by Simon Jakobi at 2021-11-12T21:20:17-05:00 Turn GHC.Data.Graph.Base.Graph into a newtype - - - - - a57cc754 by John Ericson at 2021-11-12T21:20:52-05:00 Make: Do not generate ghc.* headers in stage0 GHC should get everything it needs from the RTS, which for stage0 is the "old" RTS that comes from the bootstrap compiler. - - - - - 265ead8a by Richard Eisenberg at 2021-11-12T21:21:27-05:00 Improve redundant-constraints warning Previously, we reported things wrong with f :: (Eq a, Ord a) => a -> Bool f x = x == x saying that Eq a was redundant. This is fixed now, along with some simplification in Note [Replacement vs keeping]. There's a tiny bit of extra complexity in setImplicationStatus, but it's explained in Note [Tracking redundant constraints]. Close #20602 - - - - - ca90ffa3 by Richard Eisenberg at 2021-11-12T21:21:27-05:00 Use local instances with least superclass depth See new Note [Use only the best local instance] in GHC.Tc.Solver.Interact. This commit also refactors the InstSC/OtherSC mechanism slightly. Close #20582. - - - - - dfc4093c by Vladislav Zavialov at 2021-11-12T21:22:03-05:00 Implement -Wforall-identifier (#20609) In accordance with GHC Proposal #281 "Visible forall in types of terms": For three releases before this change takes place, include a new warning -Wforall-identifier in -Wdefault. This warning will be triggered at definition sites (but not use sites) of forall as an identifier. Updates the haddock submodule. - - - - - 4143bd21 by Cheng Shao at 2021-11-12T21:22:39-05:00 hadrian: use /bin/sh in timeout wrapper /usr/bin/env doesn't work within a nix build. - - - - - 43cab5f7 by Simon Peyton Jones at 2021-11-12T21:23:15-05:00 Get the in-scope set right in simplArg This was a simple (but long standing) error in simplArg, revealed by #20639 - - - - - 578b8b48 by Ben Gamari at 2021-11-12T21:23:51-05:00 gitlab-ci: Allow draft MRs to fail linting jobs Addresses #20623 by allowing draft MRs to fail linting jobs. - - - - - 908e49fa by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - 05166660 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - e41cffb0 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - cce3a025 by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - 4499db7d by Ben Gamari at 2021-11-12T21:23:51-05:00 Fix it - - - - - dd1be88b by Travis Whitaker at 2021-11-12T21:24:29-05:00 mmapForLinkerMarkExecutable: do nothing when len = 0 - - - - - 4c6ace75 by John Ericson at 2021-11-12T21:25:04-05:00 Delete compiler/MachDeps.h This was accidentally added back in 28334b475a109bdeb8d53d58c48adb1690e2c9b4 after it is was no longer needed by the compiler proper in 20956e5784fe43781d156dd7ab02f0bff4ab41fb. - - - - - 490e8c75 by John Ericson at 2021-11-12T21:25:40-05:00 Generate ghcversion.h with the top-level configure This is, rather unintuitively, part of the goal of making the packages that make of the GHC distribution more freestanding. `ghcversion.h` is very simple, so we easily can move it out of the main build systems (make and Hadrian). By doing so, the RTS becomes less of a special case to those build systems as the header, already existing in the source tree, appears like any other. We could do this with the upcomming RTS configure, but it hardly matters because there is nothing platform-specific here, it is just versioning information like the other files the top-level configure can be responsible for. - - - - - bba156f3 by John Ericson at 2021-11-12T21:26:15-05:00 Remove bit about size_t in ghc-llvm-version.h This shouldn't be here. It wasn't causing a problem because this header was only used from Haskell, but still. - - - - - 0b1da2f1 by John Ericson at 2021-11-12T21:26:50-05:00 Make: Install RTS headers in `$libdir/rts/include` not `$libdir/include` Before we were violating the convention of every other package. This fixes that. It matches the changes made in d5de970dafd5876ef30601697576167f56b9c132 to the location of the files in the repo. - - - - - b040d0d4 by Sebastian Graf at 2021-11-12T21:27:26-05:00 Add regression test for #20663 - - - - - c6065292 by John Ericson at 2021-11-12T21:28:02-05:00 Make: Move remaining built RTS headers to ...build/include This allows us to clean up the rts include dirs in the package conf. - - - - - aa372972 by Ryan Scott at 2021-11-15T10:17:57-05:00 Refactoring: Consolidate some arguments with DerivInstTys Various functions in GHC.Tc.Deriv.* were passing around `TyCon`s and `[Type]`s that ultimately come from the same `DerivInstTys`. This patch moves the definition of `DerivInstTys` to `GHC.Tc.Deriv.Generate` so that all of these `TyCon` and `[Type]` arguments can be consolidated into a single `DerivInstTys`. Not only does this make the code easier to read (in my opinion), this will also be important in a subsequent commit where we need to add another field to `DerivInstTys` that will also be used from `GHC.Tc.Deriv.Generate` and friends. - - - - - 564a19af by Ryan Scott at 2021-11-15T10:17:57-05:00 Refactoring: Move DataConEnv to GHC.Core.DataCon `DataConEnv` will prove to be useful in another place besides `GHC.Core.Opt.SpecConstr` in a follow-up commit. - - - - - 3e5f0595 by Ryan Scott at 2021-11-15T10:17:57-05:00 Instantiate field types properly in stock-derived instances Previously, the `deriving` machinery was very loosey-goosey about how it used the types of data constructor fields when generating code. It would usually just consult `dataConOrigArgTys`, which returns the _uninstantiated_ field types of each data constructor. Usually, you can get away with this, but issues #20375 and #20387 revealed circumstances where this approach fails. Instead, when generated code for a stock-derived instance `C (T arg_1 ... arg_n)`, one must take care to instantiate the field types of each data constructor with `arg_1 ... arg_n`. The particulars of how this is accomplished is described in the new `Note [Instantiating field types in stock deriving]` in `GHC.Tc.Deriv.Generate`. Some highlights: * `DerivInstTys` now has a new `dit_dc_inst_arg_env :: DataConEnv [Type]` field that caches the instantiated field types of each data constructor. Whenever we need to consult the field types somewhere in `GHC.Tc.Deriv.*` we avoid using `dataConOrigArgTys` and instead look it up in `dit_dc_inst_arg_env`. * Because `DerivInstTys` now stores the instantiated field types of each constructor, some of the details of the `GHC.Tc.Deriv.Generics.mkBindsRep` function were able to be simplified. In particular, we no longer need to apply a substitution to instantiate the field types in a `Rep(1)` instance, as that is already done for us by `DerivInstTys`. We still need a substitution to implement the "wrinkle" section of `Note [Generating a correctly typed Rep instance]`, but the code is nevertheless much simpler than before. * The `tyConInstArgTys` function has been removed in favor of the new `GHC.Core.DataCon.dataConInstUnivs` function, which is really the proper tool for the job. `dataConInstUnivs` is much like `tyConInstArgTys` except that it takes a data constructor, not a type constructor, as an argument, and it adds extra universal type variables from that data constructor at the end of the returned list if need be. `dataConInstUnivs` takes care to instantiate the kinds of the universal type variables at the end, thereby avoiding a bug in `tyConInstArgTys` discovered in https://gitlab.haskell.org/ghc/ghc/-/issues/20387#note_377037. Fixes #20375. Fixes #20387. - - - - - 25d36c31 by John Ericson at 2021-11-15T10:18:32-05:00 Make: Get rid of GHC_INCLUDE_DIRS These dirs should not be included in all stages. Instead make the per-stage `BUILD_*_INCLUDE_DIR` "plural" to insert `rts/include` in the right place. - - - - - b679721a by John Ericson at 2021-11-15T10:18:32-05:00 Delete dead code knobs for building GHC itself As GHC has become target agnostic, we've left behind some now-useless logic in both build systems. - - - - - 3302f42a by Sylvain Henry at 2021-11-15T13:19:42-05:00 Fix windres invocation I've already fixed this 7 months ago in the comments of #16780 but it never got merged. Now we need this for #20657 too. - - - - - d9f54905 by Sylvain Henry at 2021-11-15T13:19:42-05:00 Hadrian: fix windows cross-build (#20657) Many small things to fix: * Hadrian: platform triple is "x86_64-w64-mingw32" and this wasn't recognized by Hadrian (note "w64" instead of "unknown") * Hadrian was using the build platform ("isWindowsHost") to detect the use of the Windows toolchain, which was wrong. We now use the "targetOs" setting. * Hadrian was doing the same thing for Darwin so we fixed both at once, even if cross-compilation to Darwin is unlikely to happen afaik (cf "osxHost" vs "osxTarget" changes) * Hadrian: libffi name was computed in two different places and one of them wasn't taking the different naming on Windows into account. * Hadrian was passing "-Irts/include" when building the stage1 compiler leading to the same error as in #18143 (which is using make). stage1's RTS is stage0's one so mustn't do this. * Hadrian: Windows linker doesn't seem to support "-zorigin" so we don't pass it (similarly to Darwin) * Hadrian: hsc2hs in cross-compilation mode uses a trick (taken from autoconf): it defines "static int test_array[SOME_EXPR]" where SOME_EXPR is a constant expression. However GCC reports an error because SOME_EXPR is supposedly not constant. This is fixed by using another method enabled with the `--via-asm` flag of hsc2hs. It has been fixed in `make` build system (5f6fcf7808b16d066ad0fb2068225b3f2e8363f7) but not in Hadrian. * Hadrian: some packages are specifically built only on Windows but they shouldn't be when building a cross-compiler (`touchy` and `ghci-wrapper`). We now correctly detect this case and disable these packages. * Base: we use `iNVALID_HANDLE_VALUE` in a few places. It fixed some hsc2hs issues before we switched to `--via-asm` (see above). I've kept these changes are they make the code nicer. * Base: `base`'s configure tries to detect if it is building for Windows but for some reason the `$host_alias` value is `x86_64-windows` in my case and it wasn't properly detected. * Base: libraries/base/include/winio_structs.h imported "Windows.h" with a leading uppercase. It doesn't work on case-sensitive systems when cross-compiling so we have to use "windows.h". * RTS: rts/win32/ThrIOManager.c was importin "rts\OSThreads.h" but this path isn't valid when cross-compiling. We replaced "\" with "/". * DeriveConstants: this tool derives the constants from the target RTS header files. However these header files define `StgAsyncIOResult` only when `mingw32_HOST_OS` is set hence it seems we have to set it explicitly. Note that deriveConstants is called more than once (why? there is only one target for now so it shouldn't) and in the second case this value is correctly defined (probably coming indirectly from the import of "rts/PosixSource.h"). A better fix would probably be to disable the unneeded first run of deriveconstants. - - - - - cc635da1 by Richard Eisenberg at 2021-11-15T13:20:18-05:00 Link to ghc-proposals repo from README A potential contributor said that they weren't aware of ghc-proposals. This might increase visibility. - - - - - a8e1a756 by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci: Refactor toolchain provision This makes it easier to invoke ci.sh on Darwin by teaching it to manage the nix business. - - - - - 1f0014a8 by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci: Fail if dynamic references are found in a static bindist Previously we called error, which just prints an error, rather than fail, which actually fails. - - - - - 85f2c0ba by Ben Gamari at 2021-11-16T03:12:34-05:00 gitlab-ci/darwin: Move SDK path discovery into toolchain.nix Reduce a bit of duplication and a manual step when running builds manually. - - - - - 3e94b5a7 by John Ericson at 2021-11-16T03:13:10-05:00 Make: Get rid of `BUILD_.*_INCLUDE_DIRS` First, we improve some of the rules around -I include dirs, and CPP opts. Then, we just specify the RTS's include dirs normally (locally per the package and in the package conf), and then everything should work normally. The primops.txt.pp rule needs no extra include dirs at all, as it no longer bakes in a target platfom. Reverts some of the extra stage arguments I added in 05419e55cab272ed39790695f448b311f22669f7, as they are no longer needed. - - - - - 083a7583 by Ben Gamari at 2021-11-17T05:10:27-05:00 Increase type sharing Fixes #20541 by making mkTyConApp do more sharing of types. In particular, replace * BoxedRep Lifted ==> LiftedRep * BoxedRep Unlifted ==> UnliftedRep * TupleRep '[] ==> ZeroBitRep * TYPE ZeroBitRep ==> ZeroBitType In each case, the thing on the right is a type synonym for the thing on the left, declared in ghc-prim:GHC.Types. See Note [Using synonyms to compress types] in GHC.Core.Type. The synonyms for ZeroBitRep and ZeroBitType are new, but absolutely in the same spirit as the other ones. (These synonyms are mainly for internal use, though the programmer can use them too.) I also renamed GHC.Core.Ty.Rep.isVoidTy to isZeroBitTy, to be compatible with the "zero-bit" nomenclature above. See discussion on !6806. There is a tricky wrinkle: see GHC.Core.Types Note [Care using synonyms to compress types] Compiler allocation decreases by up to 0.8%. - - - - - 20a4f251 by Ben Gamari at 2021-11-17T05:11:03-05:00 hadrian: Factor out --extra-*-dirs=... pattern We repeated this idiom quite a few times. Give it a name. - - - - - 4cec6cf2 by Ben Gamari at 2021-11-17T05:11:03-05:00 hadrian: Ensure that term.h is in include search path terminfo now requires term.h but previously neither build system offered any way to add the containing directory to the include search path. Fix this in Hadrian. Also adds libnuma includes to global include search path as it was inexplicably missing earlier. - - - - - 29086749 by Sebastian Graf at 2021-11-17T05:11:38-05:00 Pmc: Don't case split on wildcard matches (#20642) Since 8.10, when formatting a pattern match warning, we'd case split on a wildcard match such as ```hs foo :: [a] -> [a] foo [] = [] foo xs = ys where (_, ys@(_:_)) = splitAt 0 xs -- Pattern match(es) are non-exhaustive -- In a pattern binding: -- Patterns not matched: -- ([], []) -- ((_:_), []) ``` But that's quite verbose and distracts from which part of the pattern was actually the inexhaustive one. We'd prefer a wildcard for the first pair component here, like it used to be in GHC 8.8. On the other hand, case splitting is pretty handy for `-XEmptyCase` to know the different constructors we could've matched on: ```hs f :: Bool -> () f x = case x of {} -- Pattern match(es) are non-exhaustive -- In a pattern binding: -- Patterns not matched: -- False -- True ``` The solution is to communicate that we want a top-level case split to `generateInhabitingPatterns` for `-XEmptyCase`, which is exactly what this patch arranges. Details in `Note [Case split inhabiting patterns]`. Fixes #20642. - - - - - c591ab1f by Sebastian Graf at 2021-11-17T05:11:38-05:00 testsuite: Refactor pmcheck all.T - - - - - 33c0c83d by Andrew Pritchard at 2021-11-17T05:12:17-05:00 Fix Haddock markup on Data.Type.Ord.OrdCond. - - - - - 7bcd91f4 by Andrew Pritchard at 2021-11-17T05:12:17-05:00 Provide in-line kind signatures for Data.Type.Ord.Compare. Haddock doesn't know how to render SAKS, so the only current way to make the documentation show the kind is to write what it should say into the type family declaration. - - - - - 16d86b97 by ARATA Mizuki at 2021-11-17T05:12:56-05:00 bitReverse functions in GHC.Word are since base-4.14.0.0, not 4.12.0.0 They were added in 33173a51c77d9960d5009576ad9b67b646dfda3c, which constitutes GHC 8.10.1 / base-4.14.0.0 - - - - - 7850142c by Morrow at 2021-11-17T11:14:37+00:00 Improve handling of import statements in GHCi (#20473) Currently in GHCi, when given a line of user input we: 1. Attempt to parse and handle it as a statement 2. Otherwise, attempt to parse and handle a single import 3. Otherwise, check if there are imports present (and if so display an error message) 4. Otherwise, attempt to parse a module and only handle the declarations This patch simplifies the process to: Attempt to parse and handle it as a statement Otherwise, attempt to parse a module and handle the imports and declarations This means that multiple imports in a multiline are now accepted, and a multiline containing both imports and declarations is now accepted (as well as when separated by semicolons). - - - - - 09d44b4c by Zubin Duggal at 2021-11-18T01:37:36-05:00 hadrian: add threadedDebug RTS way to devel compilers - - - - - 5fa45db7 by Zubin Duggal at 2021-11-18T01:37:36-05:00 testsuite: disable some tests when we don't have dynamic libraries - - - - - f8c1c549 by Matthew Pickering at 2021-11-18T01:38:11-05:00 Revert "base: Use one-shot kqueue on macOS" This reverts commit 41117d71bb58e001f6a2b6a11c9314d5b70b9182 - - - - - f55ae180 by Simon Peyton Jones at 2021-11-18T14:44:45-05:00 Add one line of comments (c.f. !5706) Ticket #19815 suggested changing coToMCo to use isReflexiveCo rather than isReflCo. But perf results weren't encouraging. This patch just adds a comment to point to the data, such as it is. - - - - - 12d023d1 by Vladislav Zavialov at 2021-11-18T14:45:20-05:00 testsuite: check for FlexibleContexts in T17563 The purpose of testsuite/tests/typecheck/should_fail/T17563.hs is to make sure we do validity checking on quantified constraints. In particular, see the following functions in GHC.Tc.Validity: * check_quant_pred * check_pred_help * check_class_pred The original bug report used a~b constraints as an example of a constraint that requires validity checking. But with GHC Proposal #371, equality constraints no longer require GADTs or TypeFamilies; instead, they require TypeOperators, which are checked earlier in the pipeline, in the renamer. Rather than simply remove this test, we change the example to use another extension: FlexibleContexts. Since we decide whether a constraint requires this extension in check_class_pred, the regression test continues to exercise the relevant code path. - - - - - 78d4bca0 by Ben Gamari at 2021-11-18T22:27:20-05:00 ghc-cabal, make: Add support for building C++ object code Co-Authored By: Matthew Pickering <matthew at well-typed.com> - - - - - a8b4961b by Ben Gamari at 2021-11-18T22:27:20-05:00 Bump Cabal submodule - - - - - 59e8a900 by Ben Gamari at 2021-11-18T22:27:20-05:00 Bump text and parsec submodules Accommodates text-2.0. Metric Decrease: T15578 - - - - - 7f7d7888 by Ben Gamari at 2021-11-18T22:27:20-05:00 ghc-cabal: Use bootstrap compiler's text package This avoids the need to build `text` without Cabal, in turn avoiding the need to reproduce the workaround for #20010 contained therein. - - - - - 048f8d96 by Ben Gamari at 2021-11-18T22:27:20-05:00 gitlab-ci: Bump MACOSX_DEPLOYMENT_TARGET It appears that Darwin's toolchain includes system headers in the dependency makefiles it generates with `-M` with older `MACOSX_DEPLOYMENT_TARGETS`. To avoid this we have bumped the deployment target for x86-64/Darwin to 10.10. - - - - - 0acbbd20 by Ben Gamari at 2021-11-18T22:27:20-05:00 testsuite: Use libc++ rather than libstdc++ in objcpp-hi It appears that libstdc++ is no longer available in recent XCode distributions. Closes #16083. - - - - - aed98dda by John Ericson at 2021-11-18T22:27:55-05:00 Hadrian: bring up to date with latest make improvements Headers should be associated with the RTS, and subject to less hacks. The most subtle issue was that the package-grained dependencies on generated files were being `need`ed before calculating Haskell deps, but not before calculating C/C++ deps. - - - - - aabff109 by Ben Gamari at 2021-11-20T05:34:27-05:00 Bump deepseq submodule to 1.4.7.0-pre Addresses #20653. - - - - - 3d6b78db by Matthew Pickering at 2021-11-20T05:35:02-05:00 Remove unused module import syntax from .bkp mode .bkp mode had this unused feature where you could write module A and it would go looking for A.hs on the file system and use that rather than provide the definition inline. This isn't use anywhere in the testsuite and the code to find the module A looks dubious. Therefore to reduce .bkp complexity I propose to remove it. Fixes #20701 - - - - - bdeea37e by Sylvain Henry at 2021-11-20T05:35:42-05:00 More support for optional home-unit This is a preliminary refactoring for #14335 (supporting plugins in cross-compilers). In many places the home-unit must be optional because there won't be one available in the plugin environment (we won't be compiling anything in this environment). Hence we replace "HomeUnit" with "Maybe HomeUnit" in a few places and we avoid the use of "hsc_home_unit" (which is partial) in some few others. - - - - - 29e03071 by Ben Gamari at 2021-11-20T05:36:18-05:00 rts: Ensure that markCAFs marks object code Previously `markCAFs` would only evacuate CAFs' indirectees. This would allow reachable object code to be unloaded by the linker as `evacuate` may never be called on the CAF itself, despite it being reachable via the `{dyn,revertible}_caf_list`s. To fix this we teach `markCAFs` to explicit call `markObjectCode`, ensuring that the linker is aware of objects reachable via the CAF lists. Fixes #20649. - - - - - b2933ea9 by Ben Gamari at 2021-11-20T05:36:54-05:00 gitlab-ci: Set HOME to plausible but still non-existent location We have been seeing numerous CI failures on aarch64/Darwin of the form: CI_COMMIT_BRANCH: CI_PROJECT_PATH: ghc/ghc error: creating directory '/nonexistent': Read-only file system Clearly *something* is attempting to create `$HOME`. A bit of sleuthing by @int-e found that the culprit is likely `nix`, although it's not clear why. For now we avoid the issue by setting `HOME` to a fresh directory in the working tree. - - - - - bc7e9f03 by Zubin Duggal at 2021-11-20T17:39:25+00:00 Use 'NonEmpty' for the fields in an 'HsProjection' (#20389) T12545 is very inconsistently affected by this change for some reason. There is a decrease in allocations on most configurations, but an increase on validate-x86_64-linux-deb9-unreg-hadrian. Accepting it as it seems unrelated to this patch. Metric Decrease: T12545 Metric Increase: T12545 - - - - - 742d8b60 by sheaf at 2021-11-20T18:13:23-05:00 Include "not more specific" info in overlap msg When instances overlap, we now include additional information about why we weren't able to select an instance: perhaps one instance overlapped another but was not strictly more specific, so we aren't able to directly choose it. Fixes #20542 - - - - - f748988b by Simon Peyton Jones at 2021-11-22T11:53:02-05:00 Better wrapper activation calculation As #20709 showed, GHC could prioritise a wrapper over a SPEC rule, which is potentially very bad. This patch fixes that problem. The fix is is described in Note [Wrapper activation], especially item 4, 4a, and Conclusion. For now, it has a temporary hack (replicating what was there before to make sure that wrappers inline no earlier than phase 2. But it should be temporary; see #19001. - - - - - f0bac29b by Simon Peyton Jones at 2021-11-22T11:53:02-05:00 Make INLINE/NOINLINE pragmas a bgi less constraining We can inline a bit earlier than the previous pragmas said. I think they dated from an era in which the InitialPhase did no inlining. I don't think this patch will have much effect, but it's a bit cleaner. - - - - - 68a3665a by Sylvain Henry at 2021-11-22T11:53:47-05:00 Hadrian: bump stackage LTS to 18.18 (GHC 8.10.7) - - - - - 680ef2c8 by Andreas Klebinger at 2021-11-23T01:07:29-05:00 CmmSink: Be more aggressive in removing no-op assignments. No-op assignments like R1 = R1 are not only wasteful. They can also inhibit other optimizations like inlining assignments that read from R1. We now check for assignments being a no-op before and after we simplify the RHS in Cmm sink which should eliminate most of these no-ops. - - - - - 1ed2aa90 by Andreas Klebinger at 2021-11-23T01:07:29-05:00 Don't include types in test output - - - - - 3ab3631f by Krzysztof Gogolewski at 2021-11-23T01:08:05-05:00 Add a warning for GADT match + NoMonoLocalBinds (#20485) Previously, it was an error to pattern match on a GADT without GADTs or TypeFamilies. This is now allowed. Instead, we check the flag MonoLocalBinds; if it is not enabled, we issue a warning, controlled by -Wgadt-mono-local-binds. Also fixes #20485: pattern synonyms are now checked too. - - - - - 9dcb2ad1 by Ben Gamari at 2021-11-23T16:09:39+00:00 gitlab-ci: Bump DOCKER_REV - - - - - 16690374 by nineonine at 2021-11-23T22:32:51-08:00 Combine STG free variable traversals (#17978) Previously we would traverse the STG AST twice looking for free variables. * Once in `annTopBindingsDeps` which considers top level and imported ids free. Its output is used to put bindings in dependency order. The pass happens in STG pipeline. * Once in `annTopBindingsFreeVars` which only considers non-top level ids free. Its output is used by the code generator to compute offsets into closures. This happens in Cmm (CodeGen) pipeline. Now these two traversal operations are merged into one - `FVs.depSortWithAnnotStgPgm`. The pass happens right at the end of STG pipeline. Some type signatures had to be updated due to slight shifts of StgPass boundaries (for example, top-level CodeGen handler now directly works with CodeGen flavoured Stg AST instead of Vanilla). Due to changed order of bindings, a few debugger type reconstruction bugs have resurfaced again (see tests break018, break021) - work item #18004 tracks this investigation. authors: simonpj, nineonine - - - - - 91c0a657 by Matthew Pickering at 2021-11-25T01:03:17-05:00 Correct retypechecking in --make mode Note [Hydrating Modules] ~~~~~~~~~~~~~~~~~~~~~~~~ What is hydrating a module? * There are two versions of a module, the ModIface is the on-disk version and the ModDetails is a fleshed-out in-memory version. * We can **hydrate** a ModIface in order to obtain a ModDetails. Hydration happens in three different places * When an interface file is initially loaded from disk, it has to be hydrated. * When a module is finished compiling, we hydrate the ModIface in order to generate the version of ModDetails which exists in memory (see Note) * When dealing with boot files and module loops (see Note [Rehydrating Modules]) Note [Rehydrating Modules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a module has a boot file then it is critical to rehydrate the modules on the path between the two. Suppose we have ("R" for "recursive"): ``` R.hs-boot: module R where data T g :: T -> T A.hs: module A( f, T, g ) where import {-# SOURCE #-} R data S = MkS T f :: T -> S = ...g... R.hs: module R where data T = T1 | T2 S g = ...f... ``` After compiling A.hs we'll have a TypeEnv in which the Id for `f` has a type type uses the AbstractTyCon T; and a TyCon for `S` that also mentions that same AbstractTyCon. (Abstract because it came from R.hs-boot; we know nothing about it.) When compiling R.hs, we build a TyCon for `T`. But that TyCon mentions `S`, and it currently has an AbstractTyCon for `T` inside it. But we want to build a fully cyclic structure, in which `S` refers to `T` and `T` refers to `S`. Solution: **rehydration**. *Before compiling `R.hs`*, rehydrate all the ModIfaces below it that depend on R.hs-boot. To rehydrate a ModIface, call `typecheckIface` to convert it to a ModDetails. It's just a de-serialisation step, no type inference, just lookups. Now `S` will be bound to a thunk that, when forced, will "see" the final binding for `T`; see [Tying the knot](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/tying-the-knot). But note that this must be done *before* compiling R.hs. When compiling R.hs, the knot-tying stuff above will ensure that `f`'s unfolding mentions the `LocalId` for `g`. But when we finish R, we carefully ensure that all those `LocalIds` are turned into completed `GlobalIds`, replete with unfoldings etc. Alas, that will not apply to the occurrences of `g` in `f`'s unfolding. And if we leave matters like that, they will stay that way, and *all* subsequent modules that import A will see a crippled unfolding for `f`. Solution: rehydrate both R and A's ModIface together, right after completing R.hs. We only need rehydrate modules that are * Below R.hs * Above R.hs-boot There might be many unrelated modules (in the home package) that don't need to be rehydrated. This dark corner is the subject of #14092. Suppose we add to our example ``` X.hs module X where import A data XT = MkX T fx = ...g... ``` If in `--make` we compile R.hs-boot, then A.hs, then X.hs, we'll get a `ModDetails` for `X` that has an AbstractTyCon for `T` in the the argument type of `MkX`. So: * Either we should delay compiling X until after R has beeen compiled. * Or we should rehydrate X after compiling R -- because it transitively depends on R.hs-boot. Ticket #20200 has exposed some issues to do with the knot-tying logic in GHC.Make, in `--make` mode. this particular issue starts [here](https://gitlab.haskell.org/ghc/ghc/-/issues/20200#note_385758). The wiki page [Tying the knot](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/tying-the-knot) is helpful. Also closely related are * #14092 * #14103 Fixes tickets #20200 #20561 - - - - - f0c5d8d3 by Matthew Pickering at 2021-11-25T01:03:17-05:00 Make T14075 more robust - - - - - 6907e9fa by Matthew Pickering at 2021-11-25T01:03:17-05:00 Revert "Convert lookupIdSubst panic back to a warning (#20200)" This reverts commit df1d808f26544cbb77d85773d672137c65fd3cc7. - - - - - baa8ffee by Greg Steuck at 2021-11-25T01:03:54-05:00 Use getExecutablePath in getBaseDir on OpenBSD While OpenBSD doesn't have a general mechanism for determining the path of the executing program image, it is reasonable to rely on argv[0] which happens as a fallback in getExecutablePath. With this change on top of T18173 we can get a bit close to fixing #18173. - - - - - e3c59191 by Christiaan Baaij at 2021-11-25T01:04:32-05:00 Ensure new Ct/evidence invariant The `ctev_pred` field of a `CtEvidence` is a just a cache for the type of the evidence. More precisely: * For Givens, `ctev_pred` = `varType ctev_evar` * For Wanteds, `ctev_pred` = `evDestType ctev_dest` This new invariant is needed because evidence can become part of a type, via `Castty ty kco`. - - - - - 3639ad8f by Christiaan Baaij at 2021-11-25T01:04:32-05:00 Compare types of recursive let-bindings in alpha-equivalence This commit fixes #20641 by checking the types of recursive let-bindings when performing alpha-equality. The `Eq (DeBruijn CoreExpr)` instance now also compares `BreakPoint`s similarly to `GHC.Core.Utils.eqTickish`, taking bound variables into account. In addition, the `Eq (DeBruijn Type)` instance now correctly compares the kinds of the types when one of them contains a Cast: the instance is modeled after `nonDetCmpTypeX`. - - - - - 7c65687e by CarrieMY at 2021-11-25T01:05:11-05:00 Enable UnboxedTuples in `genInst`, Fixes #20524 - - - - - e33412d0 by Krzysztof Gogolewski at 2021-11-25T01:05:46-05:00 Misc cleanup * Remove `getTag_RDR` (unused), `tidyKind` and `tidyOpenKind` (already available as `tidyType` and `tidyOpenType`) * Remove Note [Explicit Case Statement for Specificity]. Since 0a709dd9876e40 we require GHC 8.10 for bootstrapping. * Change the warning to `cmpAltCon` to a panic. This shouldn't happen. If it ever does, the code was wrong anyway: it shouldn't always return `LT`, but rather `LT` in one case and `GT` in the other case. * Rename `verifyLinearConstructors` to `verifyLinearFields` * Fix `Note [Local record selectors]` which was not referenced * Remove vestiges of `type +v` * Minor fixes to StaticPointers documentation, part of #15603 - - - - - bb71f7f1 by Greg Steuck at 2021-11-25T01:06:25-05:00 Reorder `sed` arguments to work with BSD sed The order was swapped in 490e8c750ea23ce8e2b7309e0d514b7d27f231bb causing the build on OpenBSD to fail with: `sed: 1: "mk/config.h": invalid command code m` - - - - - c18a51f0 by John Ericson at 2021-11-25T01:06:25-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - d530c46c by sheaf at 2021-11-25T01:07:04-05:00 Add Data.Bits changes to base 4.16 changelog Several additions since 4.15 had not been recorded in the changelog: - newtypes And, Ior, Xor and Iff, - oneBits - symbolic synonyms `.^.`, `.>>.`, `!>>.`, `.<<.` and `!<<.`. Fixes #20608. - - - - - 4d34bf15 by Matthew Pickering at 2021-11-25T01:07:40-05:00 Don't use implicit lifting when deriving Lift It isn't much more complicated to be more precise when deriving Lift so we now generate ``` data Foo = Foo Int Bool instance Lift Foo where lift (Foo a b) = [| Foo $(lift a) $(lift b) |] liftTyped (Foo a b) = [|| Foo $$(lift a) $$(lift b) |] ``` This fixes #20688 which complained about using implicit lifting in the derived code. - - - - - 8961d632 by Greg Steuck at 2021-11-25T01:08:18-05:00 Disable warnings for unused goto labels Clang on OpenBSD aborts compilation with this diagnostics: ``` % "inplace/bin/ghc-stage1" -optc-Wno-error=unused-label -optc-Wall -optc-Werror -optc-Wall -optc-Wextra -optc-Wstrict-prototypes -optc-Wmissing-prototypes -optc-Wmissing-declarations -optc-Winline -optc-Wpointer-arith -optc-Wmissing-noreturn -optc-Wnested-externs -optc-Wredundant-decls -optc-Wno-aggregate-return -optc-fno-strict-aliasing -optc-fno-common -optc-Irts/dist-install/build/./autogen -optc-Irts/include/../dist-install/build/include -optc-Irts/include/. -optc-Irts/. -optc-DCOMPILING_RTS -optc-DFS_NAMESPACE=rts -optc-Wno-unknown-pragmas -optc-O2 -optc-fomit-frame-pointer -optc-g -optc-DRtsWay=\"rts_v\" -static -O0 -H64m -Wall -fllvm-fill-undef-with-garbage -Werror -this-unit-id rts -dcmm-lint -package-env - -i -irts -irts/dist-install/build -Irts/dist-install/build -irts/dist-install/build/./autogen -Irts/dist-install/build/./autogen -Irts/include/../dist-install/build/include -Irts/include/. -Irts/. -optP-DCOMPILING_RTS -optP-DFS_NAMESPACE=rts -O2 -Wcpp-undef -Wnoncanonical-monad-instances -c rts/linker/Elf.c -o rts/dist-install/build/linker/Elf.o rts/linker/Elf.c:2169:1: error: error: unused label 'dl_iterate_phdr_fail' [-Werror,-Wunused-label] | 2169 | dl_iterate_phdr_fail: | ^ dl_iterate_phdr_fail: ^~~~~~~~~~~~~~~~~~~~~ rts/linker/Elf.c:2172:1: error: error: unused label 'dlinfo_fail' [-Werror,-Wunused-label] | 2172 | dlinfo_fail: | ^ dlinfo_fail: ^~~~~~~~~~~~ 2 errors generated. ``` - - - - - 5428b8c6 by Zubin Duggal at 2021-11-25T01:08:54-05:00 testsuite: debounce title updates - - - - - 96b3899e by Ben Gamari at 2021-11-25T01:09:29-05:00 gitlab-ci: Add release jobs for Darwin targets As noted in #20707, the validate jobs which we previously used lacked profiling support. Also clean up some variable definitions. Fixes #20707. - - - - - 52cdc2fe by Pepe Iborra at 2021-11-25T05:00:43-05:00 Monoid instance for InstalledModuleEnv - - - - - 47f36440 by Pepe Iborra at 2021-11-25T05:00:43-05:00 Drop instance Semigroup ModuleEnv There is more than one possible Semigroup and it is not needed since plusModuleEnv can be used directly - - - - - b742475a by Pepe Iborra at 2021-11-25T05:00:43-05:00 drop instance Semigroup InstalledModuleEnv Instead, introduce plusInstalledModuleEnv - - - - - b24e8d91 by Roland Senn at 2021-11-25T05:01:21-05:00 GHCi Debugger - Improve RTTI When processing the heap, use also `APClosures` to create additional type constraints. This adds more equations and therefore improves the unification process to infer the correct type of values at breakpoints. (Fix the `incr` part of #19559) - - - - - cf5279ed by Gergő Érdi at 2021-11-25T05:01:59-05:00 Use `simplify` in non-optimizing build pipeline (#20500) - - - - - c9cead1f by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add specific optimization flag for fast PAP calls (#6084, #20500) - - - - - be0a9470 by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add specific optimization flag for Cmm control flow analysis (#20500) - - - - - b52a9a3f by Gergő Érdi at 2021-11-25T05:01:59-05:00 Add `llvmOptLevel` to `DynFlags` (#20500) - - - - - f27a63fe by sheaf at 2021-11-25T05:02:39-05:00 Allow boring class declarations in hs-boot files There are two different ways of declaring a class in an hs-boot file: - a full declaration, where everything is written as it is in the .hs file, - an abstract declaration, where class methods and superclasses are left out. However, a declaration with no methods and a trivial superclass, such as: class () => C a was erroneously considered to be an abstract declaration, because the superclass is trivial. This is remedied by a one line fix in GHC.Tc.TyCl.tcClassDecl1. This patch also further clarifies the documentation around class declarations in hs-boot files. Fixes #20661, #20588. - - - - - cafb1f99 by Ben Gamari at 2021-11-25T05:03:15-05:00 compiler: Mark GHC.Prelude as Haddock no-home This significantly improves Haddock documentation generated by nix. - - - - - bd92c9b2 by Sebastian Graf at 2021-11-25T05:03:51-05:00 hadrian: Add `collect_stats` flavour transformer This is useful for later consumption with https://gitlab.haskell.org/bgamari/ghc-utils/-/blob/master/ghc_timings.py - - - - - 774fc4d6 by Ilias Tsitsimpis at 2021-11-25T08:34:54-05:00 Link against libatomic for 64-bit atomic operations Some platforms (e.g., armel) require linking against libatomic for 64-bit atomic operations. Fixes #20549 - - - - - 20101d9c by Greg Steuck at 2021-11-25T08:35:31-05:00 Permit multiple values in config_args for validate The whitespace expansion should be permitted to pass multiple arguments to configure. - - - - - e2c48b98 by Greg Steuck at 2021-11-25T08:36:09-05:00 Kill a use of %n format specifier This format has been used as a security exploit vector for decades now. Some operating systems (OpenBSD, Android, MSVC). It is targeted for removal in C2X standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2834.htm This requires extending the debug message function to return the number of bytes written (like printf(3)), to permit %n format specifier in one in one invocation of statsPrintf() in report_summary(). Implemented by Matthias Kilian (kili<AT>outback.escape.de) - - - - - ff0c45f3 by Andrew Lelechenko at 2021-11-26T16:01:09-05:00 Rename Data.ByteArray to Data.Array.ByteArray + add Trustworthy - - - - - 9907d540 by Andrew Lelechenko at 2021-11-26T16:01:09-05:00 Rename Data.Array.ByteArray -> Data.Array.Byte - - - - - 0c8e1b4d by Kai Prott at 2021-11-26T16:01:47-05:00 Improve error message for mis-typed plugins #20671 Previously, when a plugin could not be loaded because it was incorrectly typed, the error message only printed the expected but not the actual type. This commit augments the error message such that both types are printed and the corresponding module is printed as well. - - - - - 51bcb986 by Kai Prott at 2021-11-26T16:01:47-05:00 Remove duplicate import - - - - - 1830eea7 by Kai Prott at 2021-11-26T16:01:47-05:00 Simplify printQualification - - - - - 69e62032 by Kai Prott at 2021-11-26T16:01:47-05:00 Fix plugin type to GHC.Plugins.Plugin - - - - - 0a6776a3 by Kai Prott at 2021-11-26T16:01:47-05:00 Adapt plugin test case - - - - - 7e18b304 by Kai Prott at 2021-11-26T16:01:47-05:00 Reflect type change in the haddock comment - - - - - 02372be1 by Matthew Pickering at 2021-11-26T16:02:23-05:00 Allow keywords which can be used as variables to be used with OverloadedDotSyntax There are quite a few keywords which are allowed to be used as variables. Such as "as", "dependency" etc. These weren't accepted by OverloadedDotSyntax. The fix is pretty simple, use the varid production rather than raw VARID. Fixes #20723 - - - - - 13ef345c by John Ericson at 2021-11-27T19:41:11+00:00 Factor our `FP_CAPITALIZE_YES_NO` This deduplicates converting from yes/no to YES/NO in the configure scripts while also making it safer. - - - - - 88481c94 by John Ericson at 2021-11-27T19:46:16+00:00 Fix top-level configure script so --disable-foo works - - - - - f67060c6 by John Ericson at 2021-11-27T19:47:09+00:00 Make ambient MinGW support a proper settings Get rid of `USE_INPLACE_MINGW_TOOLCHAIN` and use a settings file entry instead. The CPP setting was originally introduced in f065b6b012. - - - - - 1dc0d7af by Ben Gamari at 2021-11-29T11:02:43-05:00 linker: Introduce linker_verbose debug output This splits the -Dl RTS debug output into two distinct flags: * `+RTS -Dl` shows errors and debug output which scales with at most O(# objects) * `+RTS -DL` shows debug output which scales with O(# symbols)t - - - - - 7ea665bf by Krzysztof Gogolewski at 2021-11-29T11:03:19-05:00 TTG: replace Void/NoExtCon with DataConCantHappen There were two ways to indicate that a TTG constructor is unused in a phase: `NoExtCon` and `Void`. This unifies the code, and uses the name 'DataConCantHappen', following the discussion at MR 7041. Updates haddock submodule - - - - - 14e9cab6 by Sylvain Henry at 2021-11-29T11:04:03-05:00 Use Monoid in hptSomeThingsBelowUs It seems to have a moderate but good impact on perf tests in CI. In particular: MultiLayerModules(normal) ghc/alloc 3125771138.7 3065532240.0 -1.9% So it's likely that huge projects will benefit from this. - - - - - 22bbf449 by Anton-Latukha at 2021-11-29T20:03:52+00:00 docs/users_guide/bugs.rst: Rewording It is either "slightly" || "significantly". If it is "bogus" - then no quotes around "optimization" & overall using word "bogus" or use quotes in that way in documentation is... Instead, something like "hack" or "heuristic" can be used there. - - - - - 9345bfed by Mitchell Rosen at 2021-11-30T01:32:22-05:00 Fix caluclation of nonmoving GC elapsed time Fixes #20751 - - - - - c7613493 by PHO at 2021-12-01T03:07:32-05:00 rts/ProfHeap.c: Use setlocale() on platforms where uselocale() is not available Not all platforms have per-thread locales. NetBSD doesn't have uselocale() in particular. Using setlocale() is of course not a safe thing to do, but it would be better than no GHC at all. - - - - - 4acfa0db by Ben Gamari at 2021-12-01T03:08:07-05:00 rts: Refactor SRT representation selection The goal here is to make the SRT selection logic a bit clearer and allow configurations which we currently don't support (e.g. using a full word in the info table even when TNTC is used). - - - - - 87bd9a67 by Ben Gamari at 2021-12-01T03:08:07-05:00 gitlab-ci: Introduce no_tntc job A manual job for testing the non-tables-next-to-code configuration. - - - - - 7acb945d by Carrie Xu at 2021-12-01T03:08:46-05:00 Dump non-module specific info to file #20316 - Change the dumpPrefix to FilePath, and default to non-module - Add dot to seperate dump-file-prefix and suffix - Modify user guide to introduce how dump files are named - This commit does not affect Ghci dump file naming. See also #17500 - - - - - 7bdca2ba by Ben Gamari at 2021-12-01T03:09:21-05:00 rts/RtsSymbols: Provide a proper prototype for environ Previously we relied on Sym_NeedsProto, but this gave the symbol a type which conflicts with the definition that may be provided by unistd.h. Fixes #20577. - - - - - 91d1a773 by Ben Gamari at 2021-12-01T03:09:21-05:00 hadrian: Don't pass empty paths via -I Previously we could in some cases add empty paths to `cc`'s include file search path. See #20578. - - - - - d8d57729 by Ben Gamari at 2021-12-01T03:09:21-05:00 ghc-cabal: Manually specify -XHaskell2010 Otherwise we end up with issues like #19631 when bootstrapping using GHC 9.2 and above. Fixes #19631. - - - - - 1c0c140a by Ben Gamari at 2021-12-01T03:09:21-05:00 ghc-compact: Update cabal file Improve documentation, bump bounds and cabal-version. - - - - - 322b6b45 by Ben Gamari at 2021-12-01T03:09:21-05:00 hadrian: Document fully_static flavour transformer - - - - - 4c434c9e by Ben Gamari at 2021-12-01T03:09:21-05:00 user-guide: Fix :since: of -XCApiFFI Closes #20504. - - - - - 0833ad55 by Matthew Pickering at 2021-12-01T03:09:58-05:00 Add failing test for #20674 - - - - - c2cb5e9a by Ben Gamari at 2021-12-01T03:10:34-05:00 testsuite: Print geometric mean of stat metrics As suggested in #20733. - - - - - 59b27945 by Ben Gamari at 2021-12-01T03:11:09-05:00 users-guide: Describe requirements of DWARF unwinding As requested in #20702 - - - - - c2f6cbef by Matthew Pickering at 2021-12-01T03:11:45-05:00 Fix several quoting issues in testsuite This fixes the ./validate script on my machine. I also took the step to add some linters which would catch problems like these in future. Fixes #20506 - - - - - bffd4074 by John Ericson at 2021-12-01T03:12:21-05:00 rts.cabal.in: Move `extra-source-files` so it is valid - - - - - 86c14db5 by John Ericson at 2021-12-01T03:12:21-05:00 Switch RTS cabal file / package conf to use Rts.h not Stg.h When we give cabal a configure script, it seems to begin checking whether or not Stg.h is valid, and then gets tripped up on all the register stuff which evidentally requires obscure command line flags to go. We can side-step this by making the test header Rts.h instead, which is more normal. I was a bit sketched out making this change, as I don't know why the Cabal library would suddenly beging checking the header. But I did confirm even without my RTS configure script the header doesn't compile stand-alone, and also the Stg.h is a probably-arbitrary choice since it dates all the way back to 2002 in 2cc5b907318f97e19b28b2ad8ed9ff8c1f401dcc. - - - - - defd8d54 by John Ericson at 2021-12-01T03:12:21-05:00 Avoid raw `echo` in `FPTOOLS_SET_PLATFORM_VARS` This ensures quiet configuring works. - - - - - b53f1227 by John Ericson at 2021-12-01T03:12:21-05:00 Factor our `$dir_$distdir_PKGDATA` make variable This makes a few things cleaner. - - - - - f124f2a0 by Ben Gamari at 2021-12-01T03:12:56-05:00 rts: Annotate benign race in pthread ticker's exit test Previously TSAN would report spurious data races due to the unsynchronized access of `exited`. I would have thought that using a relaxed load on `exited` would be enough to convince TSAN that the race was intentional, but apparently not. Closes #20690. - - - - - d3c7f9be by Viktor Dukhovni at 2021-12-01T03:13:34-05:00 Use POSIX shell syntax to redirect stdout/err FreeBSD (and likely NetBSD) /bin/sh does not support '>& word' to redirect stdout + stderr. (Also the preferred syntax in bash would be '&> word' to avoid surprises when `word` is "-" or a number). Resolves: #20760 - - - - - 1724ac37 by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/x86: Don't encode large shift offsets Handle the case of a shift larger than the width of the shifted value. This is necessary since x86 applies a mask of 0x1f to the shift amount, meaning that, e.g., `shr 47, $eax` will actually shift by 47 & 0x1f == 15. See #20626. (cherry picked from commit 31370f1afe1e2f071b3569fb5ed4a115096127ca) - - - - - 5b950a7f by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm: narrow when folding signed quotients Previously the constant-folding behavior for MO_S_Quot and MO_S_Rem failed to narrow its arguments, meaning that a program like: %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) would be miscompiled. Specifically, this program should reduce as %lobits8(0x00e1::bits16) == -31 %quot(%lobits8(0x00e1::bits16), 3::bits8) == -10 %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) == 246 However, with this bug the `%lobits8(0x00e1::bits16)` would instead be treated as `+31`, resulting in the incorrect result of `75`. (cherry picked from commit 94e197e3dbb9a48991eb90a03b51ea13d39ba4cc) - - - - - 78b78ac4 by Ben Gamari at 2021-12-02T18:13:30-05:00 ncg/aarch64: Don't sign extend loads Previously we would emit the sign-extending LDS[HB] instructions for sub-word loads. However, this is wrong, as noted in #20638. - - - - - 35bbc251 by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm: Disallow shifts larger than shiftee Previously primops.txt.pp stipulated that the word-size shift primops were only defined for shift offsets in [0, word_size). However, there was no further guidance for the definition of Cmm's sub-word size shift MachOps. Here we fix this by explicitly disallowing (checked in many cases by CmmLint) shift operations where the shift offset is larger than the shiftee. This is consistent with LLVM's shift operations, avoiding the miscompilation noted in #20637. - - - - - 2f6565cf by Ben Gamari at 2021-12-02T18:13:30-05:00 testsuite: Add testcases for various machop issues There were found by the test-primops testsuite. - - - - - 7094f4fa by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/aarch64: Don't rely on register width to determine amode We might be loading, e.g., a 16- or 8-bit value, in which case the register width is not reflective of the loaded element size. - - - - - 9c65197e by Ben Gamari at 2021-12-02T18:13:30-05:00 cmm/opt: Fold away shifts larger than shiftee width This is necessary for lint-correctness since we no longer allow such shifts in Cmm. - - - - - adc7f108 by Ben Gamari at 2021-12-02T18:13:30-05:00 nativeGen/aarch64: Fix handling of subword values Here we rework the handling of sub-word operations in the AArch64 backend, fixing a number of bugs and inconsistencies. In short, we now impose the invariant that all subword values are represented in registers in zero-extended form. Signed arithmetic operations are then responsible for sign-extending as necessary. Possible future work: * Use `CMP`s extended register form to avoid burning an instruction in sign-extending the second operand. * Track sign-extension state of registers to elide redundant sign extensions in blocks with frequent sub-word signed arithmetic. - - - - - e19e9e71 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Fix width of shift operations Under C's implicit widening rules, the result of an operation like (a >> b) where a::Word8 and b::Word will have type Word, yet we want Word. - - - - - ebaf7333 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Zero-extend sub-word size results As noted in Note [Zero-extending sub-word signed results] we must explicitly zero-extend the results of sub-word-sized signed operations. - - - - - 0aeaa8f3 by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Always cast arguments as unsigned As noted in Note [When in doubt, cast arguments as unsigned], we must ensure that arguments have the correct signedness since some operations (e.g. `%`) have different semantics depending upon signedness. - - - - - e98dad1b by Ben Gamari at 2021-12-02T18:13:31-05:00 CmmToC: Cast possibly-signed results as unsigned C11 rule 6.3.1.1 dictates that all small integers used in expressions be implicitly converted to `signed int`. However, Cmm semantics require that the width of the operands be preserved with zero-extension semantics. For this reason we must recast sub-word arithmetic results as unsigned. - - - - - 44c08863 by Ben Gamari at 2021-12-02T18:13:31-05:00 testsuite: Specify expected word-size of machop tests These generally expect a particular word size. - - - - - fab2579e by Ben Gamari at 2021-12-02T18:14:06-05:00 hadrian: Don't rely on realpath in bindist Makefile As noted in #19963, `realpath` is not specified by POSIX and therefore cannot be assumed to be available. Here we provide a POSIX shell implementation of `realpath`, due to Julian Ospald and others. Closes #19963. - - - - - 99eb54bd by Kamil Dworakowski at 2021-12-02T21:45:10-05:00 Make openFile more tolerant of async excs (#18832) - - - - - 0e274c39 by nineonine at 2021-12-02T21:45:49-05:00 Require all dirty_MUT_VAR callers to do explicit stg_MUT_VAR_CLEAN_info comparison (#20088) - - - - - 81082cf4 by Matthew Pickering at 2021-12-03T10:12:04-05:00 Revert "Data.List specialization to []" This reverts commit bddecda1a4c96da21e3f5211743ce5e4c78793a2. This implements the first step in the plan formulated in #20025 to improve the communication and migration strategy for the proposed changes to Data.List. Requires changing the haddock submodule to update the test output. - - - - - a9e035a4 by sheaf at 2021-12-03T10:12:42-05:00 Test-suite: fix geometric mean of empty list The geometric mean computation panicked when it was given an empty list, which happens when there are no baselines. Instead, we should simply return 1. - - - - - d72720f9 by Matthew Pickering at 2021-12-06T16:27:35+00:00 Add section to the user guide about OS memory usage - - - - - 0fe45d43 by Viktor Dukhovni at 2021-12-07T06:27:12-05:00 List-monomorphic `foldr'` While a *strict* (i.e. constant space) right-fold on lists is not possible, the default `foldr'` is optimised for structures like `Seq`, that support efficient access to the right-most elements. The original default implementation seems to have a better constant factor for lists, so we add a monomorphic implementation in GHC.List. Should this be re-exported from `Data.List`? That would be a user-visible change if both `Data.Foldable` and `Data.List` are imported unqualified... - - - - - 7d2283b9 by Ben Gamari at 2021-12-07T06:27:47-05:00 compiler: Eliminate accidental loop in GHC.SysTools.BaseDir As noted in #20757, `GHC.SysTools.BaseDir.findToolDir` previously contained an loop, which would be triggered in the case that the search failed. Closes #20757. - - - - - 8044e232 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 More specific documentation of foldr' caveats - - - - - d932e2d6 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 Use italic big-O notation in Data.Foldable - - - - - 57c9c0a2 by Viktor Dukhovni at 2021-12-07T06:28:23-05:00 Fix user-guide typo - - - - - 324772bb by Ben Gamari at 2021-12-07T06:28:59-05:00 rts/Linker: Ensure that mmap_32bit_base is updated after mapping The amount of duplicated code in `mmapForLinker` hid the fact that some codepaths would fail to update `mmap_32bit_base` (specifically, on platforms like OpenBSD where `MAP_32BIT` is not supported). Refactor the function to make the implementation more obviously correct. Closes #20734. - - - - - 5dbdf878 by Ben Gamari at 2021-12-07T06:28:59-05:00 rts: +RTS -DL should imply +RTS -Dl Otherwise the user may be surprised by the missing context provided by the latter. - - - - - 7eb56064 by sheaf at 2021-12-07T06:29:38-05:00 More permissive parsing of higher-rank type IPs The parser now accepts implicit parameters with higher-rank types, such as `foo :: (?ip :: forall a. a -> a) => ...` Before this patch, we instead insisted on parentheses like so: `foo :: (?ip :: (forall a. a -> a)) => ...` The rest of the logic surrounding implicit parameters is unchanged; in particular, even with ImpredicativeTypes, this idiom is not likely to be very useful. Fixes #20654 - - - - - 427f9c12 by sheaf at 2021-12-07T13:32:55-05:00 Re-export GHC.Types from GHC.Exts Several times in the past, it has happened that things from GHC.Types were not re-exported from GHC.Exts, forcing users to import either GHC.Types or GHC.Prim, which are subject to internal change without notice. We now re-export GHC.Types from GHC.Exts, which should avoid this happening again in the future. In particular, we now re-export `Multiplicity` and `MultMul`, which we didn't before. Fixes #20695 - - - - - 483bd04d by Sebastian Graf at 2021-12-07T13:33:31-05:00 Explicit Data.List import list in check-ppr (#20789) `check-ppr` features an import of Data.List without an import list. After 81082cf4, this breaks the local validate flavour because of the compat warning and `-Werror`. So fix that. Fixes #20789. - - - - - cc2bf8e9 by Norman Ramsey at 2021-12-07T17:34:51-05:00 generalize GHC.Cmm.Dataflow to work over any node type See #20725. The commit includes source-code changes and a test case. - - - - - 4c6985cc by Sylvain Henry at 2021-12-07T17:35:30-05:00 Perf: remove an indirection when fetching the unique mask Slight decrease but still noticeable on CI: Baseline Test Metric value New value Change ----------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 747607676.0 747458936.0 -0.0% ManyConstructors(normal) ghc/alloc 4003722296.0 4003530032.0 -0.0% MultiLayerModules(normal) ghc/alloc 3064539560.0 3063984552.0 -0.0% MultiLayerModulesRecomp(normal) ghc/alloc 894700016.0 894700624.0 +0.0% PmSeriesG(normal) ghc/alloc 48410952.0 48262496.0 -0.3% PmSeriesS(normal) ghc/alloc 61561848.0 61415768.0 -0.2% PmSeriesT(normal) ghc/alloc 90975784.0 90829360.0 -0.2% PmSeriesV(normal) ghc/alloc 60405424.0 60259008.0 -0.2% T10421(normal) ghc/alloc 113275928.0 113137168.0 -0.1% T10421a(normal) ghc/alloc 79195676.0 79050112.0 -0.2% T10547(normal) ghc/alloc 28720176.0 28710008.0 -0.0% T10858(normal) ghc/alloc 180992412.0 180857400.0 -0.1% T11195(normal) ghc/alloc 283452220.0 283293832.0 -0.1% T11276(normal) ghc/alloc 137882128.0 137745840.0 -0.1% T11303b(normal) ghc/alloc 44453956.0 44309184.0 -0.3% T11374(normal) ghc/alloc 248118668.0 247979880.0 -0.1% T11545(normal) ghc/alloc 971994728.0 971852696.0 -0.0% T11822(normal) ghc/alloc 131544864.0 131399024.0 -0.1% T12150(optasm) ghc/alloc 79336468.0 79191888.0 -0.2% T12227(normal) ghc/alloc 495064180.0 494943040.0 -0.0% T12234(optasm) ghc/alloc 57198468.0 57053568.0 -0.3% T12425(optasm) ghc/alloc 90928696.0 90793440.0 -0.1% T12545(normal) ghc/alloc 1695417772.0 1695275744.0 -0.0% T12707(normal) ghc/alloc 956258984.0 956138864.0 -0.0% T13035(normal) ghc/alloc 102279484.0 102132616.0 -0.1% T13056(optasm) ghc/alloc 367196556.0 367066408.0 -0.0% T13253(normal) ghc/alloc 334365844.0 334255264.0 -0.0% T13253-spj(normal) ghc/alloc 125474884.0 125328672.0 -0.1% T13379(normal) ghc/alloc 359185604.0 359036960.0 -0.0% T13701(normal) ghc/alloc 2403026480.0 2402677464.0 -0.0% T13719(normal) ghc/alloc 4192234752.0 4192039448.0 -0.0% T14052(ghci) ghc/alloc 2745868552.0 2747706176.0 +0.1% T14052Type(ghci) ghc/alloc 7335937964.0 7336283280.0 +0.0% T14683(normal) ghc/alloc 2992557736.0 2992436872.0 -0.0% T14697(normal) ghc/alloc 363391248.0 363222920.0 -0.0% T15164(normal) ghc/alloc 1292578008.0 1292434240.0 -0.0% T15304(normal) ghc/alloc 1279603472.0 1279465944.0 -0.0% T15630(normal) ghc/alloc 161707776.0 161602632.0 -0.1% T16190(normal) ghc/alloc 276904644.0 276555264.0 -0.1% T16577(normal) ghc/alloc 7573033016.0 7572982752.0 -0.0% T16875(normal) ghc/alloc 34937980.0 34796592.0 -0.4% T17096(normal) ghc/alloc 287436348.0 287299368.0 -0.0% T17516(normal) ghc/alloc 1714727484.0 1714617664.0 -0.0% T17836(normal) ghc/alloc 1091095748.0 1090958168.0 -0.0% T17836b(normal) ghc/alloc 52467912.0 52321296.0 -0.3% T17977(normal) ghc/alloc 44971660.0 44826480.0 -0.3% T17977b(normal) ghc/alloc 40941128.0 40793160.0 -0.4% T18140(normal) ghc/alloc 82363124.0 82213056.0 -0.2% T18223(normal) ghc/alloc 1168448128.0 1168333624.0 -0.0% T18282(normal) ghc/alloc 131577844.0 131440400.0 -0.1% T18304(normal) ghc/alloc 86988664.0 86844432.0 -0.2% T18478(normal) ghc/alloc 742992400.0 742871136.0 -0.0% T18698a(normal) ghc/alloc 337654412.0 337526792.0 -0.0% T18698b(normal) ghc/alloc 398840772.0 398716472.0 -0.0% T18923(normal) ghc/alloc 68964992.0 68818768.0 -0.2% T1969(normal) ghc/alloc 764285884.0 764156168.0 -0.0% T19695(normal) ghc/alloc 1395577984.0 1395552552.0 -0.0% T20049(normal) ghc/alloc 89159032.0 89012952.0 -0.2% T3064(normal) ghc/alloc 191194856.0 191051816.0 -0.1% T3294(normal) ghc/alloc 1604762016.0 1604656488.0 -0.0% T4801(normal) ghc/alloc 296829368.0 296687824.0 -0.0% T5030(normal) ghc/alloc 364720540.0 364580152.0 -0.0% T5321FD(normal) ghc/alloc 271090004.0 270950824.0 -0.1% T5321Fun(normal) ghc/alloc 301244320.0 301102960.0 -0.0% T5631(normal) ghc/alloc 576154548.0 576022904.0 -0.0% T5642(normal) ghc/alloc 471105876.0 470967552.0 -0.0% T5837(normal) ghc/alloc 36328620.0 36186720.0 -0.4% T6048(optasm) ghc/alloc 103125988.0 102981024.0 -0.1% T783(normal) ghc/alloc 386945556.0 386795984.0 -0.0% T9020(optasm) ghc/alloc 247835012.0 247696704.0 -0.1% T9198(normal) ghc/alloc 47556208.0 47413784.0 -0.3% T9233(normal) ghc/alloc 682210596.0 682069960.0 -0.0% T9630(normal) ghc/alloc 1429689648.0 1429581168.0 -0.0% T9675(optasm) ghc/alloc 431092812.0 430943192.0 -0.0% T9872a(normal) ghc/alloc 1705052592.0 1705042064.0 -0.0% T9872b(normal) ghc/alloc 2180406760.0 2180395784.0 -0.0% T9872c(normal) ghc/alloc 1760508464.0 1760497936.0 -0.0% T9872d(normal) ghc/alloc 501517968.0 501309464.0 -0.0% T9961(normal) ghc/alloc 354037204.0 353891576.0 -0.0% TcPlugin_RewritePerf(normal) ghc/alloc 2381708520.0 2381550824.0 -0.0% WWRec(normal) ghc/alloc 589553520.0 589407216.0 -0.0% hard_hole_fits(normal) ghc/alloc 492122188.0 492470648.0 +0.1% hie002(normal) ghc/alloc 9336434800.0 9336443496.0 +0.0% parsing001(normal) ghc/alloc 537680944.0 537659824.0 -0.0% geo. mean -0.1% - - - - - aafa5079 by Andrew Lelechenko at 2021-12-09T04:26:35-05:00 Bump bytestring submodule to 0.11.2.0 Both tests import `Data.ByteString`, so the change in allocations is more or less expected. Metric Increase: T19695 T9630 - - - - - 803eefb1 by Matthew Pickering at 2021-12-09T04:27:11-05:00 package imports: Take into account package visibility when renaming In 806e49ae the package imports refactoring code was modified to rename package imports. There was a small oversight which meant the code didn't account for module visibility. This patch fixes that oversight. In general the "lookupPackageName" function is unsafe to use as it doesn't account for package visiblity/thinning/renaming etc, there is just one use in the compiler which would be good to audit. Fixes #20779 - - - - - 52bbea0f by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 Fix typo and outdated link in Data.Foldable Amazing nobody had reported the "Foldabla" typo. :-( The Traversable docs got overhauled, leaving a stale link in Foldable to a section that got replaced. Gave the new section an anchor and updated the link. - - - - - a722859f by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 A few more typos - - - - - d6177cb5 by Viktor Dukhovni at 2021-12-09T04:27:48-05:00 Drop O(n^2) warning on concat - - - - - 9f988525 by David Feuer at 2021-12-09T13:49:47+00:00 Improve mtimesDefault * Make 'mtimesDefault' use 'stimes' for the underlying monoid rather than the default 'stimes'. * Explain in the documentation why one might use `mtimesDefault`. - - - - - 2fca50d4 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Use same optimization pipeline regardless of `optLevel` (#20500) - - - - - 6d031922 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Add `Opt_CoreConstantFolding` to turn on constant folding (#20500) Previously, `-O1` and `-O2`, by way of their effect on the compilation pipeline, they implicitly turned on constant folding - - - - - b6f7d145 by Gergő Érdi at 2021-12-09T22:14:24-05:00 Remove `optLevel` from `DynFlags` (closes #20500) - - - - - 724df9c3 by Ryan Scott at 2021-12-09T22:15:00-05:00 Hadrian: Allow building with GHC 9.2 A separate issue is the fact that many of `hadrian`'s modules produce `-Wincomplete-uni-patterns` warnings under 9.2, but that is probably best left to a separate patch. - - - - - 80a25502 by Matthew Pickering at 2021-12-09T22:15:35-05:00 Use file hash cache when hashing object file dependencies This fixes the immediate problem that we hash the same file multiple different times which causes quite a noticeably performance regression. In the future we can probably do better than this by storing the implementation hash in the interface file rather than dependending on hashing the object file. Related to #20604 which notes some inefficiencies with the current recompilation logic. Closes #20790 ------------------------- Metric Decrease: T14052Type ------------------------- - - - - - f573cb16 by nineonine at 2021-12-10T06:16:41-05:00 rts: use allocation helpers from RtsUtils Just a tiny cleanup inspired by the following comment: https://gitlab.haskell.org/ghc/ghc/-/issues/19437#note_334271 I was just getting familiar with rts code base so I thought might as well do this. - - - - - 16eab39b by Matthew Pickering at 2021-12-10T06:17:16-05:00 Remove confusing haddock quotes in 'readInt' documentation As pointed out in #20776, placing quotes in this way linked to the 'Integral' type class which is nothing to do with 'readInt', the text should rather just be "integral", to suggest that the argument must be an integer. Closes #20776 - - - - - b4a55419 by Ben Gamari at 2021-12-10T06:17:52-05:00 docs: Drop old release notes Closes #20786 - - - - - 8d1f30e7 by Jakob Brünker at 2021-12-11T00:55:48-05:00 Add PromotedInfixT/PromotedUInfixT to TH Previously, it was not possible to refer to a data constructor using InfixT with a dynamically bound name (i.e. a name with NameFlavour `NameS` or `NameQ`) if a type constructor of the same name exists. This commit adds promoted counterparts to InfixT and UInfixT, analogously to how PromotedT is the promoted counterpart to ConT. Closes #20773 - - - - - 785859fa by Andrew Lelechenko at 2021-12-11T00:56:26-05:00 Bump text submodule to 2.0-rc2 - - - - - 352284de by Sylvain Henry at 2021-12-11T00:57:05-05:00 Perf: remove allocation in writeBlocks and fix comment (#14309) - - - - - 40a44f68 by Douglas Wilson at 2021-12-12T09:09:30-05:00 rts: correct stats when running with +RTS -qn1 Despite the documented care having been taken, several bugs are fixed here. When run with -qn1, when a SYNC_GC_PAR is requested we will have n_gc_threads == n_capabilities && n_gc_idle_threads == (n_gc_threads - 1) In this case we now: * Don't increment par_collections * Don't increment par_balanced_copied * Don't emit debug traces for idle threads * Take the fast path in scavenge_until_all_done, wakeup_gc_threads, and shutdown_gc_threads. Some ASSERTs have also been tightened. Fixes #19685 - - - - - 6b2947d2 by Matthew Pickering at 2021-12-12T09:10:06-05:00 iserv: Remove network dependent parts of libiserv As noted in #20794 the parts of libiserv and iserv-proxy depend on network, therefore are never built nor tested during CI. Due to this iserv-proxy had bitrotted due to the bound on bytestring being out of date. Given we don't test this code it seems undesirable to distribute it. Therefore, it's removed and an external maintainer can be responsible for testing it (via head.hackage if desired). Fixes #20794 - - - - - f04d1a49 by Ben Gamari at 2021-12-12T09:10:41-05:00 gitlab-ci: Bump fedora jobs to use Fedora 33 Annoyingly, this will require downstream changes in head.hackage, which depends upon the artifact produced by this job. Prompted by !6462. - - - - - 93783e6a by Andrey Mokhov at 2021-12-12T09:11:20-05:00 Drop --configure from Hadrian docs - - - - - 31bf380f by Oleg Grenrus at 2021-12-12T12:52:18-05:00 Use HasCallStack and error in GHC.List and .NonEmpty In addition to providing stack traces, the scary HasCallStack will hopefully make people think whether they want to use these functions, i.e. act as a documentation hint that something weird might happen. A single metric increased, which doesn't visibly use any method with `HasCallStack`. ------------------------- Metric Decrease: T9630 Metric Decrease: T19695 T9630 ------------------------- - - - - - 401ddd53 by Greg Steuck at 2021-12-12T12:52:56-05:00 Respect W^X in Linker.c:preloadObjectFile on OpenBSD This fixes -fexternal-interpreter for ghci. Fixes #20814. - - - - - c43ee6b8 by Andreas Klebinger at 2021-12-14T19:24:20+01:00 GHC.Utils.Misc.only: Add doc string. This function expects a singleton list as argument but only checks this in debug builds. I've added a docstring saying so. Fixes #20797 - - - - - 9ff54ea8 by Vaibhav Sagar at 2021-12-14T20:50:08-05:00 Data.Functor.Classes: fix Ord1 instance for Down - - - - - 8a2de3c2 by Tamar Christina at 2021-12-14T20:50:47-05:00 rts: update xxhash used by the linker's hashmap - - - - - 1c8d609a by alirezaghey at 2021-12-14T20:51:25-05:00 fix ambiguity in `const` documentation fixes #20412 - - - - - a5d8d47f by Joachim Breitner at 2021-12-14T20:52:00-05:00 Ghci environment: Do not remove shadowed ids Names defined earier but shadowed need to be kept around, e.g. for type signatures: ``` ghci> data T = T ghci> let t = T ghci> data T = T ghci> :t t t :: Ghci1.T ``` and indeed they can be used: ``` ghci> let t2 = Ghci1.T :: Ghci1.T ghci> :t t2 t2 :: Ghci1.T ``` However, previously this did not happen for ids (non-types), although they are still around under the qualified name internally: ``` ghci> let t = "other t" ghci> t' <interactive>:8:1: error: • Variable not in scope: t' • Perhaps you meant one of these: ‘Ghci2.t’ (imported from Ghci2), ‘t’ (line 7), ‘t2’ (line 5) ghci> Ghci2.t <interactive>:9:1: error: • GHC internal error: ‘Ghci2.t’ is not in scope during type checking, but it passed the renamer tcl_env of environment: [] • In the expression: Ghci2.t In an equation for ‘it’: it = Ghci2.t ``` This fixes the problem by simply removing the code that tries to remove shadowed ids from the environment. Now you can refer to shadowed ids using `Ghci2.t`, just like you can do for data and type constructors. This simplifies the code, makes terms and types more similar, and also fixes #20455. Now all names ever defined in GHCi are in `ic_tythings`, which is printed by `:show bindings`. But for that commands, it seems to be more ergonomic to only list those bindings that are not shadowed. Or, even if it is not more ergonomic, it’s the current behavour. So let's restore that by filtering in `icInScopeTTs`. Of course a single `TyThing` can be associated with many names. We keep it it in the bindings if _any_ of its names are still visible unqualifiedly. It's a judgement call. This commit also turns a rather old comment into a test files. The comment is is rather stale and things are better explained elsewhere. Fixes #925. Two test cases are regressing: T14052(ghci) ghc/alloc 2749444288.0 12192109912.0 +343.4% BAD T14052Type(ghci) ghc/alloc 7365784616.0 10767078344.0 +46.2% BAD This is not unexpected; the `ic_tythings list grows` a lot more if we don’t remove shadowed Ids. I tried to alleviate it a bit with earlier MRs, but couldn’t make up for it completely. Metric Increase: T14052 T14052Type - - - - - 7c2609d8 by Cheng Shao at 2021-12-14T20:52:37-05:00 base: fix clockid_t usage when it's a pointer type in C Closes #20607. - - - - - 55cb2aa7 by MichaWiedenmann1 at 2021-12-14T20:53:16-05:00 Fixes typo in documentation of the Semigroup instance of Equivalence - - - - - 82c39f4d by Ben Gamari at 2021-12-14T20:53:51-05:00 users-guide: Fix documentation for -shared flag This flag was previously called `--mk-dll`. It was renamed to `-shared` in b562cbe381d54e08dcafa11339e9a82e781ad557 but the documentation wasn't updated to match. - - - - - 4f654071 by Ben Gamari at 2021-12-14T20:53:51-05:00 compiler: Drop `Maybe ModLocation` from T_MergeForeign This field was entirely unused. - - - - - 71ecb55b by Ben Gamari at 2021-12-14T20:53:51-05:00 compiler: Use withFile instead of bracket A minor refactoring noticed by hlint. - - - - - 5686f47b by Ben Gamari at 2021-12-14T20:53:51-05:00 ghc-bin: Add --merge-objs mode This adds a new mode, `--merge-objs`, which can be used to produce merged GHCi library objects. As future work we will rip out the object-merging logic in Hadrian and Cabal and instead use this mode. Closes #20712. - - - - - 0198bb11 by Ben Gamari at 2021-12-14T20:54:27-05:00 libiserv: Rename Lib module to IServ As proposed in #20546. - - - - - ecaec722 by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm: Remove DynFlags, add LlvmCgConfig CodeOutput: LCGConfig, add handshake initLCGConfig Add two modules: GHC.CmmToLlvm.Config -- to hold the Llvm code gen config GHC.Driver.Config.CmmToLlvm -- for initialization, other utils CmmToLlvm: remove HasDynFlags, add LlvmConfig CmmToLlvm: add lcgContext to LCGConfig CmmToLlvm.Base: DynFlags --> LCGConfig Llvm: absorb LlvmOpts into LCGConfig CmmToLlvm.Ppr: swap DynFlags --> LCGConfig CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig CmmToLlvm.Data: swap LlvmOpts --> LCGConfig CmmToLlvm: swap DynFlags --> LCGConfig CmmToLlvm: move LlvmVersion to CmmToLlvm.Config Additionally: - refactor Config and initConfig to hold LlvmVersion - push IO needed to get LlvmVersion to boundary between Cmm and LLvm code generation - remove redundant imports, this is much cleaner! CmmToLlvm.Config: store platformMisc_llvmTarget instead of all of platformMisc - - - - - 6b0fb9a0 by doyougnu at 2021-12-14T20:55:06-05:00 SysTools.Tasks Llvm.Types: remove redundant import Llvm.Types: remove redundant import SysTools.Tasks: remove redundant import - namely CmmToLlvm.Base - - - - - 80016022 by doyougnu at 2021-12-14T20:55:06-05:00 LLVM.CodeGen: use fast-string literals That is remove factorization of common strings and string building code for the LLVM code gen ops. Replace these with string literals to obey the FastString rewrite rule in GHC.Data.FastString and compute the string length at compile time - - - - - bc663f87 by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm.Config: strictify LlvmConfig field - - - - - 70f0aafe by doyougnu at 2021-12-14T20:55:06-05:00 CmmToLlvm: rename LCGConfig -> LlvmCgConfig CmmToLlvm: renamce lcgPlatform -> llvmCgPlatform CmmToLlvm: rename lcgContext -> llvmCgContext CmmToLlvm: rename lcgFillUndefWithGarbage CmmToLlvm: rename lcgSplitSections CmmToLlvm: lcgBmiVersion -> llvmCgBmiVersion CmmToLlvm: lcgLlvmVersion -> llvmCgLlvmVersion CmmToLlvm: lcgDoWarn -> llvmCgDoWarn CmmToLlvm: lcgLlvmConfig -> llvmCgLlvmConfig CmmToLlvm: llvmCgPlatformMisc --> llvmCgLlvmTarget - - - - - 34abbd81 by Greg Steuck at 2021-12-14T20:55:43-05:00 Add OpenBSD to llvm-targets This improves some tests that previously failed with: ghc: panic! (the 'impossible' happened) GHC version 9.3.20211211: Failed to lookup LLVM data layout Target: x86_64-unknown-openbsd Added the new generated lines to `llvm-targets` on an openbsd 7.0-current with clang 11.1.0. - - - - - 45bd6308 by Joachim Breitner at 2021-12-14T20:56:18-05:00 Test case from #19313 - - - - - f5a0b408 by Andrei Barbu at 2021-12-15T16:33:17-05:00 Plugin load order should follow the commandline order (fixes #17884) In the past the order was reversed because flags are consed onto a list. No particular behavior was documented. We now reverse the flags and document the behavior. - - - - - d13b9f20 by Cheng Shao at 2021-12-15T16:33:54-05:00 base: use `CUIntPtr` instead of `Ptr ()` as the autoconf detected Haskell type for C pointers When autoconf detects a C pointer type, we used to specify `Ptr ()` as the Haskell type. This doesn't work in some cases, e.g. in `wasi-libc`, `clockid_t` is a pointer type, but we expected `CClockId` to be an integral type, and `Ptr ()` lacks various integral type instances. - - - - - 89c1ffd6 by Cheng Shao at 2021-12-15T16:33:54-05:00 base: fix autoconf detection of C pointer types We used to attempt compiling `foo_t val; *val;` to determine if `foo_t` is a pointer type in C. This doesn't work if `foo_t` points to an incomplete type, and autoconf will detect `foo_t` as a floating point type in that case. Now we use `memset(val, 0, 0)` instead, and it works for incomplete types as well. - - - - - 6cea7311 by Cheng Shao at 2021-12-15T16:33:54-05:00 Add a note to base changelog - - - - - 3c3e5c03 by Ben Gamari at 2021-12-17T21:20:57-05:00 Regression test for renamer/typechecker performance (#20261) We use the parser generated by stack to ensure reproducibility - - - - - 5d5620bc by Krzysztof Gogolewski at 2021-12-17T21:21:32-05:00 Change isUnliftedTyCon to marshalablePrimTyCon (#20401) isUnliftedTyCon was used in three places: Ticky, Template Haskell and FFI checks. It was straightforward to remove it from Ticky and Template Haskell. It is now used in FFI only and renamed to marshalablePrimTyCon. Previously, it was fetching information from a field in PrimTyCon called is_unlifted. Instead, I've changed the code to compute liftedness based on the kind. isFFITy and legalFFITyCon are removed. They were only referred from an old comment that I removed. There were three functions to define a PrimTyCon, but the only difference was that they were setting is_unlifted to True or False. Everything is now done in mkPrimTyCon. I also added missing integer types in Ticky.hs, I think it was an oversight. Fixes #20401 - - - - - 9d77976d by Matthew Pickering at 2021-12-17T21:22:08-05:00 testsuite: Format metric results with comma separator As noted in #20763 the way the stats were printed was quite hard for a human to compare. Therefore we now insert the comma separator so that they are easier to compare at a glance. Before: ``` Baseline Test Metric value New value Change ----------------------------------------------------------------------------- Conversions(normal) run/alloc 107088.0 107088.0 +0.0% DeriveNull(normal) run/alloc 112050656.0 112050656.0 +0.0% InlineArrayAlloc(normal) run/alloc 1600040712.0 1600040712.0 +0.0% InlineByteArrayAlloc(normal) run/alloc 1440040712.0 1440040712.0 +0.0% InlineCloneArrayAlloc(normal) run/alloc 1600040872.0 1600040872.0 +0.0% MethSharing(normal) run/alloc 480097864.0 480097864.0 +0.0% T10359(normal) run/alloc 354344.0 354344.0 +0.0% ``` After ``` Baseline Test Metric value New value Change ---------------------------------------------------------------------------------- Conversions(normal) run/alloc 107,088 107,088 +0.0% DeriveNull(normal) run/alloc 112,050,656 112,050,656 +0.0% InlineArrayAlloc(normal) run/alloc 1,600,040,712 1,600,040,712 +0.0% InlineByteArrayAlloc(normal) run/alloc 1,440,040,712 1,440,040,712 +0.0% InlineCloneArrayAlloc(normal) run/alloc 1,600,040,872 1,600,040,872 +0.0% MethSharing(normal) run/alloc 480,097,864 480,097,864 +0.0% T10359(normal) run/alloc 354,344 354,344 +0.0% ``` Closes #20763 - - - - - 3f31bfe8 by Sylvain Henry at 2021-12-17T21:22:48-05:00 Perf: inline exprIsCheapX Allow specialization for the ok_app predicate. Perf improvements: Baseline Test Metric value New value Change ----------------------------------------------------------------------------- ManyAlternatives(normal) ghc/alloc 747317244.0 746444024.0 -0.1% ManyConstructors(normal) ghc/alloc 4005046448.0 4001548792.0 -0.1% MultiLayerModules(normal) ghc/alloc 3063361000.0 3063178472.0 -0.0% MultiLayerModulesRecomp(normal) ghc/alloc 894208428.0 894252496.0 +0.0% PmSeriesG(normal) ghc/alloc 48021692.0 47901592.0 -0.3% PmSeriesS(normal) ghc/alloc 61322504.0 61149008.0 -0.3% PmSeriesT(normal) ghc/alloc 90879364.0 90609048.0 -0.3% PmSeriesV(normal) ghc/alloc 60155376.0 59983632.0 -0.3% T10421(normal) ghc/alloc 112820720.0 112517208.0 -0.3% T10421a(normal) ghc/alloc 78783696.0 78557896.0 -0.3% T10547(normal) ghc/alloc 28331984.0 28354160.0 +0.1% T10858(normal) ghc/alloc 180715296.0 180226720.0 -0.3% T11195(normal) ghc/alloc 284139184.0 283981048.0 -0.1% T11276(normal) ghc/alloc 137830804.0 137688912.0 -0.1% T11303b(normal) ghc/alloc 44080856.0 43956152.0 -0.3% T11374(normal) ghc/alloc 249319644.0 249059288.0 -0.1% T11545(normal) ghc/alloc 971507488.0 971146136.0 -0.0% T11822(normal) ghc/alloc 131410208.0 131269664.0 -0.1% T12150(optasm) ghc/alloc 78866860.0 78762296.0 -0.1% T12227(normal) ghc/alloc 494467900.0 494138112.0 -0.1% T12234(optasm) ghc/alloc 56781044.0 56588256.0 -0.3% T12425(optasm) ghc/alloc 90462264.0 90240272.0 -0.2% T12545(normal) ghc/alloc 1694316588.0 1694128448.0 -0.0% T12707(normal) ghc/alloc 955665168.0 955005336.0 -0.1% T13035(normal) ghc/alloc 101875160.0 101713312.0 -0.2% T13056(optasm) ghc/alloc 366370168.0 365347632.0 -0.3% T13253(normal) ghc/alloc 333741472.0 332612920.0 -0.3% T13253-spj(normal) ghc/alloc 124947560.0 124427552.0 -0.4% T13379(normal) ghc/alloc 358997996.0 358879840.0 -0.0% T13701(normal) ghc/alloc 2400391456.0 2399956840.0 -0.0% T13719(normal) ghc/alloc 4193179228.0 4192476392.0 -0.0% T14052(ghci) ghc/alloc 2734741552.0 2735731808.0 +0.0% T14052Type(ghci) ghc/alloc 7323235724.0 7323042264.0 -0.0% T14683(normal) ghc/alloc 2990457260.0 2988899144.0 -0.1% T14697(normal) ghc/alloc 363606476.0 363452952.0 -0.0% T15164(normal) ghc/alloc 1291321780.0 1289491968.0 -0.1% T15304(normal) ghc/alloc 1277838020.0 1276208304.0 -0.1% T15630(normal) ghc/alloc 161074632.0 160388136.0 -0.4% T16190(normal) ghc/alloc 276567192.0 276235216.0 -0.1% T16577(normal) ghc/alloc 7564318656.0 7535598656.0 -0.4% T16875(normal) ghc/alloc 34867720.0 34752440.0 -0.3% T17096(normal) ghc/alloc 288477360.0 288156960.0 -0.1% T17516(normal) ghc/alloc 1712777224.0 1704655496.0 -0.5% T17836(normal) ghc/alloc 1092127336.0 1091709880.0 -0.0% T17836b(normal) ghc/alloc 52083516.0 51954056.0 -0.2% T17977(normal) ghc/alloc 44552228.0 44425448.0 -0.3% T17977b(normal) ghc/alloc 40540252.0 40416856.0 -0.3% T18140(normal) ghc/alloc 81908200.0 81678928.0 -0.3% T18223(normal) ghc/alloc 1166459176.0 1164418104.0 -0.2% T18282(normal) ghc/alloc 131123648.0 130740432.0 -0.3% T18304(normal) ghc/alloc 86486796.0 86223088.0 -0.3% T18478(normal) ghc/alloc 746029440.0 745619968.0 -0.1% T18698a(normal) ghc/alloc 337037580.0 336533824.0 -0.1% T18698b(normal) ghc/alloc 398324600.0 397696400.0 -0.2% T18923(normal) ghc/alloc 68496432.0 68286264.0 -0.3% T1969(normal) ghc/alloc 760424696.0 759641664.0 -0.1% T19695(normal) ghc/alloc 1421672472.0 1413682104.0 -0.6% T20049(normal) ghc/alloc 88601524.0 88336560.0 -0.3% T3064(normal) ghc/alloc 190808832.0 190659328.0 -0.1% T3294(normal) ghc/alloc 1604483120.0 1604339080.0 -0.0% T4801(normal) ghc/alloc 296501624.0 296388448.0 -0.0% T5030(normal) ghc/alloc 364336308.0 364206240.0 -0.0% T5321FD(normal) ghc/alloc 270688492.0 270386832.0 -0.1% T5321Fun(normal) ghc/alloc 300860396.0 300559200.0 -0.1% T5631(normal) ghc/alloc 575822760.0 575579160.0 -0.0% T5642(normal) ghc/alloc 470243356.0 468988784.0 -0.3% T5837(normal) ghc/alloc 35936468.0 35821360.0 -0.3% T6048(optasm) ghc/alloc 102587024.0 102222000.0 -0.4% T783(normal) ghc/alloc 386539204.0 386003344.0 -0.1% T9020(optasm) ghc/alloc 247435312.0 247324184.0 -0.0% T9198(normal) ghc/alloc 47170036.0 47054840.0 -0.2% T9233(normal) ghc/alloc 677186820.0 676550032.0 -0.1% T9630(normal) ghc/alloc 1456411516.0 1451045736.0 -0.4% T9675(optasm) ghc/alloc 427190224.0 426812568.0 -0.1% T9872a(normal) ghc/alloc 1704660040.0 1704681856.0 +0.0% T9872b(normal) ghc/alloc 2180109488.0 2180130856.0 +0.0% T9872c(normal) ghc/alloc 1760209640.0 1760231456.0 +0.0% T9872d(normal) ghc/alloc 501126052.0 500973488.0 -0.0% T9961(normal) ghc/alloc 353244688.0 353063104.0 -0.1% TcPlugin_RewritePerf(normal) ghc/alloc 2387276808.0 2387254168.0 -0.0% WWRec(normal) ghc/alloc 588651140.0 587684704.0 -0.2% hard_hole_fits(normal) ghc/alloc 492063812.0 491798360.0 -0.1% hie002(normal) ghc/alloc 9334355960.0 9334396872.0 +0.0% parsing001(normal) ghc/alloc 537410584.0 537421736.0 +0.0% geo. mean -0.2% - - - - - e04878b0 by Matthew Pickering at 2021-12-17T21:23:23-05:00 ci: Use correct metrics baseline It turns out there was already a function in the CI script to correctly set the baseline for performance tests but it was just never called. I now call it during the initialisation to set the correct baseline. I also made the make testsuite driver take into account the PERF_BASELINE_COMMIT environment variable Fixes #20811 - - - - - 1327c176 by Matthew Pickering at 2021-12-17T21:23:58-05:00 Add regression test for T20189 Closes #20189 - - - - - fc9b1755 by Matthew Pickering at 2021-12-17T21:24:33-05:00 Fix documentation formatting in Language.Haskell.TH.CodeDo Fixes #20543 - - - - - abef93f3 by Matthew Pickering at 2021-12-17T21:24:33-05:00 Expand documentation for MulArrowT constructor Fixes #20812 - - - - - 94c3ff66 by Cheng Shao at 2021-12-17T21:25:09-05:00 Binary: make withBinBuffer safe With this patch, withBinBuffer will construct a ByteString that properly captures the reference to the BinHandle internal MutableByteArray#, making it safe to convert a BinHandle to ByteString and use that ByteString outside the continuation. - - - - - a3552934 by Sebastian Graf at 2021-12-17T21:25:45-05:00 Demand: `Eq DmdType` modulo `defaultFvDmd` (#20827) Fixes #20827 by filtering out any default free variable demands (as per `defaultFvDmd`) prior to comparing the assocs of the `DmdEnv`. The details are in `Note [Demand type Equality]`. - - - - - 9529d859 by Sylvain Henry at 2021-12-17T21:26:24-05:00 Perf: avoid using (replicateM . length) when possible Extracted from !6622 - - - - - 887d8b4c by Matthew Pickering at 2021-12-17T21:26:59-05:00 testsuite: Ensure that -dcore-lint is not set for compiler performance tests This place ensures that the default -dcore-lint option is disabled by default when collect_compiler_stats is used but you can still pass -dcore-lint as an additional option (see T1969 which tests core lint performance). Fixes #20830 ------------------------- Metric Decrease: PmSeriesS PmSeriesT PmSeriesV T10858 T11195 T11276 T11374 T11822 T14052 T14052Type T17096 T17836 T17836b T18478 T18698a T18698b ------------------------- - - - - - 5ff47ff5 by Ben Gamari at 2021-12-21T01:46:00-05:00 codeGen: Introduce flag to bounds-check array accesses Here we introduce code generator support for instrument array primops with bounds checking, enabled with the `-fcheck-prim-bounds` flag. Introduced to debug #20769. - - - - - d47bb109 by Ben Gamari at 2021-12-21T01:46:00-05:00 rts: Add optional bounds checking in out-of-line primops - - - - - 8ea79a16 by Ben Gamari at 2021-12-21T01:46:00-05:00 Rename -fcatch-bottoms to -fcatch-nonexhaustive-cases As noted in #20601, the previous name was rather misleading. - - - - - 00b55bfc by Ben Gamari at 2021-12-21T01:46:00-05:00 Introduce -dlint flag As suggested in #20601, this is a short-hand for enabling the usual GHC-internal sanity checks one typically leans on when debugging runtime crashes. - - - - - 9728d6c2 by Sylvain Henry at 2021-12-21T01:46:39-05:00 Give plugins a better interface (#17957) Plugins were directly fetched from HscEnv (hsc_static_plugins and hsc_plugins). The tight coupling of plugins and of HscEnv is undesirable and it's better to store them in a new Plugins datatype and to use it in the plugins' API (e.g. withPlugins, mapPlugins...). In the process, the interactive context (used by GHCi) got proper support for different static plugins than those used for loaded modules. Bump haddock submodule - - - - - 9bc5ab64 by Greg Steuck at 2021-12-21T01:47:17-05:00 Use libc++ instead of libstdc++ on openbsd in addition to freebsd This is not entirely accurate because some openbsd architectures use gcc. Yet we don't have ghc ported to them and thus the approximation is good enough. Fixes ghcilink006 test - - - - - f92c9c0d by Greg Steuck at 2021-12-21T01:47:55-05:00 Only use -ldl conditionally to fix T3807 OpenBSD doesn't have this library and so the linker complains: ld.lld: error: unable to find library -ldl - - - - - ff657a81 by Greg Steuck at 2021-12-21T01:48:32-05:00 Mark `linkwhole` test as expected broken on OpenBSD per #20841 - - - - - 1a596d06 by doyougnu at 2021-12-22T00:12:27-05:00 Cmm: DynFlags to CmmConfig refactor add files GHC.Cmm.Config, GHC.Driver.Config.Cmm Cmm: DynFlag references --> CmmConfig Cmm.Pipeline: reorder imports, add handshake Cmm: DynFlag references --> CmmConfig Cmm.Pipeline: DynFlag references --> CmmConfig Cmm.LayoutStack: DynFlag references -> CmmConfig Cmm.Info.Build: DynFlag references -> CmmConfig Cmm.Config: use profile to retrieve platform Cmm.CLabel: unpack NCGConfig in labelDynamic Cmm.Config: reduce CmmConfig surface area Cmm.Config: add cmmDoCmmSwitchPlans field Cmm.Config: correct cmmDoCmmSwitchPlans flag The original implementation dispatches work in cmmImplementSwitchPlans in an `otherwise` branch, hence we must add a not to correctly dispatch Cmm.Config: add cmmSplitProcPoints simplify Config remove cmmBackend, and cmmPosInd Cmm.CmmToAsm: move ncgLabelDynamic to CmmToAsm Cmm.CLabel: remove cmmLabelDynamic function Cmm.Config: rename cmmOptDoLinting -> cmmDoLinting testsuite: update CountDepsAst CountDepsParser - - - - - d7cc8f19 by Matthew Pickering at 2021-12-22T00:13:02-05:00 ci: Fix master CI I made a mistake in the bash script so there were errors about "$CI_MERGE_REQUEST_DIFF_BASE_SHA" not existing. - - - - - 09b6cb45 by Alan Zimmerman at 2021-12-22T00:13:38-05:00 Fix panic trying to -ddump-parsed-ast for implicit fixity A declaration such as infixr ++++ is supplied with an implicit fixity of 9 in the parser, but uses an invalid SrcSpan to capture this. Use of this span triggers a panic. Fix the problem by not recording an exact print annotation for the non-existent fixity source. Closes #20846 - - - - - 3ed90911 by Matthew Pickering at 2021-12-22T14:47:40-05:00 testsuite: Remove reqlib modifier The reqlib modifer was supposed to indicate that a test needed a certain library in order to work. If the library happened to be installed then the test would run as normal. However, CI has never run these tests as the packages have not been installed and we don't want out tests to depend on things which might get externally broken by updating the compiler. The new strategy is to run these tests in head.hackage, where the tests have been cabalised as well as possible. Some tests couldn't be transferred into the normal style testsuite but it's better than never running any of the reqlib tests. https://gitlab.haskell.org/ghc/head.hackage/-/merge_requests/169 A few submodules also had reqlib tests and have been updated to remove it. Closes #16264 #20032 #17764 #16561 - - - - - ac3e8c52 by Matthew Pickering at 2021-12-22T14:48:16-05:00 perf ci: Start searching form the performance baseline If you specify PERF_BASELINE_COMMIT then this can fail if the specific commit you selected didn't have perf test metrics. (This can happen in CI for example if a build fails on master). Therefore instead of just reporting all tests as new, we start searching downwards from this point to try and find a good commit to report numbers from. - - - - - 9552781a by Matthew Pickering at 2021-12-22T14:48:51-05:00 Mark T16525b as fragile on windows See ticket #20852 - - - - - 13a6d85a by Andreas Klebinger at 2021-12-23T10:55:36-05:00 Make callerCC profiling mode represent entry counter flag. Fixes #20854 - - - - - 80daefce by Matthew Pickering at 2021-12-23T10:56:11-05:00 Properly filter for module visibility in resolvePackageImport This completes the fix for #20779 / !7123. Beforehand, the program worked by accident because the two versions of the library happened to be ordered properly (due to how the hashes were computed). In the real world I observed them being the other way around which meant the final lookup failed because we weren't filtering for visibility. I modified the test so that it failed (and it's fixed by this patch). - - - - - e6191d39 by Krzysztof Gogolewski at 2021-12-25T18:26:44+01:00 Fix typos - - - - - 3219610e by Greg Steuck at 2021-12-26T22:12:43-05:00 Use POSIX-compliant egrep expression to fix T8832 on OpenBSD - - - - - fd42ab5f by Matthew Pickering at 2021-12-28T09:47:53+00:00 Multiple Home Units Multiple home units allows you to load different packages which may depend on each other into one GHC session. This will allow both GHCi and HLS to support multi component projects more naturally. Public Interface ~~~~~~~~~~~~~~~~ In order to specify multiple units, the -unit @⟨filename⟩ flag is given multiple times with a response file containing the arguments for each unit. The response file contains a newline separated list of arguments. ``` ghc -unit @unitLibCore -unit @unitLib ``` where the `unitLibCore` response file contains the normal arguments that cabal would pass to `--make` mode. ``` -this-unit-id lib-core-0.1.0.0 -i -isrc LibCore.Utils LibCore.Types ``` The response file for lib, can specify a dependency on lib-core, so then modules in lib can use modules from lib-core. ``` -this-unit-id lib-0.1.0.0 -package-id lib-core-0.1.0.0 -i -isrc Lib.Parse Lib.Render ``` Then when the compiler starts in --make mode it will compile both units lib and lib-core. There is also very basic support for multiple home units in GHCi, at the moment you can start a GHCi session with multiple units but only the :reload is supported. Most commands in GHCi assume a single home unit, and so it is additional work to work out how to modify the interface to support multiple loaded home units. Options used when working with Multiple Home Units There are a few extra flags which have been introduced specifically for working with multiple home units. The flags allow a home unit to pretend it’s more like an installed package, for example, specifying the package name, module visibility and reexported modules. -working-dir ⟨dir⟩ It is common to assume that a package is compiled in the directory where its cabal file resides. Thus, all paths used in the compiler are assumed to be relative to this directory. When there are multiple home units the compiler is often not operating in the standard directory and instead where the cabal.project file is located. In this case the -working-dir option can be passed which specifies the path from the current directory to the directory the unit assumes to be it’s root, normally the directory which contains the cabal file. When the flag is passed, any relative paths used by the compiler are offset by the working directory. Notably this includes -i and -I⟨dir⟩ flags. -this-package-name ⟨name⟩ This flag papers over the awkward interaction of the PackageImports and multiple home units. When using PackageImports you can specify the name of the package in an import to disambiguate between modules which appear in multiple packages with the same name. This flag allows a home unit to be given a package name so that you can also disambiguate between multiple home units which provide modules with the same name. -hidden-module ⟨module name⟩ This flag can be supplied multiple times in order to specify which modules in a home unit should not be visible outside of the unit it belongs to. The main use of this flag is to be able to recreate the difference between an exposed and hidden module for installed packages. -reexported-module ⟨module name⟩ This flag can be supplied multiple times in order to specify which modules are not defined in a unit but should be reexported. The effect is that other units will see this module as if it was defined in this unit. The use of this flag is to be able to replicate the reexported modules feature of packages with multiple home units. Offsetting Paths in Template Haskell splices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When using Template Haskell to embed files into your program, traditionally the paths have been interpreted relative to the directory where the .cabal file resides. This causes problems for multiple home units as we are compiling many different libraries at once which have .cabal files in different directories. For this purpose we have introduced a way to query the value of the -working-dir flag to the Template Haskell API. By using this function we can implement a makeRelativeToProject function which offsets a path which is relative to the original project root by the value of -working-dir. ``` import Language.Haskell.TH.Syntax ( makeRelativeToProject ) foo = $(makeRelativeToProject "./relative/path" >>= embedFile) ``` > If you write a relative path in a Template Haskell splice you should use the makeRelativeToProject function so that your library works correctly with multiple home units. A similar function already exists in the file-embed library. The function in template-haskell implements this function in a more robust manner by honouring the -working-dir flag rather than searching the file system. Closure Property for Home Units ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For tools or libraries using the API there is one very important closure property which must be adhered to: > Any dependency which is not a home unit must not (transitively) depend on a home unit. For example, if you have three packages p, q and r, then if p depends on q which depends on r then it is illegal to load both p and r as home units but not q, because q is a dependency of the home unit p which depends on another home unit r. If you are using GHC by the command line then this property is checked, but if you are using the API then you need to check this property yourself. If you get it wrong you will probably get some very confusing errors about overlapping instances. Limitations of Multiple Home Units ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are a few limitations of the initial implementation which will be smoothed out on user demand. * Package thinning/renaming syntax is not supported * More complicated reexports/renaming are not yet supported. * It’s more common to run into existing linker bugs when loading a large number of packages in a session (for example #20674, #20689) * Backpack is not yet supported when using multiple home units. * Dependency chasing can be quite slow with a large number of modules and packages. * Loading wired-in packages as home units is currently not supported (this only really affects GHC developers attempting to load template-haskell). * Barely any normal GHCi features are supported, it would be good to support enough for ghcid to work correctly. Despite these limitations, the implementation works already for nearly all packages. It has been testing on large dependency closures, including the whole of head.hackage which is a total of 4784 modules from 452 packages. Internal Changes ~~~~~~~~~~~~~~~~ * The biggest change is that the HomePackageTable is replaced with the HomeUnitGraph. The HomeUnitGraph is a map from UnitId to HomeUnitEnv, which contains information specific to each home unit. * The HomeUnitEnv contains: - A unit state, each home unit can have different package db flags - A set of dynflags, each home unit can have different flags - A HomePackageTable * LinkNode: A new node type is added to the ModuleGraph, this is used to place the linking step into the build plan so linking can proceed in parralel with other packages being built. * New invariant: Dependencies of a ModuleGraphNode can be completely determined by looking at the value of the node. In order to achieve this, downsweep now performs a more complete job of downsweeping and then the dependenices are recorded forever in the node rather than being computed again from the ModSummary. * Some transitive module calculations are rewritten to use the ModuleGraph which is more efficient. * There is always an active home unit, which simplifies modifying a lot of the existing API code which is unit agnostic (for example, in the driver). The road may be bumpy for a little while after this change but the basics are well-tested. One small metric increase, which we accept and also submodule update to haddock which removes ExtendedModSummary. Closes #10827 ------------------------- Metric Increase: MultiLayerModules ------------------------- Co-authored-by: Fendor <power.walross at gmail.com> - - - - - 72824c63 by Richard Eisenberg at 2021-12-28T10:09:28-05:00 Skip computing superclass origins for equalities This yields a small, but measurable, performance improvement. - - - - - 8b6aafb2 by Matthew Pickering at 2021-12-29T14:09:47-05:00 Cabal: Update submodule Closes #20874 - - - - - 44a5507f by Peter Trommler at 2021-12-29T14:10:22-05:00 RTS: Fix CloneStack.c when no table next to code Function `lookupIPE` does not modify its argument. Reflect this in the type. Module `CloneStack.c` relies on this for RTS without tables next to code. Fixes #20879 - - - - - 246d2782 by sheaf at 2022-01-02T04:20:09-05:00 User's guide: newtype decls can use GADTSyntax The user's guide failed to explicitly mention that GADTSyntax can be used to declare newtypes, so we add an example and a couple of explanations. Also explains that `-XGADTs` generalises `-XExistentialQuantification`. Fixes #20848 and #20865. - - - - - f212cece by Hécate Moonlight at 2022-01-02T04:20:47-05:00 Add a source-repository stanza to rts/rts.cabal - - - - - d9e49195 by Greg Steuck at 2022-01-03T05:18:24+00:00 Replace `seq` with POSIX-standard printf(1) in ManyAlternatives test The test now passes on OpenBSD instead of generating broken source which was rejected by GHC with ManyAlternatives.hs:5:1: error: The type signature for ‘f’ lacks an accompanying binding - - - - - 80e416ae by Greg Steuck at 2022-01-03T05:18:24+00:00 Replace `seq` with POSIX-standard in PmSeriesG test - - - - - 8fa52f5c by Eric Lindblad at 2022-01-03T16:48:51-05:00 fix typo - - - - - a49f5889 by Roland Senn at 2022-01-03T16:49:29-05:00 Add regressiontest for #18045 Issue #18045 got fixed by !6971. - - - - - 7f10686e by sheaf at 2022-01-03T16:50:07-05:00 Add test for #20894 - - - - - 5111028e by sheaf at 2022-01-04T19:56:13-05:00 Check quoted TH names are in the correct namespace When quoting (using a TH single or double quote) a built-in name such as the list constructor (:), we didn't always check that the resulting 'Name' was in the correct namespace. This patch adds a check in GHC.Rename.Splice to ensure we get a Name that is in the term-level/type-level namespace, when using a single/double tick, respectively. Fixes #20884. - - - - - 1de94daa by George Thomas at 2022-01-04T19:56:51-05:00 Fix Haddock parse error in GHC.Exts.Heap.FFIClosures.hs - - - - - e59bd46a by nineonine at 2022-01-05T18:07:18+00:00 Add regression test (#13997) - - - - - c080b443 by Sylvain Henry at 2022-01-06T02:24:54-05:00 Perf: use SmallArray for primops' Ids cache (#20857) SmallArray doesn't perform bounds check (faster). Make primop tags start at 0 to avoid index arithmetic. - - - - - ec26c38b by Sylvain Henry at 2022-01-06T02:24:54-05:00 Use primOpIds cache more often (#20857) Use primOpId instead of mkPrimOpId in a few places to benefit from Id caching. I had to mess a little bit with the module hierarchy to fix cycles and to avoid adding too many new dependencies to count-deps tests. - - - - - f7fc62e2 by Greg Steuck at 2022-01-06T07:56:22-05:00 Disable T2615 on OpenBSD, close #20869 - - - - - 978ea35e by Greg Steuck at 2022-01-06T07:57:00-05:00 Change ulimit -n in openFile008 back to 1024 The test only wants 1000 descriptors, so changing the limit to double that *in the context of just this test* makes no sense. This is a manual revert of 8f7194fae23bdc6db72fc5784933f50310ce51f9. The justification given in the description doesn't instill confidence. As of HEAD, the test fails on OpenBSD where ulimit -n is hard-limited to 1024. The test suite attempts to change it to 2048, which fails. The test proceeds with the unchanged default of 512 and naturally the test program fails due to the low ulimit. The fixed test now passes. - - - - - 7b783c9d by Matthew Pickering at 2022-01-07T18:25:06-05:00 Thoughtful forcing in CoreUnfolding We noticed that the structure of CoreUnfolding could leave double the amount of CoreExprs which were retained in the situation where the template but not all the predicates were forced. This observation was then confirmed using ghc-debug: ``` (["ghc:GHC.Core:App","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 237) (["ghc:GHC.Core:App","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 1) (["ghc:GHC.Core:Case","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 12) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","BLACKHOLE"],Count 1) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 78) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","THUNK_1_0","ghc-prim:GHC.Types:False","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","THUNK_1_0","THUNK_1_0"],Count 3) (["ghc:GHC.Core:Cast","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","BLACKHOLE"],Count 31) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 4307) (["ghc:GHC.Core:Lam","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 6) (["ghc:GHC.Core:Let","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 29) (["ghc:GHC.Core:Lit","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","ghc-prim:GHC.Types:True"],Count 1) (["ghc:GHC.Core:Tick","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 36) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","THUNK_1_0","THUNK_1_0","THUNK_1_0"],Count 1) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","THUNK_1_0","THUNK_1_0"],Count 6) (["ghc:GHC.Core:Var","ghc-prim:GHC.Types:True","ghc-prim:GHC.Types:False","ghc-prim:GHC.Types:True","THUNK_1_0"],Count 2) ``` Where we can see that the first argument is forced but there are still thunks remaining which retain the old expr. For my test case (a very big module, peak of 3 000 000 core terms) this reduced peak memory usage by 1G (12G -> 11G). Fixes #20905 - - - - - f583eb8e by Joachim Breitner at 2022-01-07T18:25:41-05:00 Remove dangling references to Note [Type-checking overloaded labels] that note was removed in 4196969c53c55191e644d9eb258c14c2bc8467da - - - - - 2b6c2179 by Matthew Pickering at 2022-01-11T19:37:45-05:00 hadrian: Add bootstrap scripts for building without cabal-install These scripts are originally from the cabal-install repo with a few small tweaks. This utility allows you to build hadrian without cabal-install, which can be useful for packagers. If you are a developer then build hadrian using cabal-install. If you want to bootstrap with ghc-8.10.5 then run the ./bootstrap script with the `plan-bootstrap-8.10.5.json` file. bootstrap.py -d plan-bootstrap-8.10.5.json -w /path/to-ghc The result of the bootstrap script will be a hadrian binary in `_build/bin/hadrian`. There is a script (using nix) which can be used to generate the bootstrap plans for the range of supported GHC versions using nix. generate_bootstrap_plans Otherwise you can run the commands in ./generate_bootstrap_plans directly. Fixes #17103 - - - - - a8fb4251 by Zubin Duggal at 2022-01-11T19:37:45-05:00 hadrian: allow offline bootstrapping This patch adds the ability to fetch and store dependencies needed for boostrapping hadrian. By default the script will download the dependencies from the network but some package managers disallow network access so there are also options to build given a supplied tarball. The -s option allos you to provide the tarball bootstrap.py -d plan-bootstrap-8.10.5.json -w /path/to-ghc -s sources-tarball.tar.gz Which dependencies you need can be queried using the `list-sources` option. bootstrap.py list-sources -d plan-bootstrap-8.10.5.json This produces `fetch_plan.json` which tells you where to get each source from. You can instruct the script to create the tarball using the `fetch` option. bootstrap.py fetch -d plan-bootstrap-8.10.5.json -o sources-tarball.tar.gz Together these commands mean you can build GHC without needing cabal-install. Fixes #17103 - - - - - 02cf4bc6 by Zubin Duggal at 2022-01-11T19:37:45-05:00 hadrian: Fully implement source distributions (#19317) We use `git ls-files` to get the list of files to include in the source distribution. Also implements the `-testsuite` and `-extra-tarballs` distributions. - - - - - 85473a09 by Zubin Duggal at 2022-01-11T19:37:45-05:00 ci: test bootstrapping and use hadrian for source dists - - - - - 759f3421 by Matthew Pickering at 2022-01-11T19:38:21-05:00 ci: Nightly, run one head.hackage job with core-lint and one without This fixes serious skew in the performance numbers because the packages were build with core-lint. Fixes #20826 - - - - - 6737c8e1 by Ben Gamari at 2022-01-11T19:38:56-05:00 rts: Depend explicitly on libc As noted in #19029, currently `ghc-prim` explicitly lists `libc` in `extra-libraries`, resulting in incorrect link ordering with the `extra-libraries: pthread` in `libHSrts`. Fix this by adding an explicit dependency on `libc` to `libHSrts`. Closes #19029. - - - - - 247cd336 by Ben Gamari at 2022-01-11T19:39:32-05:00 rts: Only declare environ when necessary Previously we would unconditionally provide a declaration for `environ`, even if `<unistd.h>` already provided one. This would result in `-Werror` builds failing on some platforms. Also `#include <unistd.h>` to ensure that the declaration is visible. Fixes #20861. - - - - - b65e7274 by Greg Steuck at 2022-01-11T19:40:10-05:00 Skip T18623 on OpenBSD The bug it regresses didn't happen on this OS (no RLIMIT_AS) and the regression doesn't work (ulimit: -v: unknown option) - - - - - c6300cb3 by Greg Steuck at 2022-01-11T19:40:50-05:00 Skip T16180 on OpenBSD due to bug #14012 - - - - - addf8e54 by sheaf at 2022-01-11T19:41:28-05:00 Kind TyCons: require KindSignatures, not DataKinds Uses of a TyCon in a kind signature required users to enable DataKinds, which didn't make much sense, e.g. in type U = Type type MyMaybe (a :: U) = MyNothing | MyJust a Now the DataKinds error is restricted to data constructors; the use of kind-level type constructors is instead gated behind -XKindSignatures. This patch also adds a convenience pattern synonym for patching on both a TyCon or a TcTyCon stored in a TcTyThing, used in tcTyVar and tc_infer_id. fixes #20873 - - - - - 34d8bc24 by sheaf at 2022-01-11T19:42:07-05:00 Fix parsing & printing of unboxed sums The pretty-printing of partially applied unboxed sums was incorrect, as we incorrectly dropped the first half of the arguments, even for a partial application such as (# | #) @IntRep @DoubleRep Int# which lead to the nonsensical (# DoubleRep | Int# #). This patch also allows users to write unboxed sum type constructors such as (# | #) :: TYPE r1 -> TYPE r2 -> TYPE (SumRep '[r1,r2]). Fixes #20858 and #20859. - - - - - 49731fed by sheaf at 2022-01-11T19:42:46-05:00 TcPlugins: `newWanted` uses the provided `CtLoc` The `GHC.Tc.Plugin.newWanted` function takes a `CtLoc` as an argument, but it used to discard the location information, keeping only the `CtOrigin`. It would then retrieve the source location from the `TcM` environment using `getCtLocM`. This patch changes this so that `GHC.Tc.Plugin.newWanted` passes on the full `CtLoc`. This means that authors of type-checking plugins no longer need to manually set the `CtLoc` environment in the `TcM` monad if they want to create a new Wanted constraint with the given `CtLoc` (in particular, for setting the `SrcSpan` of an emitted constraint). This makes the `newWanted` function consistent with `newGiven`, which always used the full `CtLoc` instead of using the environment. Fixes #20895 - - - - - 23d215fc by Krzysztof Gogolewski at 2022-01-11T19:43:22-05:00 warnPprTrace: pass separately the reason This makes it more similar to pprTrace, pprPanic etc. - - - - - 833216a3 by Matthew Pickering at 2022-01-11T19:43:57-05:00 Use interactive flags when printing expressions in GHCi The documentation states that the interactive flags should be use for any interactive expressions. The interactive flags are used when typechecking these expressions but not when printing. The session flags (modified by :set) are only used when loading a module. Fixes #20909 - - - - - 19b13698 by Matthew Pickering at 2022-01-11T19:43:57-05:00 Enable :seti in a multi component repl Part of #20889 - - - - - 7ca43a3f by Matthew Pickering at 2022-01-11T19:44:33-05:00 Change assertions in Stats.c to warnings (and introduce WARN macro) ASSERT should be used in situations where something very bad will happen later on if a certain invariant doesn't hold. The idea is that IF we catch the assertion earlier then it will be easier to work out what's going on at that point rather than at some indeterminate point in the future of the program. The assertions in Stats.c do not obey this philsophy and it is quite annoying if you are running a debug build (or a ticky compiler) and one of these assertions fails right at the end of your program, before the ticky report is printed out so you don't get any profiling information. Given that nothing terrible happens if these assertions are not true, or at least the terrible thing will happen in very close proximity to the assertion failure, these assertions use the new WARN macro which prints the assertion failure to stdout but does not exit the program. Of course, it would be better to fix these metrics to not trigger the assertion in the first place but if they did fail again in the future it is frustrating to be bamboozled in this manner. Fixes #20899 - - - - - e505dbd3 by Greg Steuck at 2022-01-11T19:45:11-05:00 Remove from error the parenthesized amount of memory requested Diagnostics for outofmem test on OpenBSD includes the amount of memory that it failed to allocate. This seems like an irrelevant detail that could change over time and isn't required for determining if test passed. Typical elided text is '(requested 2148532224 bytes)' - - - - - 7911aaa9 by Greg Steuck at 2022-01-11T19:45:50-05:00 Feed /dev/null into cgrun025 The test currently times out waiting for end of stdin in getContents. The expected output indicates that nothing should come for the test to pass as written. It is unclear how the test was supposed to pass, but this looks like a sufficient hack to make it work. - - - - - ed39d15c by Greg Steuck at 2022-01-11T19:46:28-05:00 Disable keep-cafs{,-fail} tests on OpenBSD They are likely broken for the same reason as FreeBSD where the tests are already disabled. - - - - - 35bea01b by Peter Trommler at 2022-01-11T19:47:04-05:00 RTS: Remove unused file xxhash.c - - - - - c2099059 by Matthew Pickering at 2022-01-11T19:47:39-05:00 RTTI: Substitute the [rk] skolems into kinds (Fixes #10616 and #10617) Co-authored-by: Roland Senn <rsx at bluewin.ch> - - - - - 92f3e6e4 by Matthew Pickering at 2022-01-11T19:48:15-05:00 docs: MonadComprehension desugar using Alternative rather than MonadPlus Fixes #20928 - - - - - 7b0c9384 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Abstract BangOpts Avoid requiring to pass DynFlags to mkDataConRep/buildDataCon. When we load an interface file, these functions don't use the flags. This is preliminary work to decouple the loader from the type-checker for #14335. - - - - - a31ace56 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Untangled GHC.Types.Id.Make from the driver - - - - - 81a8f7a7 by Zubin Duggal at 2022-01-12T23:26:24-05:00 testsuite: Fix import on python 3.10 - - - - - 66831b94 by Ben Gamari at 2022-01-13T14:50:13-05:00 hadrian: Include bash completion script in bindist See #20802. - - - - - be33d61a by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to CPR analysis - - - - - c2a6c3eb by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to Demand analysis - - - - - 9ccc445a by Eric Lindblad at 2022-01-14T10:35:46-05:00 add NUMJOBS - - - - - 564b89ae by Eric Lindblad at 2022-01-14T10:35:46-05:00 Revert "add NUMJOBS" This reverts commit c0b854e929f82c680530e944e12fad24f9e14f8e - - - - - 2dfc268c by Eric Lindblad at 2022-01-14T10:35:46-05:00 update URLs - - - - - 1aace894 by Eric Lindblad at 2022-01-14T10:35:46-05:00 reinsert target - - - - - 52a4f5ab by Andreas Klebinger at 2022-01-14T10:36:21-05:00 Add test for #20938. - - - - - e2b60be8 by Ben Gamari at 2022-01-15T03:41:16-05:00 rts: Consolidate RtsSymbols from libc Previously (9ebda74ec5331911881d734b21fbb31c00a0a22f) `environ` was added to `RtsSymbols` to ensure that environment was correctly propagated when statically linking. However, this introduced #20577 since platforms are inconsistent in whether they provide a prototype for `environ`. I fixed this by providing a prototype but while doing so dropped symbol-table entry, presumably thinking that it was redundant due to the entry in the mingw-specific table. Here I reintroduce the symbol table entry for `environ` and move libc symbols shared by Windows and Linux into a new macro, `RTS_LIBC_SYMBOLS`, avoiding this potential confusion. - - - - - 0dc72395 by Tamar Christina at 2022-01-15T03:41:55-05:00 winio: fix heap corruption and various leaks. - - - - - 4031ef62 by Eric Lindblad at 2022-01-15T20:11:55+00:00 wikipedia link - - - - - a13aff98 by Eric Lindblad at 2022-01-17T08:25:51-05:00 ms link - - - - - f161e890 by sheaf at 2022-01-17T14:52:50+00:00 Use diagnostic infrastructure in GHC.Tc.Errors - - - - - 18c797b8 by Jens Petersen at 2022-01-18T16:12:14-05:00 hadrian BinaryDist: version ghc in ghciScriptWrapper like we do for the non-Hadrian wrapper script. Otherwise if $bindir/ghc is a different ghc version then versioned ghci will incorrectly run the other ghc version instead. (Normally this would only happen if there are parallel ghc versions installed in bindir.) All the other wrapper scripts already have versioned executablename - - - - - 310424d0 by Matthew Pickering at 2022-01-18T16:12:50-05:00 Correct type of static forms in hsExprType The simplest way to do this seemed to be to persist the whole type in the extension field from the typechecker so that the few relevant places * Desugaring can work out the return type by splitting this type rather than calling `dsExpr` (slightly more efficient). * hsExprType can just return the correct type. * Zonking has to now zonk the type as well The other option we considered was wiring in StaticPtr but that is actually quite tricky because StaticPtr refers to StaticPtrInfo which has field selectors (which we can't easily wire in). Fixes #20150 - - - - - 7ec783de by Matthew Pickering at 2022-01-18T16:12:50-05:00 Add test for using type families with static pointers Issue was reported on #13306 - - - - - 2d205154 by Sebastian Graf at 2022-01-18T16:13:25-05:00 Stricten the Strict State monad I found it weird that most of the combinators weren't actually strict. Making `pure` strict in the state should hopefully give Nested CPR an easier time to unbox the nested state. - - - - - 5a6efd21 by Ben Gamari at 2022-01-18T16:14:01-05:00 rts/winio: Fix #18382 Here we refactor WinIO's IO completion scheme, squashing a memory leak and fixing #18382. To fix #18382 we drop the special thread status introduced for IoPort blocking, BlockedOnIoCompletion, as well as drop the non-threaded RTS's special dead-lock detection logic (which is redundant to the GC's deadlock detection logic), as proposed in #20947. Previously WinIO relied on foreign import ccall "wrapper" to create an adjustor thunk which can be attached to the OVERLAPPED structure passed to the operating system. It would then use foreign import ccall "dynamic" to back out the original continuation from the adjustor. This roundtrip is significantly more expensive than the alternative, using a StablePtr. Furthermore, the implementation let the adjustor leak, meaning that every IO request would leak a page of memory. Fixes T18382. - - - - - 01254ceb by Matthew Pickering at 2022-01-18T16:14:37-05:00 Add note about heap invariant Closed #20904 - - - - - 21510698 by Sergey Vinokurov at 2022-01-18T16:15:12-05:00 Improve detection of lld linker Newer lld versions may include vendor info in --version output and thus the version string may not start with ‘LLD’. Fixes #20907 - - - - - 95e7964b by Peter Trommler at 2022-01-18T20:46:08-05:00 Fix T20638 on big-endian architectures The test reads a 16 bit value from an array of 8 bit values. Naturally, that leads to different values read on big-endian architectures than on little-endian. In this case the value read is 0x8081 on big-endian and 0x8180 on little endian. This patch changes the argument of the `and` machop to mask bit 7 which is the only bit different. The test still checks that bit 15 is zero, which was the original issue in #20638. Fixes #20906. - - - - - fd0019a0 by Eric Lindblad at 2022-01-18T20:46:48-05:00 ms and gh links - - - - - 85dc61ee by Zubin Duggal at 2022-01-18T20:47:23-05:00 ci: Fix subtlety with not taking effect because of time_it (#20898) - - - - - 592e4113 by Anselm Schüler at 2022-01-19T13:31:49-05:00 Note that ImpredicativeTypes doesn’t allow polymorphic instances See #20939 - - - - - 3b009e1a by Ben Gamari at 2022-01-19T13:32:25-05:00 base: Add CTYPE pragmas to all foreign types Fixes #15531 by ensuring that we know the corresponding C type for all marshalling wrappers. Closes #15531. - - - - - 516eeb9e by Robert Hensing at 2022-01-24T21:28:24-05:00 Add -fcompact-unwind This gives users the choice to enable __compact_unwind sections when linking. These were previously hardcoded to be removed. This can be used to solved the problem "C++ does not catch exceptions when used with Haskell-main and linked by ghc", https://gitlab.haskell.org/ghc/ghc/-/issues/11829 It does not change the default behavior, because I can not estimate the impact this would have. When Apple first introduced the compact unwind ABI, a number of open source projects have taken the easy route of disabling it, avoiding errors or even just warnings shortly after its introduction. Since then, about a decade has passed, so it seems quite possible that Apple itself, and presumably many programs with it, have successfully switched to the new format, to the point where the old __eh_frame section support is in disrepair. Perhaps we should get along with the program, but for now we can test the waters with this flag, and use it to fix packages that need it. - - - - - 5262b1e5 by Robert Hensing at 2022-01-24T21:28:24-05:00 Add test case for C++ exception handling - - - - - a5c94092 by Sebastian Graf at 2022-01-24T21:29:00-05:00 Write Note [Strict State monad] to explain what G.U.M.State.Strict does As requested by Simon after review of !7342. I also took liberty to define the `Functor` instance by hand, as the derived one subverts the invariants maintained by the pattern synonym (as already stated in `Note [The one-shot state monad trick]`). - - - - - 9b0d56d3 by Eric Lindblad at 2022-01-24T21:29:38-05:00 links - - - - - 4eac8e72 by Ben Gamari at 2022-01-24T21:30:13-05:00 ghc-heap: Drop mention of BlockedOnIOCompletion Fixes bootstrap with GHC 9.0 after 5a6efd218734dbb5c1350531680cd3f4177690f1 - - - - - 7d7b9a01 by Ryan Scott at 2022-01-24T21:30:49-05:00 Hadrian: update the index-state to allow building with GHC 9.0.2 Fixes #20984. - - - - - aa50e118 by Peter Trommler at 2022-01-24T21:31:25-05:00 testsuite: Mark test that require RTS linker - - - - - 871ce2a3 by Matthew Pickering at 2022-01-25T17:27:30-05:00 ci: Move (most) deb9 jobs to deb10 deb9 is now end-of-life so we are dropping support for producing bindists. - - - - - 9d478d51 by Ryan Scott at 2022-01-25T17:28:06-05:00 DeriveGeneric: look up datacon fixities using getDataConFixityFun Previously, `DeriveGeneric` would look up the fixity of a data constructor using `getFixityEnv`, but this is subtly incorrect for data constructors defined in external modules. This sort of situation can happen with `StandaloneDeriving`, as noticed in #20994. In fact, the same bug has occurred in the past in #9830, and while that bug was fixed for `deriving Read` and `deriving Show`, the fix was never extended to `DeriveGeneric` due to an oversight. This patch corrects that oversight. Fixes #20994. - - - - - 112e9e9e by Zubin Duggal at 2022-01-25T17:28:41-05:00 Fix Werror on alpine - - - - - 781323a3 by Matthew Pickering at 2022-01-25T17:29:17-05:00 Widen T12545 acceptance window This test has been the scourge of contributors for a long time. It has caused many failed CI runs and wasted hours debugging a test which barely does anything. The fact is does nothing is the reason for the flakiness and it's very sensitive to small changes in initialisation costs, in particular adding wired-in things can cause this test to fluctuate quite a bit. Therefore we admit defeat and just bump the threshold up to 10% to catch very large regressions but otherwise don't care what this test does. Fixes #19414 - - - - - e471a680 by sheaf at 2022-01-26T12:01:45-05:00 Levity-polymorphic arrays and mutable variables This patch makes the following types levity-polymorphic in their last argument: - Array# a, SmallArray# a, Weak# b, StablePtr# a, StableName# a - MutableArray# s a, SmallMutableArray# s a, MutVar# s a, TVar# s a, MVar# s a, IOPort# s a The corresponding primops are also made levity-polymorphic, e.g. `newArray#`, `readArray#`, `writeMutVar#`, `writeIOPort#`, etc. Additionally, exception handling functions such as `catch#`, `raise#`, `maskAsyncExceptions#`,... are made levity/representation-polymorphic. Now that Array# and MutableArray# also work with unlifted types, we can simply re-define ArrayArray# and MutableArrayArray# in terms of them. This means that ArrayArray# and MutableArrayArray# are no longer primitive types, but simply unlifted newtypes around Array# and MutableArrayArray#. This completes the implementation of the Pointer Rep proposal https://github.com/ghc-proposals/ghc-proposals/pull/203 Fixes #20911 ------------------------- Metric Increase: T12545 ------------------------- ------------------------- Metric Decrease: T12545 ------------------------- - - - - - 6e94ba54 by Andreas Klebinger at 2022-01-26T12:02:21-05:00 CorePrep: Don't try to wrap partial applications of primops in profiling ticks. This fixes #20938. - - - - - b55d7db3 by sheaf at 2022-01-26T12:03:01-05:00 Ensure that order of instances doesn't matter The insert_overlapping used in lookupInstEnv used to return different results depending on the order in which instances were processed. The problem was that we could end up discarding an overlapping instance in favour of a more specific non-overlapping instance. This is a problem because, even though we won't choose the less-specific instance for matching, it is still useful for pruning away other instances, because it has the overlapping flag set while the new instance doesn't. In insert_overlapping, we now keep a list of "guard" instances, which are instances which are less-specific that one that matches (and hence which we will discard in the end), but want to keep around solely for the purpose of eliminating other instances. Fixes #20946 - - - - - 61f62062 by sheaf at 2022-01-26T12:03:40-05:00 Remove redundant SOURCE import in FitTypes Fixes #20995 - - - - - e8405829 by sheaf at 2022-01-26T12:04:15-05:00 Fix haddock markup in GHC.Tc.Errors.Types - - - - - 590a2918 by Simon Peyton Jones at 2022-01-26T19:45:22-05:00 Make RULE matching insensitive to eta-expansion This patch fixes #19790 by making the rule matcher do on-the-fly eta reduction. See Note [Eta reduction the target] in GHC.Core.Rules I found I also had to careful about casts when matching; see Note [Casts in the target] and Note [Casts in the template] Lots more comments and Notes in the rule matcher - - - - - c61ac4d8 by Matthew Pickering at 2022-01-26T19:45:58-05:00 alwaysRerun generation of ghcconfig This file needs to match exactly what is passed as the testCompiler. Before this change the settings for the first compiler to be tested woudl be stored and not regenerated if --test-compiler changed. - - - - - b5132f86 by Matthew Pickering at 2022-01-26T19:45:58-05:00 Pass config.stage argument to testsuite - - - - - 83d3ad31 by Zubin Duggal at 2022-01-26T19:45:58-05:00 hadrian: Allow testing of the stage1 compiler (#20755) - - - - - a5924b38 by Joachim Breitner at 2022-01-26T19:46:34-05:00 Simplifier: Do the right thing if doFloatFromRhs = False If `doFloatFromRhs` is `False` then the result from `prepareBinding` should not be used. Previously it was in ways that are silly (but not completly wrong, as the simplifier would clean that up again, so no test case). This was spotted by Simon during a phone call. Fixes #20976 - - - - - ce488c2b by Simon Peyton Jones at 2022-01-26T19:47:09-05:00 Better occurrence analysis with casts This patch addresses #20988 by refactoring the way the occurrence analyser deals with lambdas. Previously it used collectBinders to split off a group of binders, and deal with them together. Now I deal with them one at a time in occAnalLam, which allows me to skip casts easily. See Note [Occurrence analysis for lambda binders] about "lambda-groups" This avoidance of splitting out a list of binders has some good consequences. Less code, more efficient, and I think, more clear. The Simplifier needed a similar change, now that lambda-groups can inlude casts. It turned out that I could simplify the code here too, in particular elminating the sm_bndrs field of StrictBind. Simpler, more efficient. Compile-time metrics improve slightly; here are the ones that are +/- 0.5% or greater: Baseline Test Metric value New value Change -------------------------------------------------------------------- T11303b(normal) ghc/alloc 40,736,702 40,543,992 -0.5% T12425(optasm) ghc/alloc 90,443,459 90,034,104 -0.5% T14683(normal) ghc/alloc 2,991,496,696 2,956,277,288 -1.2% T16875(normal) ghc/alloc 34,937,866 34,739,328 -0.6% T17977b(normal) ghc/alloc 37,908,550 37,709,096 -0.5% T20261(normal) ghc/alloc 621,154,237 618,312,480 -0.5% T3064(normal) ghc/alloc 190,832,320 189,952,312 -0.5% T3294(normal) ghc/alloc 1,604,674,178 1,604,608,264 -0.0% T5321FD(normal) ghc/alloc 270,540,489 251,888,480 -6.9% GOOD T5321Fun(normal) ghc/alloc 300,707,814 281,856,200 -6.3% GOOD WWRec(normal) ghc/alloc 588,460,916 585,536,400 -0.5% geo. mean -0.3% Metric Decrease: T5321FD T5321Fun - - - - - 4007905d by Roland Senn at 2022-01-26T19:47:47-05:00 Cleanup tests in directory ghci.debugger. Fixes #21009 * Remove wrong comment about panic in `break003.script`. * Improve test `break008`. * Add test `break028` to `all.T` * Fix wrong comments in `print019.script`, `print026.script` and `result001.script`. * Remove wrong comments from `print024.script` and `print031.script`. * Replace old module name with current name in `print035.script`. - - - - - 3577defb by Matthew Pickering at 2022-01-26T19:48:22-05:00 ci: Move source-tarball and test-bootstrap into full-build - - - - - 6e09b3cf by Matthew Pickering at 2022-01-27T02:39:35-05:00 ci: Add ENABLE_NUMA flag to explicitly turn on libnuma dependency In recent releases a libnuma dependency has snuck into our bindists because the images have started to contain libnuma. We now explicitly pass `--disable-numa` to configure unless explicitly told not to by using the `ENABLE_NUMA` environment variable. So this is tested, there is one random validate job which builds with --enable-numa so that the code in the RTS is still built. Fixes #20957 and #15444 - - - - - f4ce4186 by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Improve partial signatures As #20921 showed, with partial signatures, it is helpful to use the same algorithm (namely findInferredDiff) for * picking the constraints to retain for the /group/ in Solver.decideQuantification * picking the contraints to retain for the /individual function/ in Bind.chooseInferredQuantifiers This is still regrettably declicate, but it's a step forward. - - - - - 0573aeab by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Add an Outputable instance for RecTcChecker - - - - - f0adea14 by Ryan Scott at 2022-01-27T02:40:47-05:00 Expand type synonyms in markNominal `markNominal` is repsonsible for setting the roles of type variables that appear underneath an `AppTy` to be nominal. However, `markNominal` previously did not expand type synonyms, so in a data type like this: ```hs data M f a = MkM (f (T a)) type T a = Int ``` The `a` in `M f a` would be marked nominal, even though `T a` would simply expand to `Int`. The fix is simple: call `coreView` as appropriate in `markNominal`. This is much like the fix for #14101, but in a different spot. Fixes #20999. - - - - - 18df4013 by Simon Peyton Jones at 2022-01-27T08:22:30-05:00 Define and use restoreLclEnv This fixes #20981. See Note [restoreLclEnv vs setLclEnv] in GHC.Tc.Utils.Monad. I also use updLclEnv rather than get/set when I can, because it's then much clearer that it's an update rather than an entirely new TcLclEnv coming from who-knows-where. - - - - - 31088dd3 by David Feuer at 2022-01-27T08:23:05-05:00 Add test supplied in T20996 which uses data family result kind polymorphism David (@treeowl) writes: > Following @kcsongor, I've used ridiculous data family result kind > polymorphism in `linear-generics`, and am currently working on getting > it into `staged-gg`. If it should be removed, I'd appreciate a heads up, > and I imagine Csongor would too. > > What do I need by ridiculous polymorphic result kinds? Currently, data > families are allowed to have result kinds that end in `Type` (or maybe > `TYPE r`? I'm not sure), but not in concrete data kinds. However, they > *are* allowed to have polymorphic result kinds. This leads to things I > think most of us find at least quite *weird*. For example, I can write > > ```haskell > data family Silly :: k > data SBool :: Bool -> Type where > SFalse :: SBool False > STrue :: SBool True > SSSilly :: SBool Silly > type KnownBool b where > kb :: SBool b > instance KnownBool False where kb = SFalse > instance KnownBool True where kb = STrue > instance KnownBool Silly where kb = Silly > ``` > > Basically, every kind now has potentially infinitely many "legit" inhabitants. > > As horrible as that is, it's rather useful for GHC's current native > generics system. It's possible to use these absurdly polymorphic result > kinds to probe the structure of generic representations in a relatively > pleasant manner. It's a sort of "formal type application" reminiscent of > the notion of a formal power series (see the test case below). I suspect > a system more like `kind-generics` wouldn't need this extra probing > power, but nothing like that is natively available as yet. > > If the ridiculous result kind polymorphism is banished, we'll still be > able to do what we need as long as we have stuck type families. It's > just rather less ergonomical: a stuck type family has to be used with a > concrete marker type argument. Closes #20996 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 8fd2ac25 by Andreas Abel at 2022-01-27T18:34:54-05:00 Whitespace only - - - - - 7a854743 by Andreas Abel at 2022-01-27T18:34:54-05:00 Ctd. #18087: complete :since: info for all warnings in users guide Some warnings have been there "forever" and I could not trace back the exact genesis, so I wrote "since at least 5.04". The flag `helpful-errors` could have been added in 7.2 already. I wrote 7.4 since I have no 7.2 available and it is not recognized by 7.0. - - - - - f75411e8 by Andreas Abel at 2022-01-27T18:34:54-05:00 Re #18087 user's guide: add a note that -Wxxx used to be -fwarn-xxx The warning option syntax -W was introduced in GHC 8. The note should clarify what e.g. "since 7.6" means in connection with "-Wxxx": That "-fwarn-xxx" was introduced in 7.6.1. [ci skip] - - - - - 3cae7fde by Peter Trommler at 2022-01-27T18:35:30-05:00 testsuite: Fix AtomicPrimops test on big endian - - - - - 6cc6080c by Ben Gamari at 2022-01-27T18:36:05-05:00 users-guide: Document GHC_CHARENC environment variable As noted in #20963, this was introduced in 1b56c40578374a15b4a2593895710c68b0e2a717 but was no documentation was added at that point. Closes #20963. - - - - - ee21e2de by Ben Gamari at 2022-01-27T18:36:41-05:00 rts: Clean up RTS flags usage message Align flag descriptions and acknowledge that some flags may not be available unless the user linked with `-rtsopts` (as noted in #20961). Fixes #20961. - - - - - 7f8ce19e by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Fix getHasGivenEqs The second component is supposed to be "insoluble equalities arising from givens". But we were getting wanteds too; and that led to an outright duplication of constraints. It's not harmful, but it's not right either. I came across this when debugging something else. Easily fixed. - - - - - f9ef2d26 by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Set the TcLclEnv when solving a ForAll constraint Fix a simple omission in GHC.Tc.Solver.Canonical.solveForAll, where we ended up with the wrong TcLclEnv captured in an implication. Result: unhelpful error message (#21006) - - - - - bc6ba8ef by Sylvain Henry at 2022-01-28T12:14:41-05:00 Make most shifts branchless - - - - - 62a6d037 by Simon Peyton Jones at 2022-01-28T12:15:17-05:00 Improve boxity in deferAfterPreciseException As #20746 showed, the demand analyser behaved badly in a key I/O library (`GHC.IO.Handle.Text`), by unnessarily boxing and reboxing. This patch adjusts the subtle function deferAfterPreciseException; it's quite easy, just a bit subtle. See the new Note [deferAfterPreciseException] And this MR deals only with Problem 2 in #20746. Problem 1 is still open. - - - - - 42c47cd6 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/trace: Shrink tracing flags - - - - - cee66e71 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/EventLog: Mark various internal globals as static - - - - - 6b0cea29 by Ben Gamari at 2022-01-29T02:40:45-05:00 Propagate PythonCmd to make build system - - - - - 2e29edb7 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts: Refactor event types Previously we would build the eventTypes array at runtime during RTS initialization. However, this is completely unnecessary; it is completely static data. - - - - - bb15c347 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/eventlog: Ensure that flushCount is initialized - - - - - 268efcc9 by Matthew Pickering at 2022-01-29T02:41:21-05:00 Rework the handling of SkolemInfo The main purpose of this patch is to attach a SkolemInfo directly to each SkolemTv. This fixes the large number of bugs which have accumulated over the years where we failed to report errors due to having "no skolem info" for particular type variables. Now the origin of each type varible is stored on the type variable we can always report accurately where it cames from. Fixes #20969 #20732 #20680 #19482 #20232 #19752 #10946 #19760 #20063 #13499 #14040 The main changes of this patch are: * SkolemTv now contains a SkolemInfo field which tells us how the SkolemTv was created. Used when reporting errors. * Enforce invariants relating the SkolemInfoAnon and level of an implication (ic_info, ic_tclvl) to the SkolemInfo and level of the type variables in ic_skols. * All ic_skols are TcTyVars -- Check is currently disabled * All ic_skols are SkolemTv * The tv_lvl of the ic_skols agrees with the ic_tclvl * The ic_info agrees with the SkolInfo of the implication. These invariants are checked by a debug compiler by checkImplicationInvariants. * Completely refactor kcCheckDeclHeader_sig which kept doing my head in. Plus, it wasn't right because it wasn't skolemising the binders as it decomposed the kind signature. The new story is described in Note [kcCheckDeclHeader_sig]. The code is considerably shorter than before (roughly 240 lines turns into 150 lines). It still has the same awkward complexity around computing arity as before, but that is a language design issue. See Note [Arity inference in kcCheckDeclHeader_sig] * I added new type synonyms MonoTcTyCon and PolyTcTyCon, and used them to be clear which TcTyCons have "finished" kinds etc, and which are monomorphic. See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] * I renamed etaExpandAlgTyCon to splitTyConKind, becuase that's a better name, and it is very useful in kcCheckDeclHeader_sig, where eta-expansion isn't an issue. * Kill off the nasty `ClassScopedTvEnv` entirely. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 0a1d0944 by Ben Gamari at 2022-01-29T14:52:55-05:00 Drop SPARC NCG - - - - - 313afb3d by Ben Gamari at 2022-01-29T14:52:56-05:00 A few comment cleanups - - - - - d85a527f by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out SPARC register support - - - - - c6bede69 by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Rip out SPARC support - - - - - a67c2471 by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out remaining SPARC support - - - - - 5771b690 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop RegPair SPARC was its last and only user. - - - - - 512ed3f1 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Make RealReg a newtype Now that RegPair is gone we no longer need to pay for the additional box. - - - - - 88fea6aa by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Drop redundant #include <Arena.h> - - - - - ea2a4034 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop ncgExpandTop This was only needed for SPARC's synthetic instructions. - - - - - 88fce740 by Ben Gamari at 2022-01-29T14:54:04-05:00 rel-notes: Note dropping of SPARC support - - - - - eb956cf1 by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Force-enable caret diagnostics in T17786 Otherwise GHC realizes that it's not attached to a proper tty and will disable caret diagnostics. - - - - - d07799ab by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Make T7275 more robust against CCid changes The cost-center numbers are somewhat unstable; normalise them out. - - - - - c76c8050 by Ben Gamari at 2022-01-30T06:27:19-05:00 rts: Don't allocate closurePtrs# pointers on C stack Previously `closurePtrs#` would allocate an aray of the size of the closure being decoded on the C stack. This was ripe for overflowing the C stack overflow. This resulted in `T12492` failing on Windows. - - - - - 3af95f7a by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite/T4029: Don't depend on echo On Windows the `cmd.exe` shell may be used to execute the command, which will print `ECHO is on.` instead of a newline if you give it no argument. Avoid this by rather using `printf`. - - - - - 3531c478 by Ben Gamari at 2022-01-30T06:27:19-05:00 Use PATH_FMT instead of %s to format `pathchar *` A few %s occurrences have snuck in over the past months. - - - - - ee5c4f9d by Zubin Duggal at 2022-01-31T16:51:55+05:30 Improve migration strategy for the XDG compliance change to the GHC application directory. We want to always use the old path (~/.ghc/..) if it exists. But we never want to create the old path. This ensures that the migration can eventually be completed once older GHC versions are no longer in circulation. Fixes #20684, #20669, #20660 - - - - - 60a54a8f by doyougnu at 2022-01-31T18:46:11-05:00 StgToCmm: decouple DynFlags, add StgToCmmConfig StgToCmm: add Config, remove CgInfoDownwards StgToCmm: runC api change to take StgToCmmConfig StgToCmm: CgInfoDownad -> StgToCmmConfig StgToCmm.Monad: update getters/setters/withers StgToCmm: remove CallOpts in StgToCmm.Closure StgToCmm: remove dynflag references StgToCmm: PtrOpts removed StgToCmm: add TMap to config, Prof - dynflags StgToCmm: add omit yields to config StgToCmm.ExtCode: remove redundant import StgToCmm.Heap: remove references to dynflags StgToCmm: codeGen api change, DynFlags -> Config StgToCmm: remove dynflags in Env and StgToCmm StgToCmm.DataCon: remove dynflags references StgToCmm: remove dynflag references in DataCon StgToCmm: add backend avx flags to config StgToCmm.Prim: remove dynflag references StgToCmm.Expr: remove dynflag references StgToCmm.Bind: remove references to dynflags StgToCmm: move DoAlignSanitisation to Cmm.Type StgToCmm: remove PtrOpts in Cmm.Parser.y DynFlags: update ipInitCode api StgToCmm: Config Module is single source of truth StgToCmm: Lazy config breaks IORef deadlock testsuite: bump countdeps threshold StgToCmm.Config: strictify fields except UpdFrame Strictifying UpdFrameOffset causes the RTS build with stage1 to deadlock. Additionally, before the deadlock performance of the RTS is noticeably slower. StgToCmm.Config: add field descriptions StgToCmm: revert strictify on Module in config testsuite: update CountDeps tests StgToCmm: update comment, fix exports Specifically update comment about loopification passed into dynflags then stored into stgToCmmConfig. And remove getDynFlags from Monad.hs exports Types.Name: add pprFullName function StgToCmm.Ticky: use pprFullname, fixup ExtCode imports Cmm.Info: revert cmmGetClosureType removal StgToCmm.Bind: use pprFullName, Config update comments StgToCmm: update closureDescription api StgToCmm: SAT altHeapCheck StgToCmm: default render for Info table, ticky Use default rendering contexts for info table and ticky ticky, which should be independent of command line input. testsuite: bump count deps pprFullName: flag for ticky vs normal style output convertInfoProvMap: remove unused parameter StgToCmm.Config: add backend flags to config StgToCmm.Config: remove Backend from Config StgToCmm.Prim: refactor Backend call sites StgToCmm.Prim: remove redundant imports StgToCmm.Config: refactor vec compatibility check StgToCmm.Config: add allowQuotRem2 flag StgToCmm.Ticky: print internal names with parens StgToCmm.Bind: dispatch ppr based on externality StgToCmm: Add pprTickyname, Fix ticky naming Accidently removed the ctx for ticky SDoc output. The only relevant flag is sdocPprDebug which was accidental set to False due to using defaultSDocContext without altering the flag. StgToCmm: remove stateful fields in config fixup: config: remove redundant imports StgToCmm: move Sequel type to its own module StgToCmm: proliferate getCallMethod updated api StgToCmm.Monad: add FCodeState to Monad Api StgToCmm: add second reader monad to FCode fixup: Prim.hs: missed a merge conflict fixup: Match countDeps tests to HEAD StgToCmm.Monad: withState -> withCgState To disambiguate it from mtl withState. This withState shouldn't be returning the new state as a value. However, fixing this means tackling the knot tying in CgState and so is very difficult since it changes when the thunk of the knot is forced which either leads to deadlock or to compiler panic. - - - - - 58eccdbc by Ben Gamari at 2022-01-31T18:46:47-05:00 codeGen: Fix two buglets in -fbounds-check logic @Bodigrim noticed that the `compareByteArray#` bounds-checking logic had flipped arguments and an off-by-one. For the sake of clarity I also refactored occurrences of `cmmOffset` to rather use `cmmOffsetB`. I suspect the former should be retired. - - - - - 584f03fa by Simon Peyton Jones at 2022-01-31T18:47:23-05:00 Make typechecker trace less strict Fixes #21011 - - - - - 60ac7300 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH case pprint (fixes #20893) This patch ensures that the pretty printer formats `case` statements using braces (instead of layout) to remain consistent with the formatting of other statements (like `do`) - - - - - fdda93b0 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH LambdaCase and where clauses This patch ensures that the pretty printer formats LambdaCase and where clauses using braces (instead of layout) to remain consistent with the formatting of other statements (like `do` and `case`) - - - - - 06185102 by Ben Gamari at 2022-02-01T12:29:26-05:00 Consistently upper-case "Note [" This was achieved with git ls-tree --name-only HEAD -r | xargs sed -i -e 's/note \[/Note \[/g' - - - - - 88fba8a4 by Ben Gamari at 2022-02-01T12:29:26-05:00 Fix a few Note inconsistencies - - - - - 05548a22 by Douglas Wilson at 2022-02-02T19:26:06-05:00 rts: Address failures to inline - - - - - 074945de by Simon Peyton Jones at 2022-02-02T19:26:41-05:00 Two small improvements in the Simplifier As #20941 describes, this patch implements a couple of small fixes to the Simplifier. They make a difference principally with -O0, so few people will notice. But with -O0 they can reduce the number of Simplifer iterations. * In occurrence analysis we avoid making x = (a,b) into a loop breaker because we want to be able to inline x, or (more likely) do case-elimination. But HEAD does not treat x = let y = blah in (a,b) in the same way. We should though, because we are going to float that y=blah out of the x-binding. A one-line fix in OccurAnal. * The crucial function exprIsConApp_maybe uses getUnfoldingInRuleMatch (rightly) but the latter was deeply strange. In HEAD, if rule-rewriting was off (-O0) we only looked inside stable unfoldings. Very stupid. The patch simplifies. * I also noticed that in simplStableUnfolding we were failing to delete the DFun binders from the usage. So I added that. Practically zero perf change across the board, except that we get more compiler allocation in T3064 (which is compiled with -O0). There's a good reason: we get better code. But there are lots of other small compiler allocation decreases: Metrics: compile_time/bytes allocated --------------------- Baseline Test Metric value New value Change ----------------------------------------------------------------- PmSeriesG(normal) ghc/alloc 44,260,817 44,184,920 -0.2% PmSeriesS(normal) ghc/alloc 52,967,392 52,891,632 -0.1% PmSeriesT(normal) ghc/alloc 75,498,220 75,421,968 -0.1% PmSeriesV(normal) ghc/alloc 52,341,849 52,265,768 -0.1% T10421(normal) ghc/alloc 109,702,291 109,626,024 -0.1% T10421a(normal) ghc/alloc 76,888,308 76,809,896 -0.1% T10858(normal) ghc/alloc 125,149,038 125,073,648 -0.1% T11276(normal) ghc/alloc 94,159,364 94,081,640 -0.1% T11303b(normal) ghc/alloc 40,230,059 40,154,368 -0.2% T11822(normal) ghc/alloc 107,424,540 107,346,088 -0.1% T12150(optasm) ghc/alloc 76,486,339 76,426,152 -0.1% T12234(optasm) ghc/alloc 55,585,046 55,507,352 -0.1% T12425(optasm) ghc/alloc 88,343,288 88,265,312 -0.1% T13035(normal) ghc/alloc 98,919,768 98,845,600 -0.1% T13253-spj(normal) ghc/alloc 121,002,153 120,851,040 -0.1% T16190(normal) ghc/alloc 290,313,131 290,074,152 -0.1% T16875(normal) ghc/alloc 34,756,121 34,681,440 -0.2% T17836b(normal) ghc/alloc 45,198,100 45,120,288 -0.2% T17977(normal) ghc/alloc 39,479,952 39,404,112 -0.2% T17977b(normal) ghc/alloc 37,213,035 37,137,728 -0.2% T18140(normal) ghc/alloc 79,430,588 79,350,680 -0.1% T18282(normal) ghc/alloc 128,303,182 128,225,384 -0.1% T18304(normal) ghc/alloc 84,904,713 84,831,952 -0.1% T18923(normal) ghc/alloc 66,817,241 66,731,984 -0.1% T20049(normal) ghc/alloc 86,188,024 86,107,920 -0.1% T5837(normal) ghc/alloc 35,540,598 35,464,568 -0.2% T6048(optasm) ghc/alloc 99,812,171 99,736,032 -0.1% T9198(normal) ghc/alloc 46,380,270 46,304,984 -0.2% geo. mean -0.0% Metric Increase: T3064 - - - - - d2cce453 by Morrow at 2022-02-02T19:27:21-05:00 Fix @since annotation on Nat - - - - - 6438fed9 by Simon Peyton Jones at 2022-02-02T19:27:56-05:00 Refactor the escaping kind check for data constructors As #20929 pointed out, we were in-elegantly checking for escaping kinds in `checkValidType`, even though that check was guaranteed to succeed for type signatures -- it's part of kind-checking a type. But for /data constructors/ we kind-check the pieces separately, so we still need the check. This MR is a pure refactor, moving the test from `checkValidType` to `checkValidDataCon`. No new tests; external behaviour doesn't change. - - - - - fb05e5ac by Andreas Klebinger at 2022-02-02T19:28:31-05:00 Replace sndOfTriple with sndOf3 I also cleaned up the imports slightly while I was at it. - - - - - fbc77d3a by Matthew Pickering at 2022-02-02T19:29:07-05:00 testsuite: Honour PERF_BASELINE_COMMIT when computing allowed metric changes We now get all the commits between the PERF_BASELINE_COMMIT and HEAD and check any of them for metric changes. Fixes #20882 - - - - - 0a82ae0d by Simon Peyton Jones at 2022-02-02T23:49:58-05:00 More accurate unboxing This patch implements a fix for #20817. It ensures that * The final strictness signature for a function accurately reflects the unboxing done by the wrapper See Note [Finalising boxity for demand signatures] and Note [Finalising boxity for let-bound Ids] * A much better "layer-at-a-time" implementation of the budget for how many worker arguments we can have See Note [Worker argument budget] Generally this leads to a bit more worker/wrapper generation, because instead of aborting entirely if the budget is exceeded (and then lying about boxity), we unbox a bit. Binary sizes in increase slightly (around 1.8%) because of the increase in worker/wrapper generation. The big effects are to GHC.Ix, GHC.Show, GHC.IO.Handle.Internals. If we did a better job of dropping dead code, this effect might go away. Some nofib perf improvements: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- VSD +1.8% -0.5% 0.017 0.017 0.0% awards +1.8% -0.1% +2.3% +2.3% 0.0% banner +1.7% -0.2% +0.3% +0.3% 0.0% bspt +1.8% -0.1% +3.1% +3.1% 0.0% eliza +1.8% -0.1% +1.2% +1.2% 0.0% expert +1.7% -0.1% +9.6% +9.6% 0.0% fannkuch-redux +1.8% -0.4% -9.3% -9.3% 0.0% kahan +1.8% -0.1% +22.7% +22.7% 0.0% maillist +1.8% -0.9% +21.2% +21.6% 0.0% nucleic2 +1.7% -5.1% +7.5% +7.6% 0.0% pretty +1.8% -0.2% 0.000 0.000 0.0% reverse-complem +1.8% -2.5% +12.2% +12.2% 0.0% rfib +1.8% -0.2% +2.5% +2.5% 0.0% scc +1.8% -0.4% 0.000 0.000 0.0% simple +1.7% -1.3% +17.0% +17.0% +7.4% spectral-norm +1.8% -0.1% +6.8% +6.7% 0.0% sphere +1.7% -2.0% +13.3% +13.3% 0.0% tak +1.8% -0.2% +3.3% +3.3% 0.0% x2n1 +1.8% -0.4% +8.1% +8.1% 0.0% -------------------------------------------------------------------------------- Min +1.1% -5.1% -23.6% -23.6% 0.0% Max +1.8% +0.0% +36.2% +36.2% +7.4% Geometric Mean +1.7% -0.1% +6.8% +6.8% +0.1% Compiler allocations in CI have a geometric mean of +0.1%; many small decreases but there are three bigger increases (7%), all because we do more worker/wrapper than before, so there is simply more code to compile. That's OK. Perf benchmarks in perf/should_run improve in allocation by a geo mean of -0.2%, which is good. None get worse. T12996 improves by -5.8% Metric Decrease: T12996 Metric Increase: T18282 T18923 T9630 - - - - - d1ef6288 by Peter Trommler at 2022-02-02T23:50:34-05:00 Cmm: fix equality of expressions Compare expressions and types when comparing `CmmLoad`s. Fixes #21016 - - - - - e59446c6 by Peter Trommler at 2022-02-02T23:50:34-05:00 Check type first then expression - - - - - b0e1ef4a by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add failing test for #20791 The test produces different output on static vs dynamic GHC builds. - - - - - cae1fb17 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Frontend01 passes with static GHC - - - - - e343526b by Matthew Pickering at 2022-02-03T14:44:17-05:00 Don't initialise plugins when there are no pipelines to run - - - - - abac45fc by Matthew Pickering at 2022-02-03T14:44:17-05:00 Mark prog003 as expected_broken on static way #20704 - - - - - 13300dfd by Matthew Pickering at 2022-02-03T14:44:17-05:00 Filter out -rtsopts in T16219 to make static/dynamic ways agree - - - - - d89439f2 by Matthew Pickering at 2022-02-03T14:44:17-05:00 T13168: Filter out rtsopts for consistency between dynamic and static ways - - - - - 00180cdf by Matthew Pickering at 2022-02-03T14:44:17-05:00 Accept new output for T14335 test This test was previously not run due to #20960 - - - - - 1accdcff by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add flushes to plugin tests which print to stdout Due to #20791 you need to explicitly flush as otherwise the output from these tests doesn't make it to stdout. - - - - - d820f2e8 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Remove ghc_plugin_way Using ghc_plugin_way had the unintended effect of meaning certain tests weren't run at all when ghc_dynamic=true, if you delete this modifier then the tests work in both the static and dynamic cases. - - - - - aa5ef340 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Unbreak T13168 on windows Fixes #14276 - - - - - 84ab0153 by Matthew Pickering at 2022-02-03T14:44:53-05:00 Rewrite CallerCC parser using ReadP This allows us to remove the dependency on parsec and hence transitively on text. Also added some simple unit tests for the parser and fixed two small issues in the documentation. Fixes #21033 - - - - - 4e6780bb by Matthew Pickering at 2022-02-03T14:45:28-05:00 ci: Add debian 11 jobs (validate/release/nightly) Fixes #21002 - - - - - eddaa591 by Ben Gamari at 2022-02-04T10:01:59-05:00 compiler: Introduce and use RoughMap for instance environments Here we introduce a new data structure, RoughMap, inspired by the previous `RoughTc` matching mechanism for checking instance matches. This allows [Fam]InstEnv to be implemented as a trie indexed by these RoughTc signatures, reducing the complexity of instance lookup and FamInstEnv merging (done during the family instance conflict test) from O(n) to O(log n). The critical performance improvement currently realised by this patch is in instance matching. In particular the RoughMap mechanism allows us to discount many potential instances which will never match for constraints involving type variables (see Note [Matching a RoughMap]). In realistic code bases matchInstEnv was accounting for 50% of typechecker time due to redundant work checking instances when simplifying instance contexts when deriving instances. With this patch the cost is significantly reduced. The larger constants in InstEnv creation do mean that a few small tests regress in allocations slightly. However, the runtime of T19703 is reduced by a factor of 4. Moreover, the compilation time of the Cabal library is slightly improved. A couple of test cases are included which demonstrate significant improvements in compile time with this patch. This unfortunately does not fix the testcase provided in #19703 but does fix #20933 ------------------------- Metric Decrease: T12425 Metric Increase: T13719 T9872a T9872d hard_hole_fits ------------------------- Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 62d670eb by Matthew Pickering at 2022-02-04T10:02:35-05:00 testsuite: Run testsuite dependency calculation before GHC is built The main motivation for this patch is to allow tests to be added to the testsuite which test things about the source tree without needing to build GHC. In particular the notes linter can easily start failing and by integrating it into the testsuite the process of observing these changes is caught by normal validation procedures rather than having to run the linter specially. With this patch I can run ``` ./hadrian/build test --flavour=devel2 --only="uniques" ``` In a clean tree to run the checkUniques linter without having to build GHC. Fixes #21029 - - - - - 4bd52410 by Hécate Moonlight at 2022-02-04T16:14:10-05:00 Add the Ix class to Foreign C integral types Related CLC proposal is here: https://github.com/haskell/core-libraries-committee/issues/30 - - - - - de6d7692 by Ben Gamari at 2022-02-04T16:14:47-05:00 Drop dead code - - - - - b79206f1 by Ben Gamari at 2022-02-04T16:14:47-05:00 Add comments - - - - - 58d7faac by Ben Gamari at 2022-02-04T16:14:47-05:00 cmm: Introduce cmmLoadBWord and cmmLoadGCWord - - - - - 7217156c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment in CmmLoad - - - - - 99ea5f2c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment to CmmStore - - - - - 606b59a5 by Ben Gamari at 2022-02-04T16:14:47-05:00 Fix array primop alignment - - - - - 1cf9616a by Ben Gamari at 2022-02-04T16:14:47-05:00 llvmGen: Handle unaligned loads/stores This allows us to produce valid code for indexWord8ArrayAs*# on platforms that lack unaligned memory access. - - - - - 8c18feba by Ben Gamari at 2022-02-04T16:14:47-05:00 primops: Fix documentation of setByteArray# Previously the documentation was subtly incorrect regarding the bounds of the operation. Fix this and add a test asserting that a zero-length operation is in fact a no-op. - - - - - 88480e55 by nineonine at 2022-02-04T20:35:45-05:00 Fix unsound behavior of unlifted datatypes in ghci (#20194) Previously, directly calling a function that pattern matches on an unlifted data type which has at least two constructors in GHCi resulted in a segfault. This happened due to unaccounted return frame info table pointer. The fix is to pop the above mentioned frame info table pointer when unlifted things are returned. See Note [Popping return frame for unlifted things] authors: bgamari, nineonine - - - - - a5c7068c by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add Outputable instance for Messages c.f. #20980 - - - - - bf495f72 by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add a missing restoreLclEnv The commit commit 18df4013f6eaee0e1de8ebd533f7e96c4ee0ff04 Date: Sat Jan 22 01:12:30 2022 +0000 Define and use restoreLclEnv omitted to change one setLclEnv to restoreLclEnv, namely the one in GHC.Tc.Errors.warnRedundantConstraints. This new commit fixes the omission. - - - - - 6af8e71e by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Improve errors for non-existent labels This patch fixes #17469, by improving matters when you use non-existent field names in a record construction: data T = MkT { x :: Int } f v = MkT { y = 3 } The check is now made in the renamer, in GHC.Rename.Env.lookupRecFieldOcc. That in turn led to a spurious error in T9975a, which is fixed by making GHC.Rename.Names.extendGlobalRdrEnvRn fail fast if it finds duplicate bindings. See Note [Fail fast on duplicate definitions] in that module for more details. This patch was originated and worked on by Alex D (@nineonine) - - - - - 299acff0 by nineonine at 2022-02-05T19:21:49-05:00 Exit with failure when -e fails (fixes #18411 #9916 #17560) - - - - - 549292eb by Matthew Pickering at 2022-02-05T19:22:25-05:00 Make implication tidying agree with Note [Tidying multiple names at once] Note [Tidying multiple names at once] indicates that if multiple variables have the same name then we shouldn't prioritise one of them and instead rename them all to a1, a2, a3... etc This patch implements that change, some error message changes as expected. Closes #20932 - - - - - 2e9248b7 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Accept any address within 4GB of program text Previously m32 would assume that the program image was located near the start of the address space and therefore assume that it wanted pages in the bottom 4GB of address space. Instead we now check whether they are within 4GB of whereever the program is loaded. This is necessary on Windows, which now tends to place the image in high memory. The eventual goal is to use m32 to allocate memory for linker sections on Windows. - - - - - 86589b89 by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts: Generalize mmapForLinkerMarkExecutable Renamed to mprotectForLinker and allowed setting of arbitrary protection modes. - - - - - 88ef270a by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Add consistency-checking infrastructure This adds logic, enabled in the `-debug` RTS for checking the internal consistency of the m32 allocator. This area has always made me a bit nervous so this should help me sleep better at night in exchange for very little overhead. - - - - - 2d6f0b17 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Free large objects back to the free page pool Not entirely convinced that this is worth doing. - - - - - e96f50be by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Increase size of free page pool to 256 pages - - - - - fc083b48 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts: Dump memory map on memory mapping failures Fixes #20992. - - - - - 633296bc by Ben Gamari at 2022-02-06T01:43:56-05:00 Fix macro redefinition warnings for PRINTF * Move `PRINTF` macro from `Stats.h` to `Stats.c` as it's only needed in the latter. * Undefine `PRINTF` at the end of `Messages.h` to avoid leaking it. - - - - - 37d435d2 by John Ericson at 2022-02-06T01:44:32-05:00 Purge DynFlags from GHC.Stg Also derive some more instances. GHC doesn't need them, but downstream consumers may need to e.g. put stuff in maps. - - - - - 886baa34 by Peter Trommler at 2022-02-06T10:58:18+01:00 RTS: Fix cabal specification In 35bea01b xxhash.c was removed. Remove the extra-source-files stanza referring to it. - - - - - 27581d77 by nineonine at 2022-02-06T20:50:44-05:00 hadrian: remove redundant import - - - - - 4ff19981 by John Ericson at 2022-02-07T11:04:43-05:00 GHC.HsToCore.Coverage: No more HscEnv, less DynFlags Progress towards #20730 - - - - - b09389a6 by John Ericson at 2022-02-07T11:04:43-05:00 Create `CoverageConfig` As requested by @mpickering to collect the information we project from `HscEnv` - - - - - ff867c46 by Greg Steuck at 2022-02-07T11:05:24-05:00 Avoid using removed utils/checkUniques in validate Asked the question: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7460/diffs#4061f4d17546e239dd10d78c6b48668c2a288e02_1_0 - - - - - a9355e84 by sheaf at 2022-02-08T05:27:25-05:00 Allow HasField in quantified constraints We perform validity checking on user-written HasField instances, for example to disallow: data Foo a = Foo { fld :: Int } instance HasField "fld" (Foo a) Bool However, these checks were also being made on quantified constraints, e.g. data Bar where Bar :: (forall a. HasField s (Foo a) Int) => Proxy s -> Bar This patch simply skips validity checking for quantified constraints, in line with what we already do for equality constraints such as Coercible. Fixes #20989 - - - - - 6d77d3d8 by sheaf at 2022-02-08T05:28:05-05:00 Relax TyEq:N: allow out-of-scope newtype DataCon The 'bad_newtype' assertion in GHC.Tc.Solver.Canonical.canEqCanLHSFinish failed to account for the possibility that the newtype constructor might not be in scope, in which case we don't provide any guarantees about canonicalising away a newtype on the RHS of a representational equality. Fixes #21010 - - - - - a893d2f3 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Remove linter dependency on lint-submods - - - - - 457a5b9c by Ben Gamari at 2022-02-08T05:28:42-05:00 notes-util: initial commit - - - - - 1a943859 by Ben Gamari at 2022-02-08T05:28:42-05:00 gitlab-ci: Add lint-notes job - - - - - bc5cbce6 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add notes linter to testsuite - - - - - 38c6e301 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Fix some notes - - - - - c3aac0f8 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add suggestion mode to notes-util - - - - - 5dd29aea by Cale Gibbard at 2022-02-08T05:29:18-05:00 `hscSimpleIface` drop fingerprint param and ret `hscSimpleIface` does not depend on or modify the `Maybe Fingerprint` it is given, only passes it through, so get rid of the extraneous passing. Perhaps the intent was that there would be an iface fingerprint check of some sort? but this was never done. If/when we we want to do that, we can add it back then. - - - - - 4bcbd731 by Cale Gibbard at 2022-02-08T05:29:54-05:00 Document `hscIncrementalFrontend` and flip bool - - - - - b713db1e by John Ericson at 2022-02-08T05:30:29-05:00 StgToCmm: Get rid of GHC.Driver.Session imports `DynFlags` is gone, but let's move a few trivial things around to get rid of its module too. - - - - - f115c382 by Gleb Popov at 2022-02-08T05:31:05-05:00 Fix build on recent FreeBSD. Recent FreeBSD versions gained the sched_getaffinity function, which made two mutually exclusive #ifdef blocks to be enabled. - - - - - 3320ab40 by Ben Gamari at 2022-02-08T10:42:04-05:00 rts/MemoryMap: Use mach_-prefixed type names There appears to be some inconsistency in system-call type naming across Darwin toolchains. Specifically: * the `address` argument to `mach_vm_region` apparently wants to be a `mach_vm_address_t *`, not a `vm_address_t *` * the `vmsize` argument to `mach_vm_region` wants to be a `mach_vm_size_t`, not a `vm_size_t` - - - - - b33f0cfa by Richard Eisenberg at 2022-02-08T10:42:41-05:00 Document that reifyRoles includes kind parameters Close #21056 - - - - - bd493ed6 by PHO at 2022-02-08T10:43:19-05:00 Don't try to build stage1 with -eventlog if stage0 doesn't provide it Like -threaded, stage0 isn't guaranteed to have an event-logging RTS. - - - - - 03c2de0f by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Use absolute paths for config.libdir Fixes #21052 - - - - - ef294525 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Clean up old/redundant predicates - - - - - a39ed908 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Add missing dependency on ghcconfig - - - - - a172be07 by PHO at 2022-02-09T03:56:59-05:00 Implement System.Environment.getExecutablePath for NetBSD and also use it from GHC.BaseDir.getBaseDir - - - - - 62fa126d by PHO at 2022-02-09T03:57:37-05:00 Fix a portability issue in m4/find_llvm_prog.m4 `test A == B' is a Bash extension, which doesn't work on platforms where /bin/sh is not Bash. - - - - - fd9981e3 by Ryan Scott at 2022-02-09T03:58:13-05:00 Look through untyped TH splices in tcInferAppHead_maybe Previously, surrounding a head expression with a TH splice would defeat `tcInferAppHead_maybe`, preventing some expressions from typechecking that used to typecheck in previous GHC versions (see #21038 for examples). This is simple enough to fix: just look through `HsSpliceE`s in `tcInferAppHead_maybe`. I've added some additional prose to `Note [Application chains and heads]` in `GHC.Tc.Gen.App` to accompany this change. Fixes #21038. - - - - - 00975981 by sheaf at 2022-02-09T03:58:53-05:00 Add test for #21037 This program was rejected by GHC 9.2, but is accepted on newer versions of GHC. This patch adds a regression test. Closes #21037 - - - - - fad0b2b0 by Ben Gamari at 2022-02-09T08:29:46-05:00 Rename -merge-objs flag to --merge-objs For consistency with --make and friends. - - - - - 1dbe5b2a by Matthew Pickering at 2022-02-09T08:30:22-05:00 driver: Filter out our own boot module in hptSomeThingsBelow hptSomeThingsBelow would return a list of modules which contain the .hs-boot file for a particular module. This caused some problems because we would try and find the module in the HPT (but it's not there when we're compiling the module itself). Fixes #21058 - - - - - 2b1cced1 by Sylvain Henry at 2022-02-09T20:42:23-05:00 NCG: minor code factorization - - - - - e01ffec2 by Sylvain Henry at 2022-02-09T20:42:23-05:00 ByteCode: avoid out-of-bound read Cf https://gitlab.haskell.org/ghc/ghc/-/issues/18431#note_287139 - - - - - 53c26e79 by Ziyang Liu at 2022-02-09T20:43:02-05:00 Include ru_name in toHsRule message See #18147 - - - - - 3df06922 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Rename MemoryMap.[ch] -> ReportMemoryMap.[ch] - - - - - e219ac82 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Move mmapForLinker and friends to linker/MMap.c They are not particularly related to linking. - - - - - 30e205ca by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker: Drop dead IA64 code - - - - - 4d3a306d by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker/MMap: Use MemoryAccess in mmapForLinker - - - - - 1db4f1fe by Ben Gamari at 2022-02-09T20:43:39-05:00 linker: Don't use MAP_FIXED As noted in #21057, we really shouldn't be using MAP_FIXED. I would much rather have the process crash with a "failed to map" error than randomly overwrite existing mappings. Closes #21057. - - - - - 1eeae25c by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/mmap: Refactor mmapForLinker Here we try to separate the policy decisions of where to place mappings from the mechanism of creating the mappings. This makes things significantly easier to follow. - - - - - ac2d18a7 by sheaf at 2022-02-09T20:44:18-05:00 Add some perf tests for coercions This patch adds some performance tests for programs that create large coercions. This is useful because the existing test coverage is not very representative of real-world situations. In particular, this adds a test involving an extensible records library, a common pain-point for users. - - - - - 48f25715 by Andreas Klebinger at 2022-02-10T04:35:35-05:00 Add late cost centre support This allows cost centres to be inserted after the core optimization pipeline has run. - - - - - 0ff70427 by Andreas Klebinger at 2022-02-10T04:36:11-05:00 Docs:Mention that safe calls don't keep their arguments alive. - - - - - 1d3ed168 by Ben Gamari at 2022-02-10T04:36:46-05:00 PEi386: Drop Windows Vista fallback in addLibrarySearchPath We no longer support Windows Vista. - - - - - 2a6f2681 by Ben Gamari at 2022-02-10T04:36:46-05:00 linker/PEi386: Make addLibrarySearchPath long-path aware Previously `addLibrarySearchPath` failed to normalise the added path to UNC form before passing it to `AddDllDirectory`. Consequently, the call was subject to the MAX_PATH restriction, leading to the failure of `test-defaulting-plugin-fail`, among others. Happily, this also nicely simplifies the implementation. Closes #21059. - - - - - 2a47ee9c by Daniel Gröber at 2022-02-10T19:18:58-05:00 ghc-boot: Simplify writePackageDb permissions handling Commit ef8a3fbf1 ("ghc-boot: Fix metadata handling of writeFileAtomic") introduced a somewhat over-engineered fix for #14017 by trying to preserve the current permissions if the target file already exists. The problem in the issue is simply that the package db cache file should be world readable but isn't if umask is too restrictive. In fact the previous fix only handles part of this problem. If the file isn't already there in a readable configuration it wont make it so which isn't really ideal either. Rather than all that we now simply always force all the read access bits to allow access while leaving the owner at the system default as it's just not our business to mess with it. - - - - - a1d97968 by Ben Gamari at 2022-02-10T19:19:34-05:00 Bump Cabal submodule Adapts GHC to the factoring-out of `Cabal-syntax`. Fixes #20991. Metric Decrease: haddock.Cabal - - - - - 89cf8caa by Morrow at 2022-02-10T19:20:13-05:00 Add metadata to integer-gmp.cabal - - - - - c995b7e7 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of EVENT_IPE This leads to corrupted eventlogs because the size of EVENT_IPE is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 59ba8fb3 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of MEM_RETURN This leads to corrupted eventlogs because the size of EVENT_MEM_RETURN is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 19413d09 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Delete misleading comment in gen_event_types.py Not all events start with CapNo and there's not logic I could see which adds this to the length. - - - - - e06f49c0 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix size of TICKY_COUNTER_BEGIN_SAMPLE - - - - - 2f99255b by Matthew Pickering at 2022-02-10T19:21:24-05:00 Fix copy-pasto in prof-late-ccs docs - - - - - 19deb002 by Matthew Pickering at 2022-02-10T19:21:59-05:00 Refine tcSemigroupWarnings to work in ghc-prim ghc-prim doesn't depend on base so can't have any Monoid or Semigroup instances. However, attempting to load these definitions ran into issues when the interface for `GHC.Base` did exist as that would try and load the interface for `GHC.Types` (which is the module we are trying to compile and has no interface). The fix is to just not do this check when we are compiling a module in ghc-prim. Fixes #21069 - - - - - 34dec6b7 by sheaf at 2022-02-11T17:55:34-05:00 Decrease the size of the LargeRecord test This test was taking too long to run, so this patch makes it smaller. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 9cab90d9 by Matthew Pickering at 2022-02-11T22:27:19-05:00 Make sure all platforms have a release job The release bindists are currently a mixture of validate and release builds. This is bad because the validate builds don't have profiling libraries. The fix is to make sure there is a release job for each platform we want to produce a release for.t Fixes #21066 - - - - - 4bce3575 by Matthew Pickering at 2022-02-11T22:27:54-05:00 testsuite: Make sure all tests trigger ghc rebuild I made a mistake when implementing #21029 which meant that certain tests didn't trigger a GHC recompilation. By adding the `test:ghc` target to the default settings all tests will now depend on this target unless explicitly opting out via the no_deps modifier. - - - - - 90a26f8b by Sylvain Henry at 2022-02-11T22:28:34-05:00 Fix documentation about Word64Rep/Int64Rep (#16964) - - - - - 0e93023e by Andreas Klebinger at 2022-02-12T13:59:41+00:00 Tag inference work. This does three major things: * Enforce the invariant that all strict fields must contain tagged pointers. * Try to predict the tag on bindings in order to omit tag checks. * Allows functions to pass arguments unlifted (call-by-value). The former is "simply" achieved by wrapping any constructor allocations with a case which will evaluate the respective strict bindings. The prediction is done by a new data flow analysis based on the STG representation of a program. This also helps us to avoid generating redudant cases for the above invariant. StrictWorkers are created by W/W directly and SpecConstr indirectly. See the Note [Strict Worker Ids] Other minor changes: * Add StgUtil module containing a few functions needed by, but not specific to the tag analysis. ------------------------- Metric Decrease: T12545 T18698b T18140 T18923 LargeRecord Metric Increase: LargeRecord ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T15164 T18282 T18304 T18698a T1969 T20049 T3294 T4801 T5321FD T5321Fun T783 T9233 T9675 T9961 T19695 WWRec ------------------------- - - - - - 744f8a11 by Greg Steuck at 2022-02-12T17:13:55-05:00 Only check the exit code in derefnull & divbyzero tests on OpenBSD - - - - - eeead9fc by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/Adjustor: Ensure that allocateExecPage succeeded Previously we failed to handle the case that `allocateExecPage` failed. - - - - - afdfaff0 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Drop DEC Alpha adjustor implementation The last Alpha chip was produced in 2004. - - - - - 191dfd2d by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/adjustor: Split Windows path out of NativeAmd64 - - - - - be591e27 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Initial commit of AdjustorPool - - - - - d6d48b16 by Ben Gamari at 2022-02-13T03:26:14-05:00 Introduce initAdjustors - - - - - eab37902 by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64: Use AdjustorPool - - - - - 974e73af by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64Mingw: Use AdjustorPool - - - - - 95fab83f by Ben Gamari at 2022-02-13T03:26:14-05:00 configure: Fix result reporting of adjustors method check - - - - - ef5cf55d by nikshalark at 2022-02-13T03:26:16-05:00 (#21044) Documented arithmetic functions in base. Didn't get it right the ninth time. Now everything's formatted correctly. - - - - - acb482cc by Takenobu Tani at 2022-02-16T05:27:17-05:00 Relax load_load_barrier for aarch64 This patch relaxes the instruction for load_load_barrier(). Current load_load_barrier() implements full-barrier with `dmb sy`. It's too strong to order load-load instructions. We can relax it by using `dmb ld`. If current load_load_barrier() is used for full-barriers (load/store - load/store barrier), this patch is not suitable. See also linux-kernel's smp_rmb() implementation: https://github.com/torvalds/linux/blob/v5.14/arch/arm64/include/asm/barrier.h#L90 Hopefully, it's better to use `dmb ishld` rather than `dmb ld` to improve performance. However, I can't validate effects on a real many-core Arm machine. - - - - - 84eaa26f by Oleg Grenrus at 2022-02-16T05:27:56-05:00 Add test for #20562 - - - - - 2c28620d by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: remove struct StgRetry, it is never used - - - - - 74bf9bb5 by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: document some closure types - - - - - 316312ec by nineonine at 2022-02-16T05:29:08-05:00 ghci: fix -ddump-stg-cg (#21052) The pre-codegen Stg AST dump was not available in ghci because it was performed in 'doCodeGen'. This was now moved to 'coreToStg' area. - - - - - a6411d74 by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: mention -fprof-late-ccs in the release notes And note which compiler version it was added in. - - - - - 4127e86d by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: fix release notes formatting - - - - - 4e6c8019 by Matthew Pickering at 2022-02-17T05:25:28-05:00 Always define __GLASGOW_HASKELL_PATCHLEVEL1/2__ macros As #21076 reports if you are using `-Wcpp-undef` then you get warnings when using the `MIN_VERSION_GLASGOW_HASKELL` macro because __GLASGOW_HASKELL_PATCHLEVEL2__ is very rarely explicitliy set (as version numbers are not 4 components long). This macro was introduced in 3549c952b535803270872adaf87262f2df0295a4 and it seems the bug has existed ever since. Fixes #21076 - - - - - 67dd5724 by Ben Gamari at 2022-02-17T05:26:03-05:00 rts/AdjustorPool: Silence unused function warning bitmap_get is only used in the DEBUG RTS configuration. Fixes #21079. - - - - - 4b04f7e1 by Zubin Duggal at 2022-02-20T13:56:15-05:00 Track object file dependencies for TH accurately (#20604) `hscCompileCoreExprHook` is changed to return a list of `Module`s required by a splice. These modules are accumulated in the TcGblEnv (tcg_th_needed_mods). Dependencies on the object files of these modules are recording in the interface. The data structures in `LoaderState` are replaced with more efficient versions to keep track of all the information required. The MultiLayerModulesTH_Make allocations increase slightly but runtime is faster. Fixes #20604 ------------------------- Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - 92ab3ff2 by sheaf at 2022-02-20T13:56:55-05:00 Use diagnostics for "missing signature" errors This patch makes the "missing signature" errors from "GHC.Rename.Names" use the diagnostic infrastructure. This encompasses missing type signatures for top-level bindings and pattern synonyms, as well as missing kind signatures for type constructors. This patch also renames TcReportMsg to TcSolverReportMsg, and adds a few convenience functions to compute whether such a TcSolverReportMsg is an expected/actual message. - - - - - 845284a5 by sheaf at 2022-02-20T13:57:34-05:00 Generically: remove redundant Semigroup constraint This patch removes a redundant Semigroup constraint on the Monoid instance for Generically. This constraint can cause trouble when one wants to derive a Monoid instance via Generically through a type that doesn't itself have a Semigroup instance, for example: data Point2D a = Point2D !a !a newtype Vector2D a = Vector2D { tip :: Point2D a } deriving ( Semigroup, Monoid ) via Generically ( Point2D ( Sum a ) ) In this case, we should not require there to be an instance Semigroup ( Point2D ( Sum a ) ) as all we need is an instance for the generic representation of Point2D ( Sum a ), i.e. Semigroup ( Rep ( Point2D ( Sum a) ) () ). - - - - - 6b468f7f by Ben Gamari at 2022-02-20T13:58:10-05:00 Bump time submodule to 1.12.1 - - - - - 2f0ceecc by Zubin Duggal at 2022-02-20T19:06:19+00:00 hadrian: detect if 'main' is not a haskell file and add it to appropriate list of sources - - - - - 7ce1b694 by Zubin Duggal at 2022-02-21T11:18:58+00:00 Reinstallable GHC This patch allows ghc and its dependencies to be built using a normal invocation of cabal-install. Each componenent which relied on generated files or additional configuration now has a Setup.hs file. There are also various fixes to the cabal files to satisfy cabal-install. There is a new hadrian command which will build a stage2 compiler and then a stage3 compiler by using cabal. ``` ./hadrian/build build-cabal ``` There is also a new CI job which tests running this command. For the 9.4 release we will upload all the dependent executables to hackage and then end users will be free to build GHC and GHC executables via cabal. There are still some unresolved questions about how to ensure soundness when loading plugins into a reinstalled GHC (#20742) which will be tighted up in due course. Fixes #19896 - - - - - 78fbc3a3 by Matthew Pickering at 2022-02-21T15:14:28-05:00 hadrian: Enable late-ccs when building profiled_ghc - - - - - 2b890c89 by Matthew Pickering at 2022-02-22T15:59:33-05:00 testsuite: Don't print names of all fragile tests on all runs This information about fragile tests is pretty useless but annoying on CI where you have to scroll up a long way to see the actual issues. - - - - - 0b36801f by sheaf at 2022-02-22T16:00:14-05:00 Forbid standalone instances for built-in classes `check_special_inst_head` includes logic that disallows hand-written instances for built-in classes such as Typeable, KnownNat and KnownSymbol. However, it also allowed standalone deriving declarations. This was because we do want to allow standalone deriving instances with Typeable as they are harmless, but we certainly don't want to allow instances for e.g. KnownNat. This patch ensures that we don't allow derived instances for KnownNat, KnownSymbol (and also KnownChar, which was previously omitted entirely). Fixes #21087 - - - - - ace66dec by Krzysztof Gogolewski at 2022-02-22T16:30:59-05:00 Remove -Wunticked-promoted-constructors from -Wall Update manual; explain ticks as optional disambiguation rather than the preferred default. This is a part of #20531. - - - - - 558c7d55 by Hugo at 2022-02-22T16:31:01-05:00 docs: fix error in annotation guide code snippet - - - - - a599abba by Richard Eisenberg at 2022-02-23T08:16:07-05:00 Kill derived constraints Co-authored by: Sam Derbyshire Previously, GHC had three flavours of constraint: Wanted, Given, and Derived. This removes Derived constraints. Though serving a number of purposes, the most important role of Derived constraints was to enable better error messages. This job has been taken over by the new RewriterSets, as explained in Note [Wanteds rewrite wanteds] in GHC.Tc.Types.Constraint. Other knock-on effects: - Various new Notes as I learned about under-described bits of GHC - A reshuffling around the AST for implicit-parameter bindings, with better integration with TTG. - Various improvements around fundeps. These were caused by the fact that, previously, fundep constraints were all Derived, and Derived constraints would get dropped. Thus, an unsolved Derived didn't stop compilation. Without Derived, this is no longer possible, and so we have to be considerably more careful around fundeps. - A nice little refactoring in GHC.Tc.Errors to center the work on a new datatype called ErrorItem. Constraints are converted into ErrorItems at the start of processing, and this allows for a little preprocessing before the main classification. - This commit also cleans up the behavior in generalisation around functional dependencies. Now, if a variable is determined by functional dependencies, it will not be quantified. This change is user facing, but it should trim down GHC's strange behavior around fundeps. - Previously, reportWanteds did quite a bit of work, even on an empty WantedConstraints. This commit adds a fast path. - Now, GHC will unconditionally re-simplify constraints during quantification. See Note [Unconditionally resimplify constraints when quantifying], in GHC.Tc.Solver. Close #18398. Close #18406. Solve the fundep-related non-confluence in #18851. Close #19131. Close #19137. Close #20922. Close #20668. Close #19665. ------------------------- Metric Decrease: LargeRecord T9872b T9872b_defer T9872d TcPlugin_RewritePerf ------------------------- - - - - - 2ed22ba1 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Introduce predicate for when to enable source notes (needSourceNotes) There were situations where we were using debugLevel == 0 as a proxy for whether to retain source notes but -finfo-table-map also enables and needs source notes so we should act consistently in both cases. Ticket #20847 - - - - - 37deb893 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Use SrcSpan from the binder as initial source estimate There are some situations where we end up with no source notes in useful positions in an expression. In this case we currently fail to provide any source information about where an expression came from. This patch improves the initial estimate by using the position from the top-binder as the guess for the location of the whole inner expression. It provides quite a course estimate but it's better than nothing. Ticket #20847 - - - - - 59b7f764 by Cheng Shao at 2022-02-23T08:17:24-05:00 Don't emit foreign exports initialiser code for empty CAF list - - - - - c7f32f76 by John Ericson at 2022-02-23T13:58:36-05:00 Prepare rechecking logic for new type in a few ways Combine `MustCompile and `NeedsCompile` into a single case. `CompileReason` is put inside to destinguish the two. This makes a number of things easier. `Semigroup RecompileRequired` is no longer used, to make sure we skip doing work where possible. `recompThen` is very similar, but helps remember. `checkList` is rewritten with `recompThen`. - - - - - e60d8df8 by John Ericson at 2022-02-23T13:58:36-05:00 Introduce `MaybeValidated` type to remove invalid states The old return type `(RecompRequired, Maybe _)`, was confusing because it was inhabited by values like `(UpToDate, Nothing)` that made no sense. The new type ensures: - you must provide a value if it is up to date. - you must provide a reason if you don't provide a value. it is used as the return value of: - `checkOldIface` - `checkByteCode` - `checkObjects` - - - - - f07b13e3 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor X86 codegen Preliminary work done to make working on #5444 easier. Mostly make make control-flow easier to follow: * renamed genCCall into genForeignCall * split genForeignCall into the part dispatching on PrimTarget (genPrim) and the one really generating code for a C call (cf ForeignTarget and genCCall) * made genPrim/genSimplePrim only dispatch on MachOp: each MachOp now has its own code generation function. * out-of-line primops are not handled in a partial `outOfLineCmmOp` anymore but in the code generation functions directly. Helper functions have been introduced (e.g. genLibCCall) for code sharing. * the latter two bullets make code generated for primops that are only sometimes out-of-line (e.g. Pdep or Memcpy) and the logic to select between inline/out-of-line much more localized * avoided passing is32bit as an argument as we can easily get it from NatM state when we really need it * changed genCCall type to avoid it being partial (it can't handle PrimTarget) * globally removed 12 calls to `panic` thanks to better control flow and types ("parse, don't validate" ftw!). - - - - - 6fa7591e by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor the way registers are handled * add getLocalRegReg to avoid allocating a CmmLocal just to call getRegisterReg * 64-bit registers: in the general case we must always use the virtual higher part of the register, so we might as well always return it with the lower part. The only exception is to implement 64-bit to 32-bit conversions. We now have to explicitly discard the higher part when matching on Reg64/RegCode64 datatypes instead of explicitly fetching the higher part from the lower part: much safer default. - - - - - bc8de322 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: inline some 64-bit primops on x86/32-bit (#5444) Several 64-bit operation were implemented with FFI calls on 32-bit architectures but we can easily implement them with inline assembly code. Also remove unused hs_int64ToWord64 and hs_word64ToInt64 C functions. - - - - - 7b7c6b95 by Matthew Pickering at 2022-02-23T14:00:00-05:00 Simplify/correct implementation of getModuleInfo - - - - - 6215b04c by Matthew Pickering at 2022-02-23T14:00:00-05:00 Remove mg_boot field from ModuleGraph It was unused in the compiler so I have removed it to streamline ModuleGraph. - - - - - 818ff2ef by Matthew Pickering at 2022-02-23T14:00:01-05:00 driver: Remove needsTemplateHaskellOrQQ from ModuleGraph The idea of the needsTemplateHaskellOrQQ query is to check if any of the modules in a module graph need Template Haskell then enable -dynamic-too if necessary. This is quite imprecise though as it will enable -dynamic-too for all modules in the module graph even if only one module uses template haskell, with multiple home units, this is obviously even worse. With -fno-code we already have similar logic to enable code generation just for the modules which are dependeded on my TemplateHaskell modules so we use the same code path to decide whether to enable -dynamic-too rather than using this big hammer. This is part of the larger overall goal of moving as much statically known configuration into the downsweep as possible in order to have fully decided the build plan and all the options before starting to build anything. I also included a fix to #21095, a long standing bug with with the logic which is supposed to enable the external interpreter if we don't have the internal interpreter. Fixes #20696 #21095 - - - - - b6670af6 by Matthew Pickering at 2022-02-23T14:00:40-05:00 testsuite: Normalise output of ghci011 and T7627 The outputs of these tests vary on the order interface files are loaded so we normalise the output to correct for these inconsequential differences. Fixes #21121 - - - - - 9ed3bc6e by Peter Trommler at 2022-02-23T14:01:16-05:00 testsuite: Fix ipeMap test Pointers to closures must be untagged before use. Produce closures of different types so we get different info tables. Fixes #21112 - - - - - 7d426148 by Ziyang Liu at 2022-02-24T04:53:34-05:00 Allow `return` in more cases in ApplicativeDo The doc says that the last statement of an ado-block can be one of `return E`, `return $ E`, `pure E` and `pure $ E`. But `return` is not accepted in a few cases such as: ```haskell -- The ado-block only has one statement x :: F () x = do return () -- The ado-block only has let-statements besides the `return` y :: F () y = do let a = True return () ``` These currently require `Monad` instances. This MR fixes it. Normally `return` is accepted as the last statement because it is stripped in constructing an `ApplicativeStmt`, but this cannot be done in the above cases, so instead we replace `return` by `pure`. A similar but different issue (when the ado-block contains `BindStmt` or `BodyStmt`, the second last statement cannot be `LetStmt`, even if the last statement uses `pure`) is fixed in !6786. - - - - - a5ea7867 by John Ericson at 2022-02-24T20:23:49-05:00 Clarify laws of TestEquality It is unclear what `TestEquality` is for. There are 3 possible choices. Assuming ```haskell data Tag a where TagInt1 :: Tag Int TagInt2 :: Tag Int ``` Weakest -- type param equality semi-decidable --------------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params may or may not be not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Nothing -- oopsie is allowed testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` This option is better demonstrated with a different type: ```haskell data Tag' a where TagInt1 :: Tag Int TagInt2 :: Tag a ``` ```haskell instance TestEquality Tag' where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Nothing -- can't be sure testEquality TagInt2 TagInt1 = Nothing -- can't be sure testEquality TagInt2 TagInt2 = Nothing -- can't be sure ``` Weaker -- type param equality decidable --------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params are not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` Strong -- Like `Eq` ------------------- `Just Refl` means the type params are equal, and the values are equal according to `Eq`. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl testEquality _ _ = Nothing ``` Strongest -- unique value concrete type --------------------------------------- `Just Refl` means the type params are equal, and the values are equal, and the class assume if the type params are equal the values must also be equal. In other words, the type is a singleton type when the type parameter is a closed term. ```haskell -- instance TestEquality -- invalid instance because two variants for `Int` ``` ------ The discussion in https://github.com/haskell/core-libraries-committee/issues/21 has decided on the "Weaker" option (confusingly formerly called the "Weakest" option). So that is what is implemented. - - - - - 06c18990 by Zubin Duggal at 2022-02-24T20:24:25-05:00 TH: fix pretty printing of GADTs with multiple constuctors (#20842) - - - - - 6555b68c by Matthew Pickering at 2022-02-24T20:25:06-05:00 Move linters into the tree This MR moves the GHC linters into the tree, so that they can be run directly using Hadrian. * Query all files tracked by Git instead of using changed files, so that we can run the exact same linting step locally and in a merge request. * Only check that the changelogs don't contain TBA when RELEASE=YES. * Add hadrian/lint script, which runs all the linting steps. * Ensure the hlint job exits with a failure if hlint is not installed (otherwise we were ignoring the failure). Given that hlint doesn't seem to be available in CI at the moment, I've temporarily allowed failure in the hlint job. * Run all linting tests in CI using hadrian. - - - - - b99646ed by Matthew Pickering at 2022-02-24T20:25:06-05:00 Add rule for generating HsBaseConfig.h If you are running the `lint:{base/compiler}` command locally then this improves the responsiveness because we don't re-run configure everytime if the header file already exists. - - - - - d0deaaf4 by Matthew Pickering at 2022-02-24T20:25:06-05:00 Suggestions due to hlint It turns out this job hasn't been running for quite a while (perhaps ever) so there are quite a few failures when running the linter locally. - - - - - 70bafefb by nineonine at 2022-02-24T20:25:42-05:00 ghci: show helpful error message when loading module with SIMD vector operations (#20214) Previously, when trying to load module with SIMD vector operations, ghci would panic in 'GHC.StgToByteCode.findPushSeq'. Now, a more helpful message is displayed. - - - - - 8ed3d5fd by Matthew Pickering at 2022-02-25T10:24:12+00:00 Remove test-bootstrap and cabal-reinstall jobs from fast-ci [skip ci] - - - - - 8387dfbe by Mario Blažević at 2022-02-25T21:09:41-05:00 template-haskell: Fix two prettyprinter issues Fix two issues regarding printing numeric literals. Fixing #20454. - - - - - 4ad8ce0b by sheaf at 2022-02-25T21:10:22-05:00 GHCi: don't normalise partially instantiated types This patch skips performing type normalisation when we haven't fully instantiated the type. That is, in tcRnExpr (used only for :type in GHCi), skip normalisation if the result type responds True to isSigmaTy. Fixes #20974 - - - - - f35aca4d by Ben Gamari at 2022-02-25T21:10:57-05:00 rts/adjustor: Always place adjustor templates in data section @nrnrnr points out that on his machine ld.lld rejects text relocations. Generalize the Darwin text-relocation avoidance logic to account for this. - - - - - cddb040a by Andreas Klebinger at 2022-02-25T21:11:33-05:00 Ticky: Gate tag-inference dummy ticky-counters behind a flag. Tag inference included a way to collect stats about avoided tag-checks. This was dony by emitting "dummy" ticky entries with counts corresponding to predicted/unpredicated tag checks. This behaviour for ticky is now gated behind -fticky-tag-checks. I also documented ticky-LNE in the process. - - - - - 948bf2d0 by Ben Gamari at 2022-02-25T21:12:09-05:00 Fix comment reference to T4818 - - - - - 9c3edeb8 by Ben Gamari at 2022-02-25T21:12:09-05:00 simplCore: Correctly extend in-scope set in rule matching Note [Matching lets] in GHC.Core.Rules claims the following: > We use GHC.Core.Subst.substBind to freshen the binding, using an > in-scope set that is the original in-scope variables plus the > rs_bndrs (currently floated let-bindings). However, previously the implementation didn't actually do extend the in-scope set with rs_bndrs. This appears to be a regression which was introduced by 4ff4d434e9a90623afce00b43e2a5a1ccbdb4c05. Moreover, the originally reasoning was subtly wrong: we must rather use the in-scope set from rv_lcl, extended with rs_bndrs, not that of `rv_fltR` Fixes #21122. - - - - - 7f9f49c3 by sheaf at 2022-02-25T21:12:47-05:00 Derive some stock instances for OverridingBool This patch adds some derived instances to `GHC.Data.Bool.OverridingBool`. It also changes the order of the constructors, so that the derived `Ord` instance matches the behaviour for `Maybe Bool`. Fixes #20326 - - - - - 140438a8 by nineonine at 2022-02-25T21:13:23-05:00 Add test for #19271 - - - - - ac9f4606 by sheaf at 2022-02-25T21:14:04-05:00 Allow qualified names in COMPLETE pragmas The parser didn't allow qualified constructor names to appear in COMPLETE pragmas. This patch fixes that. Fixes #20551 - - - - - 677c6c91 by Sylvain Henry at 2022-02-25T21:14:44-05:00 Testsuite: remove arch conditional in T8832 Taken from !3658 - - - - - ad04953b by Sylvain Henry at 2022-02-25T21:15:23-05:00 Allow hscGenHardCode to not return CgInfos This is a minor change in preparation for the JS backend: CgInfos aren't mandatory and the JS backend won't return them. - - - - - 929c280f by Sylvain Henry at 2022-02-25T21:15:24-05:00 Derive Enum instances for CCallConv and Safety This is used by the JS backend for serialization. - - - - - 75e4e090 by Sebastian Graf at 2022-02-25T21:15:59-05:00 base: Improve documentation of `throwIO` (#19854) Now it takes a better account of precise vs. imprecise exception semantics. Fixes #19854. - - - - - 61a203ba by Matthew Pickering at 2022-02-26T02:06:51-05:00 Make typechecking unfoldings from interfaces lazier The old logic was unecessarily strict in loading unfoldings because when reading the unfolding we would case on the result of attempting to load the template before commiting to which type of unfolding we were producing. Hence trying to inspect any of the information about an unfolding would force the template to be loaded. This also removes a potentially hard to discover bug where if the template failed to be typechecked for some reason then we would just not return an unfolding. Instead we now panic so these bad situations which should never arise can be identified. - - - - - 2be74460 by Matthew Pickering at 2022-02-26T02:06:51-05:00 Use a more up-to-date snapshot of the current rules in the simplifier As the prescient (now deleted) note warns in simplifyPgmIO we have to be a bit careful about when we gather rules from the EPS so that we get the rules for imported bindings. ``` -- Get any new rules, and extend the rule base -- See Note [Overall plumbing for rules] in GHC.Core.Rules -- We need to do this regularly, because simplification can -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings ``` Given the previous commit, the loading of unfoldings is now even more delayed so we need to be more careful to read the EPS rule base closer to the point where we decide to try rules. Without this fix GHC performance regressed by a noticeably amount because the `zip` rule was not brought into scope eagerly enough which led to a further series of unfortunate events in the simplifer which tipped `substTyWithCoVars` over the edge of the size threshold, stopped it being inlined and increased allocations by 10% in some cases. Furthermore, this change is noticeably in the testsuite as it changes T19790 so that the `length` rules from GHC.List fires earlier. ------------------------- Metric Increase: T9961 ------------------------- - - - - - b8046195 by Matthew Pickering at 2022-02-26T02:06:52-05:00 Improve efficiency of extending a RuleEnv with a new RuleBase Essentially we apply the identity: > lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) > = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 The latter being more efficient as we don't construct an intermediate map. This is now quite important as each time we try and apply rules we need to combine the current EPS RuleBase with the HPT and ModGuts rule bases. - - - - - 033e9f0f by sheaf at 2022-02-26T02:07:30-05:00 Error on anon wildcards in tcAnonWildCardOcc The code in tcAnonWildCardOcc assumed that it could never encounter anonymous wildcards in illegal positions, because the renamer would have ruled them out. However, it's possible to sneak past the checks in the renamer by using Template Haskell. It isn't possible to simply pass on additional information when renaming Template Haskell brackets, because we don't know in advance in what context the bracket will be spliced in (see test case T15433b). So we accept that we might encounter these bogus wildcards in the typechecker and throw the appropriate error. This patch also migrates the error messages for illegal wildcards in types to use the diagnostic infrastructure. Fixes #15433 - - - - - 32d8fe3a by sheaf at 2022-02-26T14:15:33+01:00 Core Lint: ensure primops can be eta-expanded This patch adds a check to Core Lint, checkCanEtaExpand, which ensures that primops and other wired-in functions with no binding such as unsafeCoerce#, oneShot, rightSection... can always be eta-expanded, by checking that the remaining argument types have a fixed RuntimeRep. Two subtleties came up: - the notion of arity in Core looks through newtypes, so we may need to unwrap newtypes in this check, - we want to avoid calling hasNoBinding on something whose unfolding we are in the process of linting, as this would cause a loop; to avoid this we add some information to the Core Lint environment that holds this information. Fixes #20480 - - - - - 0a80b436 by Peter Trommler at 2022-02-26T17:21:59-05:00 testsuite: Require LLVM for T15155l - - - - - 38cb920e by Oleg Grenrus at 2022-02-28T07:14:04-05:00 Add Monoid a => Monoid (STM a) instance - - - - - d734ef8f by Hécate Moonlight at 2022-02-28T07:14:42-05:00 Make modules in base stable. fix #18963 - - - - - fbf005e9 by Sven Tennie at 2022-02-28T19:16:01-05:00 Fix some hlint issues in ghc-heap This does not fix all hlint issues as the criticised index and length expressions seem to be fine in context. - - - - - adfddf7d by Matthew Pickering at 2022-02-28T19:16:36-05:00 hadrian: Suggest to the user to run ./configure if missing a setting If a setting is missing from the configuration file it's likely the user needs to reconfigure. Fixes #20476 - - - - - 4f0208e5 by Andreas Klebinger at 2022-02-28T19:17:12-05:00 CLabel cleanup: Remove these smart constructors for these reasons: * mkLocalClosureTableLabel : Does the same as the non-local variant. * mkLocalClosureLabel : Does the same as the non-local variant. * mkLocalInfoTableLabel : Decide if we make a local label based on the name and just use mkInfoTableLabel everywhere. - - - - - 065419af by Matthew Pickering at 2022-02-28T19:17:47-05:00 linking: Don't pass --hash-size and --reduce-memory-overhead to ld These flags were added to help with the high linking cost of the old split-objs mode. Now we are using split-sections these flags appear to make no difference to memory usage or time taken to link. I tested various configurations linking together the ghc library with -split-sections enabled. | linker | time (s) | | ------ | ------ | | gold | 0.95 | | ld | 1.6 | | ld (hash-size = 31, reduce-memory-overheads) | 1.6 | | ldd | 0.47 | Fixes #20967 - - - - - 3e65ef05 by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix typo in docstring for Overlap - - - - - 80f9133e by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix docstring for Bytes It seems like a commented out section of code was accidentally included in the docstring for a field. - - - - - 54774268 by Matthew Pickering at 2022-03-01T16:23:10-05:00 Fix longstanding issue with moduleGraphNodes - no hs-boot files case In the case when we tell moduleGraphNodes to drop hs-boot files the idea is to collapse hs-boot files into their hs file nodes. In the old code * nodeDependencies changed edges from IsBoot to NonBoot * moduleGraphNodes just dropped boot file nodes The net result is that any dependencies of the hs-boot files themselves were dropped. The correct thing to do is * nodeDependencies changes edges from IsBoot to NonBoot * moduleGraphNodes merges dependencies of IsBoot and NonBoot nodes. The result is a properly quotiented dependency graph which contains no hs-boot files nor hs-boot file edges. Why this didn't cause endless issues when compiling with boot files, we will never know. - - - - - c84dc506 by Matthew Pickering at 2022-03-01T16:23:10-05:00 driver: Properly add an edge between a .hs and its hs-boot file As noted in #21071 we were missing adding this edge so there were situations where the .hs file would get compiled before the .hs-boot file which leads to issues with -j. I fixed this properly by adding the edge in downsweep so the definition of nodeDependencies can be simplified to avoid adding this dummy edge in. There are plenty of tests which seem to have these redundant boot files anyway so no new test. #21094 tracks the more general issue of identifying redundant hs-boot and SOURCE imports. - - - - - 7aeb6d29 by sheaf at 2022-03-01T16:23:51-05:00 Core Lint: collect args through floatable ticks We were not looking through floatable ticks when collecting arguments in Core Lint, which caused `checkCanEtaExpand` to fail on something like: ```haskell reallyUnsafePtrEquality = \ @a -> (src<loc> reallyUnsafePtrEquality#) @Lifted @a @Lifted @a ``` We fix this by using `collectArgsTicks tickishFloatable` instead of `collectArgs`, to be consistent with the behaviour of eta expansion outlined in Note [Eta expansion and source notes] in GHC.Core.Opt.Arity. Fixes #21152. - - - - - 75caafaa by Matthew Pickering at 2022-03-02T01:14:59-05:00 Ticky profiling improvements. This adds a number of changes to ticky-ticky profiling. When an executable is profiled with IPE profiling it's now possible to associate id-related ticky counters to their source location. This works by emitting the info table address as part of the counter which can be looked up in the IPE table. Add a `-ticky-ap-thunk` flag. This flag prevents the use of some standard thunks which are precompiled into the RTS. This means reduced cache locality and increased code size. But it allows better attribution of execution cost to specific source locations instead of simple attributing it to the standard thunk. ticky-ticky now uses the `arg` field to emit additional information about counters in json format. When ticky-ticky is used in combination with the eventlog eventlog2html can be used to generate a html table from the eventlog similar to the old text output for ticky-ticky. - - - - - aeea6bd5 by doyougnu at 2022-03-02T01:15:39-05:00 StgToCmm.cgTopBinding: no isNCG, use binBlobThresh This is a one line change. It is a fixup from MR!7325, was pointed out in review of MR!7442, specifically: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7442#note_406581 The change removes isNCG check from cgTopBinding. Instead it changes the type of binBlobThresh in DynFlags from Word to Maybe Word, where a Just 0 or a Nothing indicates an infinite threshold and thus the disable CmmFileEmbed case in the original check. This improves the cohesion of the module because more NCG related Backend stuff is moved into, and checked in, StgToCmm.Config. Note, that the meaning of a Just 0 or a Nothing in binBlobThresh is indicated in a comment next to its field in GHC.StgToCmm.Config. DynFlags: binBlobThresh: Word -> Maybe Word StgToCmm.Config: binBlobThesh add not ncg check DynFlags.binBlob: move Just 0 check to dflags init StgToCmm.binBlob: only check isNCG, Just 0 check to dflags StgToCmm.Config: strictify binBlobThresh - - - - - b27b2af3 by sheaf at 2022-03-02T14:08:36-05:00 Introduce ConcreteTv metavariables This patch introduces a new kind of metavariable, by adding the constructor `ConcreteTv` to `MetaInfo`. A metavariable with `ConcreteTv` `MetaInfo`, henceforth a concrete metavariable, can only be unified with a type that is concrete (that is, a type that answers `True` to `GHC.Core.Type.isConcrete`). This solves the problem of dangling metavariables in `Concrete#` constraints: instead of emitting `Concrete# ty`, which contains a secret existential metavariable, we simply emit a primitive equality constraint `ty ~# concrete_tv` where `concrete_tv` is a fresh concrete metavariable. This means we can avoid all the complexity of canonicalising `Concrete#` constraints, as we can just re-use the existing machinery for `~#`. To finish things up, this patch then removes the `Concrete#` special predicate, and instead introduces the special predicate `IsRefl#` which enforces that a coercion is reflexive. Such a constraint is needed because the canonicaliser is quite happy to rewrite an equality constraint such as `ty ~# concrete_tv`, but such a rewriting is not handled by the rest of the compiler currently, as we need to make use of the resulting coercion, as outlined in the FixedRuntimeRep plan. The big upside of this approach (on top of simplifying the code) is that we can now selectively implement PHASE 2 of FixedRuntimeRep, by changing individual calls of `hasFixedRuntimeRep_MustBeRefl` to `hasFixedRuntimeRep` and making use of the obtained coercion. - - - - - 81b7c436 by Matthew Pickering at 2022-03-02T14:09:13-05:00 Make -dannot-lint not panic on let bound type variables After certain simplifier passes we end up with let bound type variables which are immediately inlined in the next pass. The core diff utility implemented by -dannot-lint failed to take these into account and paniced. Progress towards #20965 - - - - - f596c91a by sheaf at 2022-03-02T14:09:51-05:00 Improve out-of-order inferred type variables Don't instantiate type variables for :type in `GHC.Tc.Gen.App.tcInstFun`, to avoid inconsistently instantianting `r1` but not `r2` in the type forall {r1} (a :: TYPE r1) {r2} (b :: TYPE r2). ... This fixes #21088. This patch also changes the primop pretty-printer to ensure that we put all the inferred type variables first. For example, the type of reallyUnsafePtrEquality# is now forall {l :: Levity} {k :: Levity} (a :: TYPE (BoxedRep l)) (b :: TYPE (BoxedRep k)). a -> b -> Int# This means we avoid running into issue #21088 entirely with the types of primops. Users can still write a type signature where the inferred type variables don't come first, however. This change to primops had a knock-on consequence, revealing that we were sometimes performing eta reduction on keepAlive#. This patch updates tryEtaReduce to avoid eta reducing functions with no binding, bringing it in line with tryEtaReducePrep, and thus fixing #21090. - - - - - 1617fed3 by Richard Eisenberg at 2022-03-02T14:10:28-05:00 Make inert_cycle_breakers into a stack. Close #20231. - - - - - c8652a0a by Richard Eisenberg at 2022-03-02T14:11:03-05:00 Make Constraint not *apart* from Type. More details in Note [coreView vs tcView] Close #21092. - - - - - 91a10cb0 by doyougnu at 2022-03-02T14:11:43-05:00 GenStgAlt 3-tuple synonym --> Record type This commit alters GenStgAlt from a type synonym to a Record with field accessors. In pursuit of #21078, this is not a required change but cleans up several areas for nicer code in the upcoming js-backend, and in GHC itself. GenStgAlt: 3-tuple -> record Stg.Utils: GenStgAlt 3-tuple -> record Stg.Stats: StgAlt 3-tuple --> record Stg.InferTags.Rewrite: StgAlt 3-tuple -> record Stg.FVs: GenStgAlt 3-tuple -> record Stg.CSE: GenStgAlt 3-tuple -> record Stg.InferTags: GenStgAlt 3-tuple --> record Stg.Debug: GenStgAlt 3-tuple --> record Stg.Lift.Analysis: GenStgAlt 3-tuple --> record Stg.Lift: GenStgAlt 3-tuple --> record ByteCode.Instr: GenStgAlt 3-tuple --> record Stg.Syntax: add GenStgAlt helper functions Stg.Unarise: GenStgAlt 3-tuple --> record Stg.BcPrep: GenStgAlt 3-tuple --> record CoreToStg: GenStgAlt 3-tuple --> record StgToCmm.Expr: GenStgAlt 3-tuple --> record StgToCmm.Bind: GenStgAlt 3-tuple --> record StgToByteCode: GenStgAlt 3-tuple --> record Stg.Lint: GenStgAlt 3-tuple --> record Stg.Syntax: strictify GenStgAlt GenStgAlt: add haddock, some cleanup fixup: remove calls to pure, single ViewPattern StgToByteCode: use case over viewpatterns - - - - - 73864f00 by Matthew Pickering at 2022-03-02T14:12:19-05:00 base: Remove default method from bitraversable The default instance leads to an infinite loop. bisequenceA is defined in terms of bisquence which is defined in terms of bitraverse. ``` bitraverse f g = (defn of bitraverse) bisequenceA . bimap f g = (defn of bisequenceA) bitraverse id id . bimap f g = (defn of bitraverse) ... ``` Any instances defined without an explicitly implementation are currently broken, therefore removing it will alert users to an issue in their code. CLC issue: https://github.com/haskell/core-libraries-committee/issues/47 Fixes #20329 #18901 - - - - - 9579bf35 by Matthew Pickering at 2022-03-02T14:12:54-05:00 ci: Add check to CI to ensure compiler uses correct BIGNUM_BACKEND - - - - - c48a7c3a by Sylvain Henry at 2022-03-03T07:37:12-05:00 Use Word64# primops in Word64 Num instance Taken froù!3658 - - - - - ce65d0cc by Matthew Pickering at 2022-03-03T07:37:48-05:00 hadrian: Correctly set whether we have a debug compiler when running tests For example, running the `slow-validate` flavour would incorrectly run the T16135 test which would fail with an assertion error, despite the fact that is should be skipped when we have a debug compiler. - - - - - e0c3e757 by Matthew Pickering at 2022-03-03T13:48:41-05:00 docs: Add note to unsafeCoerce function that you might want to use coerce [skip ci] Fixes #15429 - - - - - 559d4cf3 by Matthew Pickering at 2022-03-03T13:49:17-05:00 docs: Add note to RULES documentation about locally bound variables [skip ci] Fixes #20100 - - - - - c534b3dd by Matthew Pickering at 2022-03-03T13:49:53-05:00 Replace ad-hoc CPP with constant from GHC.Utils.Constant Fixes #21154 - - - - - de56cc7e by Krzysztof Gogolewski at 2022-03-04T12:44:26-05:00 Update documentation of LiberalTypeSynonyms We no longer require LiberalTypeSynonyms to use 'forall' or an unboxed tuple in a synonym. I also removed that kind checking before expanding synonyms "could be changed". This was true when type synonyms were thought of macros, but with the extensions such as SAKS or matchability I don't see it changing. - - - - - c0a39259 by Simon Jakobi at 2022-03-04T12:45:01-05:00 base: Mark GHC.Bits not-home for haddock Most (all) of the exports are re-exported from the preferable Data.Bits. - - - - - 3570eda5 by Sylvain Henry at 2022-03-04T12:45:42-05:00 Fix comments about Int64/Word64 primops - - - - - 6f84ee33 by Artem Pelenitsyn at 2022-03-05T01:06:47-05:00 remove MonadFail instances of ST CLC proposal: https://github.com/haskell/core-libraries-committee/issues/33 The instances had `fail` implemented in terms of `error`, whereas the idea of the `MonadFail` class is that the `fail` method should be implemented in terms of the monad itself. - - - - - 584cd5ae by sheaf at 2022-03-05T01:07:25-05:00 Don't allow Float#/Double# literal patterns This patch does the following two things: 1. Fix the check in Core Lint to properly throw an error when it comes across Float#/Double# literal patterns. The check was incorrect before, because it expected the type to be Float/Double instead of Float#/Double#. 2. Add an error in the parser when the user writes a floating-point literal pattern such as `case x of { 2.0## -> ... }`. Fixes #21115 - - - - - 706deee0 by Greg Steuck at 2022-03-05T17:44:10-08:00 Make T20214 terminate promptly be setting input to /dev/null It was hanging and timing out on OpenBSD before. - - - - - 14e90098 by Simon Peyton Jones at 2022-03-07T14:05:41-05:00 Always generalise top-level bindings Fix #21023 by always generalising top-level binding; change the documentation of -XMonoLocalBinds to match. - - - - - c9c31c3c by Matthew Pickering at 2022-03-07T14:06:16-05:00 hadrian: Add little flavour transformer to build stage2 with assertions This can be useful to build a `perf+assertions` build or even better `default+no_profiled_libs+omit_pragmas+assertions`. - - - - - 89c14a6c by Matthew Pickering at 2022-03-07T14:06:16-05:00 ci: Convert all deb10 make jobs into hadrian jobs This is the first step in converting all the CI configs to use hadrian rather than make. (#21129) The metrics increase due to hadrian using --hyperlinked-source for haddock builds. (See #21156) ------------------------- Metric Increase: haddock.Cabal haddock.base haddock.compiler ------------------------- - - - - - 7bfae2ee by Matthew Pickering at 2022-03-07T14:06:16-05:00 Replace use of BIN_DIST_PREP_TAR_COMP with BIN_DIST_NAME And adds a check to make sure we are not accidently settings BIN_DIST_PREP_TAR_COMP when using hadrian. - - - - - 5b35ca58 by Matthew Pickering at 2022-03-07T14:06:16-05:00 Fix gen_contents_index logic for hadrian bindist - - - - - 273bc133 by Krzysztof Gogolewski at 2022-03-07T14:06:52-05:00 Fix reporting constraints in pprTcSolverReportMsg 'no_instance_msg' and 'no_deduce_msg' were omitting the first wanted. - - - - - 5874a30a by Simon Jakobi at 2022-03-07T14:07:28-05:00 Improve setBit for Natural Previously the default definition was used, which involved allocating intermediate Natural values. Fixes #21173. - - - - - 7a02aeb8 by Matthew Pickering at 2022-03-07T14:08:03-05:00 Remove leftover trace in testsuite - - - - - 6ce6c250 by Andreas Klebinger at 2022-03-07T23:48:56-05:00 Expand and improve the Note [Strict Worker Ids]. I've added an explicit mention of the invariants surrounding those. As well as adding more direct cross references to the Strict Field Invariant. - - - - - d0f892fe by Ryan Scott at 2022-03-07T23:49:32-05:00 Delete GenericKind_ in favor of GenericKind_DC When deriving a `Generic1` instance, we need to know what the last type variable of a data type is. Previously, there were two mechanisms to determine this information: * `GenericKind_`, where `Gen1_` stored the last type variable of a data type constructor (i.e., the `tyConTyVars`). * `GenericKind_DC`, where `Gen1_DC` stored the last universally quantified type variable in a data constructor (i.e., the `dataConUnivTyVars`). These had different use cases, as `GenericKind_` was used for generating `Rep(1)` instances, while `GenericKind_DC` was used for generating `from(1)` and `to(1)` implementations. This was already a bit confusing, but things went from confusing to outright wrong after !6976. This is because after !6976, the `deriving` machinery stopped using `tyConTyVars` in favor of `dataConUnivTyVars`. Well, everywhere with the sole exception of `GenericKind_`, which still continued to use `tyConTyVars`. This lead to disaster when deriving a `Generic1` instance for a GADT family instance, as the `tyConTyVars` do not match the `dataConUnivTyVars`. (See #21185.) The fix is to stop using `GenericKind_` and replace it with `GenericKind_DC`. For the most part, this proves relatively straightforward. Some highlights: * The `forgetArgVar` function was deleted entirely, as it no longer proved necessary after `GenericKind_`'s demise. * The substitution that maps from the last type variable to `Any` (see `Note [Generating a correctly typed Rep instance]`) had to be moved from `tc_mkRepTy` to `tc_mkRepFamInsts`, as `tc_mkRepTy` no longer has access to the last type variable. Fixes #21185. - - - - - a60ddffd by Matthew Pickering at 2022-03-08T22:51:37+00:00 Move bootstrap and cabal-reinstall test jobs to nightly CI is creaking under the pressure of too many jobs so attempt to reduce the strain by removing a couple of jobs. - - - - - 7abe3288 by Matthew Pickering at 2022-03-09T10:24:15+00:00 Add 10 minute timeout to linters job - - - - - 3cf75ede by Matthew Pickering at 2022-03-09T10:24:16+00:00 Revert "hadrian: Correctly set whether we have a debug compiler when running tests" Needing the arguments for "GHC/Utils/Constant.hs" implies a dependency on the previous stage compiler. Whilst we work out how to get around this I will just revert this commit (as it only affects running the testsuite in debug way). This reverts commit ce65d0cceda4a028f30deafa3c39d40a250acc6a. - - - - - 18b9ba56 by Matthew Pickering at 2022-03-09T11:07:23+00:00 ci: Fix save_cache function Each interation of saving the cache would copy the whole `cabal` store into a subfolder in the CACHE_DIR rather than copying the contents of the cabal store into the cache dir. This resulted in a cache which looked like: ``` /builds/ghc/ghc/cabal-cache/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/ ``` So it would get one layer deeper every CI run and take longer and longer to compress. - - - - - bc684dfb by Ben Gamari at 2022-03-10T03:20:07-05:00 mr-template: Mention timeframe for review - - - - - 7f5f4ede by Vladislav Zavialov at 2022-03-10T03:20:43-05:00 Bump submodules: containers, exceptions GHC Proposal #371 requires TypeOperators to use type equality a~b. This submodule update pulls in the appropriate forward-compatibility changes in 'libraries/containers' and 'libraries/exceptions' - - - - - 8532b8a9 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Add an inline pragma to lookupVarEnv The containers bump reduced the size of the Data.IntMap.Internal.lookup function so that it no longer experienced W/W. This means that the size of lookupVarEnv increased over the inlining threshold and it wasn't inlined into the hot code path in substTyVar. See containers#821, #21159 and !7638 for some more explanation. ------------------------- Metric Decrease: LargeRecord T12227 T13386 T15703 T18223 T5030 T8095 T9872a T9872b T9872c TcPlugin_RewritePerf ------------------------- - - - - - 844cf1e1 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Normalise output of T10970 test The output of this test changes each time the containers submodule version updates. It's easier to apply the version normaliser so that the test checks that there is a version number, but not which one it is. - - - - - 24b6af26 by Ryan Scott at 2022-03-11T19:56:28-05:00 Refactor tcDeriving to generate tyfam insts before any bindings Previously, there was an awful hack in `genInst` (now called `genInstBinds` after this patch) where we had to return a continutation rather than directly returning the bindings for a derived instance. This was done for staging purposes, as we had to first infer the instance contexts for derived instances and then feed these contexts into the continuations to ensure the generated instance bindings had accurate instance contexts. `Note [Staging of tcDeriving]` in `GHC.Tc.Deriving` described this confusing state of affairs. The root cause of this confusing design was the fact that `genInst` was trying to generate instance bindings and associated type family instances for derived instances simultaneously. This really isn't possible, however: as `Note [Staging of tcDeriving]` explains, one needs to have access to the associated type family instances before one can properly infer the instance contexts for derived instances. The use of continuation-returning style was an attempt to circumvent this dependency, but it did so in an awkward way. This patch detangles this awkwardness by splitting up `genInst` into two functions: `genFamInsts` (for associated type family instances) and `genInstBinds` (for instance bindings). Now, the `tcDeriving` function calls `genFamInsts` and brings all the family instances into scope before calling `genInstBinds`. This removes the need for the awkward continuation-returning style seen in the previous version of `genInst`, making the code easier to understand. There are some knock-on changes as well: 1. `hasStockDeriving` now needs to return two separate functions: one that describes how to generate family instances for a stock-derived instance, and another that describes how to generate the instance bindings. I factored out this pattern into a new `StockGenFns` data type. 2. While documenting `StockGenFns`, I realized that there was some inconsistency regarding which `StockGenFns` functions needed which arguments. In particular, the function in `GHC.Tc.Deriv.Generics` which generates `Rep(1)` instances did not take a `SrcSpan` like other `gen_*` functions did, and it included an extra `[Type]` argument that was entirely redundant. As a consequence, I refactored the code in `GHC.Tc.Deriv.Generics` to more closely resemble other `gen_*` functions. A happy result of all this is that all `StockGenFns` functions now take exactly the same arguments, which makes everything more uniform. This is purely a refactoring that should not have any effect on user-observable behavior. The new design paves the way for an eventual fix for #20719. - - - - - 62caaa9b by Ben Gamari at 2022-03-11T19:57:03-05:00 gitlab-ci: Use the linters image in hlint job As the `hlint` executable is only available in the linters image. Fixes #21146. - - - - - 4abd7eb0 by Matthew Pickering at 2022-03-11T19:57:38-05:00 Remove partOfGhci check in the loader This special logic has been part of GHC ever since template haskell was introduced in 9af77fa423926fbda946b31e174173d0ec5ebac8. It's hard to believe in any case that this special logic pays its way at all. Given * The list is out-of-date, which has potential to lead to miscompilation when using "editline", which was removed in 2010 (46aed8a4). * The performance benefit seems negligable as each load only happens once anyway and packages specified by package flags are preloaded into the linker state at the start of compilation. Therefore we just remove this logic. Fixes #19791 - - - - - c40cbaa2 by Andreas Klebinger at 2022-03-11T19:58:14-05:00 Improve -dtag-inference-checks checks. FUN closures don't get tagged when evaluated. So no point in checking their tags. - - - - - ab00d23b by Simon Jakobi at 2022-03-11T19:58:49-05:00 Improve clearBit and complementBit for Natural Also optimize bigNatComplementBit#. Fixes #21175, #21181, #21194. - - - - - a6d8facb by Sebastian Graf at 2022-03-11T19:59:24-05:00 gitignore all (build) directories headed by _ - - - - - 524795fe by Sebastian Graf at 2022-03-11T19:59:24-05:00 Demand: Document why we need three additional equations of multSubDmd - - - - - 6bdcd557 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make 64-bit word splitting for 32-bit targets respect target endianness This used to been broken for little-endian targets. - - - - - 9e67c69e by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix Double# literal payload for 32-bit targets Contrary to the legacy comment, the splitting didn't happen and we ended up with a single StgWord64 literal in the output code! Let's just do the splitting here. - - - - - 1eee2e28 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: use __builtin versions of memcpyish functions to fix type mismatch Our memcpyish primop's type signatures doesn't match the C type signatures. It's not a problem for typical archs, since their C ABI permits dropping the result, but it doesn't work for wasm. The previous logic would cast the memcpyish function pointer to an incorrect type and perform an indirect call, which results in a runtime trap on wasm. The most straightforward fix is: don't emit EFF_ for memcpyish functions. Since we don't want to include extra headers in .hc to bring in their prototypes, we can just use the __builtin versions. - - - - - 9d8d4837 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: emit __builtin_unreachable() when CmmSwitch doesn't contain fallback case Otherwise the C compiler may complain "warning: non-void function does not return a value in all control paths [-Wreturn-type]". - - - - - 27da5540 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make floatToWord32/doubleToWord64 faster Use castFloatToWord32/castDoubleToWord64 in base to perform the reinterpret cast. - - - - - c98e8332 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix -Wunused-value warning in ASSIGN_BaseReg When ASSIGN_BaseReg is a no-op, we shouldn't generate any C code, otherwise C compiler complains a bunch of -Wunused-value warnings when doing unregisterised codegen. - - - - - 5932247c by Ben Gamari at 2022-03-11T20:00:36-05:00 users guide: Eliminate spurious \spxentry mentions We were failing to pass the style file to `makeindex`, as is done by the mklatex configuration generated by Sphinx. Fixes #20913. - - - - - e40cf4ef by Simon Jakobi at 2022-03-11T20:01:11-05:00 ghc-bignum: Tweak integerOr The result of ORing two BigNats is always greater or equal to the larger of the two. Therefore it is safe to skip the magnitude checks of integerFromBigNat#. - - - - - cf081476 by Vladislav Zavialov at 2022-03-12T07:02:40-05:00 checkUnboxedLitPat: use non-fatal addError This enables GHC to report more parse errors in a single pass. - - - - - 7fe07143 by Andreas Klebinger at 2022-03-12T07:03:16-05:00 Rename -fprof-late-ccs to -fprof-late - - - - - 88a94541 by Sylvain Henry at 2022-03-12T07:03:56-05:00 Hadrian: avoid useless allocations in trackArgument Cf ticky report before the change: Entries Alloc Alloc'd Non-void Arguments STG Name -------------------------------------------------------------------------------- 696987 29044128 0 1 L main:Target.trackArgument_go5{v r24kY} (fun) - - - - - 2509d676 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: avoid allocating in stageString (#19209) - - - - - c062fac0 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: remove useless imports Added for no reason in 7ce1b694f7be7fbf6e2d7b7eb0639e61fbe358c6 - - - - - c82fb934 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: avoid allocations in WayUnit's Read instance (#19209) - - - - - ed04aed2 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: use IntSet Binary instance for Way (#19209) - - - - - ad835531 by Simon Peyton Jones at 2022-03-13T18:12:12-04:00 Fix bug in weak loop-breakers in OccurAnal Note [Weak loop breakers] explains why we need to track variables free in RHS of rules. But we need to do this for /inactive/ rules as well as active ones, unlike the rhs_fv_env stuff. So we now have two fields in node Details, one for free vars of active rules, and one for free vars of all rules. This was shown up by #20820, which is now fixed. - - - - - 76b94b72 by Sebastian Graf at 2022-03-13T18:12:48-04:00 Worker/wrapper: Preserve float barriers (#21150) Issue #21150 shows that worker/wrapper allocated a worker function for a function with multiple calls that said "called at most once" when the first argument was absent. That's bad! This patch makes it so that WW preserves at least one non-one-shot value lambda (see `Note [Preserving float barriers]`) by passing around `void#` in place of absent arguments. Fixes #21150. Since the fix is pretty similar to `Note [Protecting the last value argument]`, I put the logic in `mkWorkerArgs`. There I realised (#21204) that `-ffun-to-thunk` is basically useless with `-ffull-laziness`, so I deprecated the flag, simplified and split into `needsVoidWorkerArg`/`addVoidWorkerArg`. SpecConstr is another client of that API. Fixes #21204. Metric Decrease: T14683 - - - - - 97db789e by romes at 2022-03-14T11:36:39-04:00 Fix up Note [Bind free vars] Move GHC-specific comments from Language.Haskell.Syntax.Binds to GHC.Hs.Binds It looks like the Note was deleted but there were actually two copies of it. L.H.S.B no longer references it, and GHC.Hs.Binds keeps an updated copy. (See #19252) There are other duplicated notes -- they will be fixed in the next commit - - - - - 135888dd by romes at 2022-03-14T11:36:39-04:00 TTG Pull AbsBinds and ABExport out of the main AST AbsBinds and ABExport both depended on the typechecker, and were thus removed from the main AST Expr. CollectPass now has a new function `collectXXHsBindsLR` used for the new HsBinds extension point Bumped haddock submodule to work with AST changes. The removed Notes from Language.Haskell.Syntax.Binds were duplicated (and not referenced) and the copies in GHC.Hs.Binds are kept (and referenced there). (See #19252) - - - - - 106413f0 by sheaf at 2022-03-14T11:37:21-04:00 Add two coercion optimisation perf tests - - - - - 8eadea67 by sheaf at 2022-03-14T15:08:24-04:00 Fix isLiftedType_maybe and handle fallout As #20837 pointed out, `isLiftedType_maybe` returned `Just False` in many situations where it should return `Nothing`, because it didn't take into account type families or type variables. In this patch, we fix this issue. We rename `isLiftedType_maybe` to `typeLevity_maybe`, which now returns a `Levity` instead of a boolean. We now return `Nothing` for types with kinds of the form `TYPE (F a1 ... an)` for a type family `F`, as well as `TYPE (BoxedRep l)` where `l` is a type variable. This fix caused several other problems, as other parts of the compiler were relying on `isLiftedType_maybe` returning a `Just` value, and were now panicking after the above fix. There were two main situations in which panics occurred: 1. Issues involving the let/app invariant. To uphold that invariant, we need to know whether something is lifted or not. If we get an answer of `Nothing` from `isLiftedType_maybe`, then we don't know what to do. As this invariant isn't particularly invariant, we can change the affected functions to not panic, e.g. by behaving the same in the `Just False` case and in the `Nothing` case (meaning: no observable change in behaviour compared to before). 2. Typechecking of data (/newtype) constructor patterns. Some programs involving patterns with unknown representations were accepted, such as T20363. Now that we are stricter, this caused further issues, culminating in Core Lint errors. However, the behaviour was incorrect the whole time; the incorrectness only being revealed by this change, not triggered by it. This patch fixes this by overhauling where the representation polymorphism involving pattern matching are done. Instead of doing it in `tcMatches`, we instead ensure that the `matchExpected` functions such as `matchExpectedFunTys`, `matchActualFunTySigma`, `matchActualFunTysRho` allow return argument pattern types which have a fixed RuntimeRep (as defined in Note [Fixed RuntimeRep]). This ensures that the pattern matching code only ever handles types with a known runtime representation. One exception was that patterns with an unknown representation type could sneak in via `tcConPat`, which points to a missing representation-polymorphism check, which this patch now adds. This means that we now reject the program in #20363, at least until we implement PHASE 2 of FixedRuntimeRep (allowing type families in RuntimeRep positions). The aforementioned refactoring, in which checks have been moved to `matchExpected` functions, is a first step in implementing PHASE 2 for patterns. Fixes #20837 - - - - - 8ff32124 by Sebastian Graf at 2022-03-14T15:09:01-04:00 DmdAnal: Don't unbox recursive data types (#11545) As `Note [Demand analysis for recursive data constructors]` describes, we now refrain from unboxing recursive data type arguments, for two reasons: 1. Relating to run/alloc perf: Similar to `Note [CPR for recursive data constructors]`, it seldomly improves run/alloc performance if we just unbox a finite number of layers of a potentially huge data structure. 2. Relating to ghc/alloc perf: Inductive definitions on single-product recursive data types like the one in T11545 will (diverge, and) have very deep demand signatures before any other abortion mechanism in Demand analysis is triggered. That leads to great and unnecessary churn on Demand analysis when ultimately we will never make use of any nested strictness information anyway. Conclusion: Discard nested demand and boxity information on such recursive types with the help of `Note [Detecting recursive data constructors]`. I also implemented `GHC.Types.Unique.MemoFun.memoiseUniqueFun` in order to avoid the overhead of repeated calls to `GHC.Core.Opt.WorkWrap.Utils.isRecDataCon`. It's nice and simple and guards against some smaller regressions in T9233 and T16577. ghc/alloc performance-wise, this patch is a very clear win: Test Metric value New value Change --------------------------------------------------------------------------------------- LargeRecord(normal) ghc/alloc 6,141,071,720 6,099,871,216 -0.7% MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,740,973,040 2,705,146,640 -1.3% T11545(normal) ghc/alloc 945,475,492 85,768,928 -90.9% GOOD T13056(optasm) ghc/alloc 370,245,880 326,980,632 -11.7% GOOD T18304(normal) ghc/alloc 90,933,944 76,998,064 -15.3% GOOD T9872a(normal) ghc/alloc 1,800,576,840 1,792,348,760 -0.5% T9872b(normal) ghc/alloc 2,086,492,432 2,073,991,848 -0.6% T9872c(normal) ghc/alloc 1,750,491,240 1,737,797,832 -0.7% TcPlugin_RewritePerf(normal) ghc/alloc 2,286,813,400 2,270,957,896 -0.7% geo. mean -2.9% No noteworthy change in run/alloc either. NoFib results show slight wins, too: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- constraints -1.9% -1.4% fasta -3.6% -2.7% reverse-complem -0.3% -0.9% treejoin -0.0% -0.3% -------------------------------------------------------------------------------- Min -3.6% -2.7% Max +0.1% +0.1% Geometric Mean -0.1% -0.1% Metric Decrease: T11545 T13056 T18304 - - - - - ab618309 by Vladislav Zavialov at 2022-03-15T18:34:38+03:00 Export (~) from Data.Type.Equality (#18862) * Users can define their own (~) type operator * Haddock can display documentation for the built-in (~) * New transitional warnings implemented: -Wtype-equality-out-of-scope -Wtype-equality-requires-operators Updates the haddock submodule. - - - - - 577135bf by Aaron Allen at 2022-03-16T02:27:48-04:00 Convert Diagnostics in GHC.Tc.Gen.Foreign Converts all uses of 'TcRnUnknownMessage' to proper diagnostics. - - - - - c1fed9da by Aaron Allen at 2022-03-16T02:27:48-04:00 Suggest FFI extensions as hints (#20116) - Use extension suggestion hints instead of suggesting extensions in the error message body for several FFI errors. - Adds a test case for `TcRnForeignImportPrimExtNotSet` - - - - - a33d1045 by Zubin Duggal at 2022-03-16T02:28:24-04:00 TH: allow negative patterns in quotes (#20711) We still don't allow negative overloaded patterns. Earler all negative patterns were treated as negative overloaded patterns. Now, we expliclty check the extension field to see if the pattern is actually a negative overloaded pattern - - - - - 1575c4a5 by Sebastian Graf at 2022-03-16T02:29:03-04:00 Demand: Let `Boxed` win in `lubBoxity` (#21119) Previously, we let `Unboxed` win in `lubBoxity`, which is unsoundly optimistic in terms ob Boxity analysis. "Unsoundly" in the sense that we sometimes unbox parameters that we better shouldn't unbox. Examples are #18907 and T19871.absent. Until now, we thought that this hack pulled its weight becuase it worked around some shortcomings of the phase separation between Boxity analysis and CPR analysis. But it is a gross hack which caused regressions itself that needed all kinds of fixes and workarounds. See for example #20767. It became impossible to work with in !7599, so I want to remove it. For example, at the moment, `lubDmd B dmd` will not unbox `dmd`, but `lubDmd A dmd` will. Given that `B` is supposed to be the bottom element of the lattice, it's hardly justifiable to get a better demand when `lub`bing with `A`. The consequence of letting `Boxed` win in `lubBoxity` is that we *would* regress #2387, #16040 and parts of #5075 and T19871.sumIO, until Boxity and CPR are able to communicate better. Fortunately, that is not the case since I could tweak the other source of optimism in Boxity analysis that is described in `Note [Unboxed demand on function bodies returning small products]` so that we *recursively* assume unboxed demands on function bodies returning small products. See the updated Note. `Note [Boxity for bottoming functions]` describes why we need bottoming functions to have signatures that say that they deeply unbox their arguments. In so doing, I had to tweak `finaliseArgBoxities` so that it will never unbox recursive data constructors. This is in line with our handling of them in CPR. I updated `Note [Which types are unboxed?]` to reflect that. In turn we fix #21119, #20767, #18907, T19871.absent and get a much simpler implementation (at least to think about). We can also drop the very ad-hoc definition of `deferAfterPreciseException` and its Note in favor of the simple, intuitive definition we used to have. Metric Decrease: T16875 T18223 T18698a T18698b hard_hole_fits Metric Increase: LargeRecord MultiComponentModulesRecomp T15703 T8095 T9872d Out of all the regresions, only the one in T9872d doesn't vanish in a perf build, where the compiler is bootstrapped with -O2 and thus SpecConstr. Reason for regressions: * T9872d is due to `ty_co_subst` taking its `LiftingContext` boxed. That is because the context is passed to a function argument, for example in `liftCoSubstTyVarBndrUsing`. * In T15703, LargeRecord and T8095, we get a bit more allocations in `expand_syn` and `piResultTys`, because a `TCvSubst` isn't unboxed. In both cases that guards against reboxing in some code paths. * The same is true for MultiComponentModulesRecomp, where we get less unboxing in `GHC.Unit.Finder.$wfindInstalledHomeModule`. In a perf build, allocations actually *improve* by over 4%! Results on NoFib: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- awards -0.4% +0.3% cacheprof -0.3% +2.4% fft -1.5% -5.1% fibheaps +1.2% +0.8% fluid -0.3% -0.1% ida +0.4% +0.9% k-nucleotide +0.4% -0.1% last-piece +10.5% +13.9% lift -4.4% +3.5% mandel2 -99.7% -99.8% mate -0.4% +3.6% parser -1.0% +0.1% puzzle -11.6% +6.5% reverse-complem -3.0% +2.0% scs -0.5% +0.1% sphere -0.4% -0.2% wave4main -8.2% -0.3% -------------------------------------------------------------------------------- Summary excludes mandel2 because of excessive bias Min -11.6% -5.1% Max +10.5% +13.9% Geometric Mean -0.2% +0.3% -------------------------------------------------------------------------------- Not bad for a bug fix. The regression in `last-piece` could become a win if SpecConstr would work on non-recursive functions. The regression in `fibheaps` is due to `Note [Reboxed crud for bottoming calls]`, e.g., #21128. - - - - - bb779b90 by sheaf at 2022-03-16T02:29:42-04:00 Add a regression test for #21130 This problem was due to a bug in cloneWanted, which was incorrectly creating a coercion hole to hold an evidence variable. This bug was introduced by 8bb52d91 and fixed in 81740ce8. Fixes #21130 - - - - - 0f0e2394 by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Initial Windows C++ exception unwinding support - - - - - 36d20d4d by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Fix ADDR32NB relocations on Windows - - - - - 8a516527 by Tamar Christina at 2022-03-17T10:16:37-04:00 testsuite: properly escape string paths - - - - - 1a0dd008 by sheaf at 2022-03-17T10:17:13-04:00 Hadrian: account for change in late-ccs flag The late cost centre flag was renamed from -fprof-late-ccs to -fprof-late in 7fe07143, but this change hadn't been propagated to Hadrian. - - - - - 8561c1af by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor HsBracket - - - - - 19163397 by romes at 2022-03-18T05:10:58-04:00 Type-checking untyped brackets When HsExpr GhcTc, the HsBracket constructor should hold a HsBracket GhcRn, rather than an HsBracket GhcTc. We make use of the HsBracket p extension constructor (XBracket (XXBracket p)) to hold an HsBracket GhcRn when the pass is GhcTc See !4782 https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - 310890a5 by romes at 2022-03-18T05:10:58-04:00 Separate constructors for typed and untyped brackets Split HsBracket into HsTypedBracket and HsUntypedBracket. Unfortunately, we still cannot get rid of instance XXTypedBracket GhcTc = HsTypedBracket GhcRn despite no longer requiring it for typechecking, but rather because the TH desugarer works on GhcRn rather than GhcTc (See GHC.HsToCore.Quote) - - - - - 4a2567f5 by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor bracket for desugaring during tc When desugaring a bracket we want to desugar /renamed/ rather than /typechecked/ code; So in (HsExpr GhcTc) tree, we must have a (HsExpr GhcRn) for the quotation itself. This commit reworks the TTG refactor on typed and untyped brackets by storing the /renamed/ code in the bracket field extension rather than in the constructor extension in `HsQuote` (previously called `HsUntypedBracket`) See Note [The life cycle of a TH quotation] and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - b056adc8 by romes at 2022-03-18T05:10:58-04:00 TTG: Make HsQuote GhcTc isomorphic to NoExtField An untyped bracket `HsQuote p` can never be constructed with `p ~ GhcTc`. This is because we don't typecheck `HsQuote` at all. That's OK, because we also never use `HsQuote GhcTc`. To enforce this at the type level we make `HsQuote GhcTc` isomorphic to `NoExtField` and impossible to construct otherwise, by using TTG field extensions to make all constructors, except for `XQuote` (which takes `NoExtField`), unconstructable, with `DataConCantHappen` This is explained more in detail in Note [The life cycle of a TH quotation] Related discussion: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - ac3b2e7d by romes at 2022-03-18T05:10:58-04:00 TTG: TH brackets finishing touches Rewrite the critical notes and fix outdated ones, use `HsQuote GhcRn` (in `HsBracketTc`) for desugaring regardless of the bracket being typed or untyped, remove unused `EpAnn` from `Hs*Bracket GhcRn`, zonkExpr factor out common brackets code, ppr_expr factor out common brackets code, and fix tests, to finish MR https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782. ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - d147428a by Ben Gamari at 2022-03-18T05:11:35-04:00 codeGen: Fix signedness of jump table indexing Previously while constructing the jump table index we would zero-extend the discriminant before subtracting the start of the jump-table. This goes subtly wrong in the case of a sub-word, signed discriminant, as described in the included Note. Fix this in both the PPC and X86 NCGs. Fixes #21186. - - - - - 435a3d5d by Ben Gamari at 2022-03-18T05:11:35-04:00 testsuite: Add test for #21186 - - - - - e9d8de93 by Zubin Duggal at 2022-03-19T07:35:49-04:00 TH: Fix pretty printing of newtypes with operators and GADT syntax (#20868) The pretty printer for regular data types already accounted for these, and had some duplication with the newtype pretty printer. Factoring the logic out into a common function and using it for both newtypes and data declarations is enough to fix the bug. - - - - - 244da9eb by sheaf at 2022-03-19T07:36:24-04:00 List GHC.Event.Internal in base.cabal on Windows GHC.Event.Internal was not listed in base.cabal on Windows. This caused undefined reference errors. This patch adds it back, by moving it out of the OS-specific logic in base.cabal. Fixes #21245. - - - - - d1c03719 by Andreas Klebinger at 2022-03-19T07:37:00-04:00 Compact regions: Maintain tags properly Fixes #21251 - - - - - d45bb701 by romes at 2022-03-19T07:37:36-04:00 Remove dead code HsDoRn - - - - - c842611f by nineonine at 2022-03-20T21:16:06-04:00 Revamp derived Eq instance code generation (#17240) This patch improves code generation for derived Eq instances. The idea is to use 'dataToTag' to evaluate both arguments. This allows to 'short-circuit' when tags do not match. Unfortunately, inner evals are still present when we branch on tags. This is due to the way 'dataToTag#' primop evaluates its argument in the code generator. #21207 was created to explore further optimizations. Metric Decrease: LargeRecord - - - - - 52ffd38c by Sylvain Henry at 2022-03-20T21:16:46-04:00 Avoid some SOURCE imports - - - - - b91798be by Zubin Duggal at 2022-03-23T13:39:39-04:00 hi haddock: Lex and store haddock docs in interface files Names appearing in Haddock docstrings are lexed and renamed like any other names appearing in the AST. We currently rename names irrespective of the namespace, so both type and constructor names corresponding to an identifier will appear in the docstring. Haddock will select a given name as the link destination based on its own heuristics. This patch also restricts the limitation of `-haddock` being incompatible with `Opt_KeepRawTokenStream`. The export and documenation structure is now computed in GHC and serialised in .hi files. This can be used by haddock to directly generate doc pages without reparsing or renaming the source. At the moment the operation of haddock is not modified, that's left to a future patch. Updates the haddock submodule with the minimum changes needed. - - - - - 78db231f by Cheng Shao at 2022-03-23T13:40:17-04:00 configure: bump LlvmMaxVersion to 14 LLVM 13.0.0 is released in Oct 2021, and latest head validates against LLVM 13 just fine if LlvmMaxVersion is bumped. - - - - - b06e5dd8 by Adam Sandberg Ericsson at 2022-03-23T13:40:54-04:00 docs: clarify the eventlog format documentation a little bit - - - - - 4dc62498 by Matthew Pickering at 2022-03-23T13:41:31-04:00 Fix behaviour of -Wunused-packages in ghci Ticket #21110 points out that -Wunused-packages behaves a bit unusually in GHCi. Now we define the semantics for -Wunused-packages in interactive mode as follows: * If you use -Wunused-packages on an initial load then the warning is reported. * If you explicitly set -Wunused-packages on the command line then the warning is displayed (until it is disabled) * If you then subsequently modify the set of available targets by using :load or :cd (:cd unloads everything) then the warning is (silently) turned off. This means that every :r the warning is printed if it's turned on (but you did ask for it). Fixes #21110 - - - - - fed05347 by Ben Gamari at 2022-03-23T13:42:07-04:00 rts/adjustor: Place adjustor templates in data section on all OSs In !7604 we started placing adjustor templates in the data section on Linux as some toolchains there reject relocations in the text section. However, it turns out that OpenBSD also exhibits this restriction. Fix this by *always* placing adjustor templates in the data section. Fixes #21155. - - - - - db32bb8c by Zubin Duggal at 2022-03-23T13:42:44-04:00 Improve error message when warning about unsupported LLVM version (#20958) Change the wording to make it clear that the upper bound is non-inclusive. - - - - - f214349a by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Untag function field in scavenge_PAP_payload Previously we failed to untag the function closure when scavenging the payload of a PAP, resulting in an invalid closure pointer being passed to scavenge_large_bitmap and consequently #21254. Fix this. Fixes #21254 - - - - - e6d0e287 by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Don't mark object code in markCAFs unless necessary Previously `markCAFs` would call `markObjectCode` even in non-major GCs. This is problematic since `prepareUnloadCheck` is not called in such GCs, meaning that the section index has not been updated. Fixes #21254 - - - - - 1a7cf096 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Avoid redundant imports of GHC.Driver.Session Remove GHC.Driver.Session imports that weren't considered as redundant because of the reexport of PlatformConstants. Also remove this reexport as modules using this datatype should import GHC.Platform instead. - - - - - e3f60577 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Reverse dependency between StgToCmm and Runtime.Heap.Layout - - - - - e6585ca1 by Sylvain Henry at 2022-03-23T13:44:46-04:00 Define filterOut with filter filter has fusion rules that filterOut lacks - - - - - c58d008c by Ryan Scott at 2022-03-24T06:10:43-04:00 Fix and simplify DeriveAnyClass's context inference using SubTypePredSpec As explained in `Note [Gathering and simplifying constraints for DeriveAnyClass]` in `GHC.Tc.Deriv.Infer`, `DeriveAnyClass` infers instance contexts by emitting implication constraints. Previously, these implication constraints were constructed by hand. This is a terribly trick thing to get right, as it involves a delicate interplay of skolemisation, metavariable instantiation, and `TcLevel` bumping. Despite much effort, we discovered in #20719 that the implementation was subtly incorrect, leading to valid programs being rejected. While we could scrutinize the code that manually constructs implication constraints and repair it, there is a better, less error-prone way to do things. After all, the heart of `DeriveAnyClass` is generating code which fills in each class method with defaults, e.g., `foo = $gdm_foo`. Typechecking this sort of code is tantamount to calling `tcSubTypeSigma`, as we much ensure that the type of `$gdm_foo` is a subtype of (i.e., more polymorphic than) the type of `foo`. As an added bonus, `tcSubTypeSigma` is a battle-tested function that handles skolemisation, metvariable instantiation, `TcLevel` bumping, and all other means of tricky bookkeeping correctly. With this insight, the solution to the problems uncovered in #20719 is simple: use `tcSubTypeSigma` to check if `$gdm_foo`'s type is a subtype of `foo`'s type. As a side effect, `tcSubTypeSigma` will emit exactly the implication constraint that we were attempting to construct by hand previously. Moreover, it does so correctly, fixing #20719 as a consequence. This patch implements the solution thusly: * The `PredSpec` data type (previously named `PredOrigin`) is now split into `SimplePredSpec`, which directly stores a `PredType`, and `SubTypePredSpec`, which stores the actual and expected types in a subtype check. `SubTypePredSpec` is only used for `DeriveAnyClass`; all other deriving strategies use `SimplePredSpec`. * Because `tcSubTypeSigma` manages the finer details of type variable instantiation and constraint solving under the hood, there is no longer any need to delicately split apart the method type signatures in `inferConstraintsAnyclass`. This greatly simplifies the implementation of `inferConstraintsAnyclass` and obviates the need to store skolems, metavariables, or given constraints in a `ThetaSpec` (previously named `ThetaOrigin`). As a bonus, this means that `ThetaSpec` now simply becomes a synonym for a list of `PredSpec`s, which is conceptually much simpler than it was before. * In `simplifyDeriv`, each `SubTypePredSpec` results in a call to `tcSubTypeSigma`. This is only performed for its side effect of emitting an implication constraint, which is fed to the rest of the constraint solving machinery in `simplifyDeriv`. I have updated `Note [Gathering and simplifying constraints for DeriveAnyClass]` to explain this in more detail. To make the changes in `simplifyDeriv` more manageable, I also performed some auxiliary refactoring: * Previously, every iteration of `simplifyDeriv` was skolemising the type variables at the start, simplifying, and then performing a reverse substitution at the end to un-skolemise the type variables. This is not necessary, however, since we can just as well skolemise once at the beginning of the `deriving` pipeline and zonk the `TcTyVar`s after `simplifyDeriv` is finished. This patch does just that, having been made possible by prior work in !7613. I have updated `Note [Overlap and deriving]` in `GHC.Tc.Deriv.Infer` to explain this, and I have also left comments on the relevant data structures (e.g., `DerivEnv` and `DerivSpec`) to explain when things might be `TcTyVar`s or `TyVar`s. * All of the aforementioned cleanup allowed me to remove an ad hoc deriving-related in `checkImplicationInvariants`, as all of the skolems in a `tcSubTypeSigma`–produced implication constraint should now be `TcTyVar` at the time the implication is created. * Since `simplifyDeriv` now needs a `SkolemInfo` and `UserTypeCtxt`, I have added `ds_skol_info` and `ds_user_ctxt` fields to `DerivSpec` to store these. Similarly, I have also added a `denv_skol_info` field to `DerivEnv`, which ultimately gets used to initialize the `ds_skol_info` in a `DerivSpec`. Fixes #20719. - - - - - 21680fb0 by Sebastian Graf at 2022-03-24T06:11:19-04:00 WorkWrap: Handle partial FUN apps in `isRecDataCon` (#21265) Partial FUN apps like `(->) Bool` aren't detected by `splitFunTy_maybe`. A silly oversight that is easily fixed by replacing `splitFunTy_maybe` with a guard in the `splitTyConApp_maybe` case. But fortunately, Simon nudged me into rewriting the whole `isRecDataCon` function in a way that makes it much shorter and hence clearer which DataCons are actually considered as recursive. Fixes #21265. - - - - - a2937e2b by Matthew Pickering at 2022-03-24T17:13:22-04:00 Add test for T21035 This test checks that you are allowed to explicitly supply object files for dependencies even if you haven't got the shared object for that library yet. Fixes #21035 - - - - - 1756d547 by Matthew Pickering at 2022-03-24T17:13:58-04:00 Add check to ensure we are not building validate jobs for releases - - - - - 99623358 by Matthew Pickering at 2022-03-24T17:13:58-04:00 hadrian: Correct generation of hsc2hs wrapper If you inspect the inside of a wrapper script for hsc2hs you will see that the cflag and lflag values are concatenated incorrectly. ``` HSC2HS_EXTRA="--cflag=-U__i686--lflag=-fuse-ld=gold" ``` It should instead be ``` HSC2HS_EXTRA="--cflag=-U__i686 --lflag=-fuse-ld=gold" ``` Fixes #21221 - - - - - fefd4e31 by Matthew Pickering at 2022-03-24T17:13:59-04:00 testsuite: Remove library dependenices from T21119 These dependencies would affect the demand signature depending on various rules and so on. Fixes #21271 - - - - - 5ff690b8 by Matthew Pickering at 2022-03-24T17:13:59-04:00 ci: Generate jobs for all normal builds and use hadrian for all builds This commit introduces a new script (.gitlab/gen_ci.hs) which generates a yaml file (.gitlab/jobs.yaml) which contains explicit descriptions for all the jobs we want to run. The jobs are separated into three categories: * validate - jobs run on every MR * nightly - jobs run once per day on the master branch * release - jobs for producing release artifacts The generation script is a Haskell program which includes a DSL for specifying the different jobs. The hope is that it's easier to reason about the different jobs and how the variables are merged together rather than the unclear and opaque yaml syntax. The goal is to fix issues like #21190 once and for all.. The `.gitlab/jobs.yaml` can be generated by running the `.gitlab/generate_jobs` script. You have to do this manually. Another consequence of this patch is that we use hadrian for all the validate, nightly and release builds on all platforms. - - - - - 1d673aa2 by Christiaan Baaij at 2022-03-25T11:35:49-04:00 Add the OPAQUE pragma A new pragma, `OPAQUE`, that ensures that every call of a named function annotated with an `OPAQUE` pragma remains a call of that named function, not some name-mangled variant. Implements GHC proposal 0415: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0415-opaque-pragma.rst This commit also updates the haddock submodule to handle the newly introduced lexer tokens corresponding to the OPAQUE pragma. - - - - - 83f5841b by Andrew Lelechenko at 2022-03-25T11:36:31-04:00 Add instance Lift ByteArray - - - - - 7cc1184a by Matthew Pickering at 2022-03-25T11:37:07-04:00 Make -ddump-rn-ast and -ddump-tc-ast work in GHCi Fixes #17830 - - - - - 940feaf3 by Sylvain Henry at 2022-03-25T11:37:47-04:00 Modularize Tidy (#17957) - Factorize Tidy options into TidyOpts datatype. Initialize it in GHC.Driver.Config.Tidy - Same thing for StaticPtrOpts - Perform lookups of unpackCString[Utf8]# once in initStaticPtrOpts instead of for every use of mkStringExprWithFS - - - - - 25101813 by Takenobu Tani at 2022-03-28T01:16:02-04:00 users-guide: Correct markdown for profiling This patch corrects some markdown. [skip ci] - - - - - c832ae93 by Matthew Pickering at 2022-03-28T01:16:38-04:00 hadrian: Flag cabal flag handling This patch basically deletes some ad-hoc handling of Cabal Flags and replaces it with a correct query of the LocalBuildInfo. The flags in the local build info can be modified by users by passing hadrian options For example (!4331) ``` *.genapply.cabal.configure.opts += --flags=unregisterised ``` And all the flags specified by the `Cabal Flags` builder were already passed to configure properly using `--flags`. - - - - - a9f3a5c6 by Ben Gamari at 2022-03-28T01:16:38-04:00 Disable text's dependency on simdutf by default Unfortunately we are simply not currently in a good position to robustly ship binary distributions which link against C++ code like simdutf. Fixes #20724. - - - - - eff86e8a by Richard Eisenberg at 2022-03-28T01:17:14-04:00 Add Red Herring to Note [What might equal later?] Close #21208. - - - - - 12653be9 by jberryman at 2022-03-28T01:17:55-04:00 Document typed splices inhibiting unused bind detection (#16524) - - - - - 4aeade15 by Adam Sandberg Ericsson at 2022-03-28T01:18:31-04:00 users-guide: group ticky-ticky profiling under one heading - - - - - cc59648a by Sylvain Henry at 2022-03-28T01:19:12-04:00 Hadrian: allow testsuite to run with cross-compilers (#21292) - - - - - 89cb1315 by Matthew Pickering at 2022-03-28T01:19:48-04:00 hadrian: Add show target to bindist makefile Some build systems use "make show" to query facts about the bindist, for example: ``` make show VALUE=ProjectVersion > version ``` to determine the ProjectVersion - - - - - 8229885c by Alan Zimmerman at 2022-03-28T19:23:28-04:00 EPA: let stmt with semicolon has wrong anchor The code let ;x =1 Captures the semicolon annotation, but did not widen the anchor in the ValBinds. Fix that. Closes #20247 - - - - - 2c12627c by Ryan Scott at 2022-03-28T19:24:04-04:00 Consistently attach SrcSpans to sub-expressions in TH splices Before, `GHC.ThToHs` was very inconsistent about where various sub-expressions would get the same `SrcSpan` from the original TH splice location or just a generic `noLoc` `SrcSpan`. I have ripped out all uses of `noLoc` in favor of the former instead, and I have added a `Note [Source locations within TH splices]` to officially enshrine this design choice. Fixes #21299. - - - - - 789add55 by Zubin Duggal at 2022-03-29T13:07:22-04:00 Fix all invalid haddock comments in the compiler Fixes #20935 and #20924 - - - - - 967dad03 by Zubin Duggal at 2022-03-29T13:07:22-04:00 hadrian: Build lib:GHC with -haddock and -Winvalid-haddock (#21273) - - - - - ad09a5f7 by sheaf at 2022-03-29T13:08:05-04:00 Hadrian: make DDEBUG separate from debugged RTS This patchs separates whether -DDEBUG is enabled (i.e. whether debug assertions are enabled) from whether we are using the debugged RTS (i.e. GhcDebugged = YES). This means that we properly skip tests which have been marked with `when(compiler_debugged(), skip)`. Fixes #21113, #21153 and #21234 - - - - - 840a6811 by Matthew Pickering at 2022-03-29T13:08:42-04:00 RTS: Zero gc_cpu_start and gc_cpu_end after accounting When passed a combination of `-N` and `-qn` options the cpu time for garbage collection was being vastly overcounted because the counters were not being zeroed appropiately. When -qn1 is passed, only 1 of the N avaiable GC threads is chosen to perform work, the rest are idle. At the end of the GC period, stat_endGC traverses all the GC threads and adds up the elapsed time from each of them. For threads which didn't participate in this GC, the value of the cpu time should be zero, but before this patch, the counters were not zeroed and hence we would count the same elapsed time on many subsequent iterations (until the thread participated in a GC again). The most direct way to zero these fields is to do so immediately after the value is added into the global counter, after which point they are never used again. We also tried another approach where we would zero the counter in yieldCapability but there are some (undiagnosed) siations where a capbility would not pass through yieldCapability before the GC ended and the same double counting problem would occur. Fixes #21082 - - - - - dda46e2d by Matthew Pickering at 2022-03-29T13:09:18-04:00 Add test for T21306 Fixes #21306 - - - - - f07c7766 by Jakob Brünker at 2022-03-30T03:10:33-04:00 Give parsing plugins access to errors Previously, when the parser produced non-fatal errors (i.e. it produced errors but the 'PState' is 'POk'), compilation would be aborted before the 'parsedResultAction' of any plugin was invoked. This commit changes that, so that such that 'parsedResultAction' gets collections of warnings and errors as argument, and must return them after potentially modifying them. Closes #20803 - - - - - e5dfde75 by Ben Gamari at 2022-03-30T03:11:10-04:00 Fix reference to Note [FunBind vs PatBind] This Note was renamed in 2535a6716202253df74d8190b028f85cc6d21b72 yet this occurrence was not updated. - - - - - 21894a63 by Krzysztof Gogolewski at 2022-03-30T03:11:45-04:00 Refactor: make primtypes independent of PrimReps Previously, 'pcPrimTyCon', the function used to define a primitive type, was taking a PrimRep, only to convert it to a RuntimeRep. Now it takes a RuntimeRep directly. Moved primRepToRuntimeRep to GHC.Types.RepType. It is now located next to its inverse function runtimeRepPrimRep. Now GHC.Builtin.Types.Prim no longer mentions PrimRep, and GHC.Types.RepType no longer imports GHC.Builtin.Types.Prim. Removed unused functions `primRepsToRuntimeRep` and `mkTupleRep`. Removed Note [PrimRep and kindPrimRep] - it was never referenced, didn't belong to Types.Prim, and Note [Getting from RuntimeRep to PrimRep] is more comprehensive. - - - - - 43da2963 by Matthew Pickering at 2022-03-30T09:55:49+01:00 Fix mention of non-existent "rehydrateIface" function [skip ci] Fixes #21303 - - - - - 6793a20f by gershomb at 2022-04-01T10:33:46+01:00 Remove wrong claim about naturality law. This docs change removes a longstanding confusion in the Traversable docs. The docs say "(The naturality law is implied by parametricity and thus so is the purity law [1, p15].)". However if one reads the reference a different "natural" law is implied by parametricity. The naturality law given as a law here is imposed. Further, the reference gives examples which violate both laws -- so they cannot be implied by parametricity. This PR just removes the wrong claim. - - - - - 5beeff46 by Ben Gamari at 2022-04-01T10:34:39+01:00 Refactor handling of global initializers GHC uses global initializers for a number of things including cost-center registration, info-table provenance registration, and setup of foreign exports. Previously, the global initializer arrays which referenced these initializers would live in the object file of the C stub, which would then be merged into the main object file of the module. Unfortunately, this approach is no longer tenable with the move to Clang/LLVM on Windows (see #21019). Specifically, lld's PE backend does not support object merging (that is, the -r flag). Instead we are now rather packaging a module's object files into a static library. However, this is problematic in the case of initializers as there are no references to the C stub object in the archive, meaning that the linker may drop the object from the final link. This patch refactors our handling of global initializers to instead place initializer arrays within the object file of the module to which they belong. We do this by introducing a Cmm data declaration containing the initializer array in the module's Cmm stream. While the initializer functions themselves remain in separate C stub objects, the reference from the module's object ensures that they are not dropped from the final link. In service of #21068. - - - - - 3e6fe71b by Matthew Pickering at 2022-04-01T10:35:41+01:00 Fix remaining issues in eventlog types (gen_event_types.py) * The size of End concurrent mark phase looks wrong and, it used to be 4 and now it's 0. * The size of Task create is wrong, used to be 18 and now 14. * The event ticky-ticky entry counter begin sample has the wrong name * The event ticky-ticky entry counter being sample has the wrong size, was 0 now 32. Closes #21070 - - - - - 7847f47a by Ben Gamari at 2022-04-01T10:35:41+01:00 users-guide: Fix a few small issues in eventlog format descriptions The CONC_MARK_END event description didn't mention its payload. Clarify the meaning of the CREATE_TASK's payload. - - - - - acfd5a4c by Matthew Pickering at 2022-04-01T10:35:53+01:00 ci: Regenerate jobs.yaml It seems I forgot to update this to reflect the current state of gen_ci.hs - - - - - a952dd80 by Matthew Pickering at 2022-04-01T10:35:59+01:00 ci: Attempt to fix windows cache issues It appears that running the script directly does nothing (no info is printed about saving the cache). - - - - - fb65e6e3 by Adrian Ratiu at 2022-04-01T10:49:52+01:00 fp_prog_ar.m4: take AR var into consideration In ChromeOS and Gentoo we want the ability to use LLVM ar instead of GNU ar even though both are installed, thus we pass (for eg) AR=llvm-ar to configure. Unfortunately GNU ar always gets picked regardless of the AR setting because the check does not consider the AR var when setting fp_prog_ar, hence this fix. - - - - - 1daaefdf by Greg Steuck at 2022-04-01T10:50:16+01:00 T13366 requires c++ & c++abi libraries on OpenBSD Fixes this failure: =====> 1 of 1 [0, 0, 0] T13366(normal) 1 of 1 [0, 0, 0] Compile failed (exit code 1) errors were: <no location info>: error: user specified .o/.so/.DLL could not be loaded (File not found) Whilst trying to load: (dynamic) stdc++ Additional directories searched: (none) *** unexpected failure for T13366(normal) - - - - - 18e6c85b by Jakob Bruenker at 2022-04-01T10:54:28+01:00 new datatypes for parsedResultAction Previously, the warnings and errors were given and returned as a tuple (Messages PsWarnings, Messages PsErrors). Now, it's just PsMessages. This, together with the HsParsedModule the parser plugin gets and returns, has been wrapped up as ParsedResult. - - - - - 9727e592 by Morrow at 2022-04-01T10:55:12+01:00 Clarify that runghc interprets the input program - - - - - f589dea3 by sheaf at 2022-04-01T10:59:58+01:00 Unify RuntimeRep arguments in ty_co_match The `ty_co_match` function ignored the implicit RuntimeRep coercions that occur in a `FunCo`. Even though a comment explained that this should be fine, #21205 showed that it could result in discarding a RuntimeRep coercion, and thus discarding an important cast entirely. With this patch, we first match the kinds in `ty_co_match`. Fixes #21205 ------------------------- Metric Increase: T12227 T18223 ------------------------- - - - - - 6f4dc372 by Andreas Klebinger at 2022-04-01T11:01:35+01:00 Export MutableByteArray from Data.Array.Byte This implements CLC proposal #49 - - - - - 5df9f5e7 by ARATA Mizuki at 2022-04-01T11:02:35+01:00 Add test cases for #20640 Closes #20640 - - - - - 8334ff9e by Krzysztof Gogolewski at 2022-04-01T11:03:16+01:00 Minor cleanup - Remove unused functions exprToCoercion_maybe, applyTypeToArg, typeMonoPrimRep_maybe, runtimeRepMonoPrimRep_maybe. - Replace orValid with a simpler check - Use splitAtList in applyTysX - Remove calls to extra_clean in the testsuite; it does not do anything. Metric Decrease: T18223 - - - - - b2785cfc by Eric Lindblad at 2022-04-01T11:04:07+01:00 hadrian typos - - - - - 418e6fab by Eric Lindblad at 2022-04-01T11:04:12+01:00 two typos - - - - - dd7c7c99 by Phil de Joux at 2022-04-01T11:04:56+01:00 Add tests and docs on plugin args and order. - - - - - 3e209a62 by MaxHearnden at 2022-04-01T11:05:19+01:00 Change may not to might not - - - - - b84380d3 by Matthew Pickering at 2022-04-01T11:07:27+01:00 hadrian: Remove linters-common from bindist Zubin observed that the bindists contains the utility library linters-common. There are two options: 1. Make sure only the right files are added into the bindist.. a bit tricky due to the non-trivial structure of the lib directory. 2. Remove the bad files once they get copied in.. a bit easier So I went for option 2 but we perhaps should go for option 1 in the future. Fixes #21203 - - - - - ba9904c1 by Zubin Duggal at 2022-04-01T11:07:31+01:00 hadrian: allow testing linters with out of tree compilers - - - - - 26547759 by Matthew Pickering at 2022-04-01T11:07:35+01:00 hadrian: Introduce CheckProgram datatype to replace a 7-tuple - - - - - df65d732 by Jakob Bruenker at 2022-04-01T11:08:28+01:00 Fix panic when pretty printing HsCmdLam When pretty printing a HsCmdLam with more than one argument, GHC panicked because of a missing case. This fixes that. Closes #21300 - - - - - ad6cd165 by John Ericson at 2022-04-01T11:10:06+01:00 hadrian: Remove vestigial -this-unit-id support check This has been dead code since 400ead81e80f66ad7b1260b11b2a92f25ccc3e5a. - - - - - 8ca7ab81 by Matthew Pickering at 2022-04-01T11:10:23+01:00 hadrian: Fix race involving empty package databases There was a small chance of a race occuring between the small window of 1. The first package (.conf) file get written into the database 2. hadrian calling "ghc-pkg recache" to refresh the package.conf file In this window the package database would contain rts.conf but not a package.cache file, and therefore if ghc was invoked it would error because it was missing. To solve this we call "ghc-pkg recache" at when the database is created by shake by writing the stamp file into the database folder. This also creates the package.cache file and so avoids the possibility of this race. - - - - - cc4ec64b by Matthew Pickering at 2022-04-01T11:11:05+01:00 hadrian: Add assertion that in/out tree args are the same There have been a few instances where this calculation was incorrect, so we add a non-terminal assertion when now checks they the two computations indeed compute the same thing. Fixes #21285 - - - - - 691508d8 by Matthew Pickering at 2022-04-01T11:13:10+01:00 hlint: Ignore suggestions in generated HaddockLex file With the make build system this file ends up in the compiler/ subdirectory so is linted. With hadrian, the file ends up in _build so it's not linted. Fixes #21313 - - - - - f8f152e7 by Krzysztof Gogolewski at 2022-04-01T11:14:08+01:00 Change GHC.Prim to GHC.Exts in docs and tests Users are supposed to import GHC.Exts rather than GHC.Prim. Part of #18749. - - - - - f8fc6d2e by Matthew Pickering at 2022-04-01T11:15:24+01:00 driver: Improve -Wunused-packages error message (and simplify implementation) In the past I improved the part of -Wunused-packages which found which packages were used. Now I improve the part which detects which ones were specified. The key innovation is to use the explicitUnits field from UnitState which has the result of resolving the package flags, so we don't need to mess about with the flag arguments from DynFlags anymore. The output now always includes the package name and version (and the flag which exposed it). ``` The following packages were specified via -package or -package-id flags, but were not needed for compilation: - bytestring-0.11.2.0 (exposed by flag -package bytestring) - ghc-9.3 (exposed by flag -package ghc) - process-1.6.13.2 (exposed by flag -package process) ``` Fixes #21307 - - - - - 5e5a12d9 by Matthew Pickering at 2022-04-01T11:15:32+01:00 driver: In oneshot mode, look for interface files in hidir How things should work: * -i is the search path for source files * -hidir explicitly sets the search path for interface files and the output location for interface files. * -odir sets the search path and output location for object files. Before in one shot mode we would look for the interface file in the search locations given by `-i`, but then set the path to be in the `hidir`, so in unusual situations the finder could find an interface file in the `-i` dir but later fail because it tried to read the interface file from the `-hidir`. A bug identified by #20569 - - - - - 950f58e7 by Matthew Pickering at 2022-04-01T11:15:36+01:00 docs: Update documentation interaction of search path, -hidir and -c mode. As noted in #20569 the documentation for search path was wrong because it seemed to indicate that `-i` dirs were important when looking for interface files in `-c` mode, but they are not important if `-hidir` is set. Fixes #20569 - - - - - d85c7dcb by sheaf at 2022-04-01T11:17:56+01:00 Keep track of promotion ticks in HsOpTy This patch adds a PromotionFlag field to HsOpTy, which is used in pretty-printing and when determining whether to emit warnings with -fwarn-unticked-promoted-constructors. This allows us to correctly report tick-related warnings for things like: type A = Int : '[] type B = [Int, Bool] Updates haddock submodule Fixes #19984 - - - - - 32070e6c by Jakob Bruenker at 2022-04-01T20:31:08+02:00 Implement \cases (Proposal 302) This commit implements proposal 302: \cases - Multi-way lambda expressions. This adds a new expression heralded by \cases, which works exactly like \case, but can match multiple apats instead of a single pat. Updates submodule haddock to support the ITlcases token. Closes #20768 - - - - - c6f77f39 by sheaf at 2022-04-01T20:33:05+02:00 Add a regression test for #21323 This bug was fixed at some point between GHC 9.0 and GHC 9.2; this patch simply adds a regression test. - - - - - 3596684e by Jakob Bruenker at 2022-04-01T20:33:05+02:00 Fix error when using empty case in arrow notation It was previously not possible to use -XEmptyCase in Arrow notation, since GHC would print "Exception: foldb of empty list". This is now fixed. Closes #21301 - - - - - 9a325b59 by Ben Gamari at 2022-04-01T20:33:05+02:00 users-guide: Fix various markup issues - - - - - aefb1e6d by sheaf at 2022-04-01T20:36:01+02:00 Ensure implicit parameters are lifted `tcExpr` typechecked implicit parameters by introducing a metavariable of kind `TYPE kappa`, without enforcing that `kappa ~ LiftedRep`. This patch instead creates a metavariable of kind `Type`. Fixes #21327 - - - - - ed62dc66 by Ben Gamari at 2022-04-05T11:44:51-04:00 gitlab-ci: Disable cabal-install store caching on Windows For reasons that remain a mystery, cabal-install seems to consistently corrupt its cache on Windows. Disable caching for now. Works around #21347. - - - - - 5ece5c5a by Ryan Scott at 2022-04-06T13:00:51-04:00 Add /linters/*/dist-install/ to .gitignore Fixes #21335. [ci skip] - - - - - 410c76ee by Ben Gamari at 2022-04-06T13:01:28-04:00 Use static archives as an alternative to object merging Unfortunately, `lld`'s COFF backend does not currently support object merging. With ld.bfd having broken support for high image-load base addresses, it's necessary to find an alternative. Here I introduce support in the driver for generating static archives, which we use on Windows instead of object merging. Closes #21068. - - - - - 400666c8 by Ben Gamari at 2022-04-06T13:01:28-04:00 rts/linker: Catch archives masquerading as object files Check the file's header to catch static archive bearing the `.o` extension, as may happen on Windows after the Clang refactoring. See #21068 - - - - - 694d39f0 by Ben Gamari at 2022-04-06T13:01:28-04:00 driver: Make object merging optional On Windows we don't have a linker which supports object joining (i.e. the `-r` flag). Consequently, `-pgmlm` is now a `Maybe`. See #21068. - - - - - 41fcb5cd by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Refactor handling of ar flags Previously the setup was quite fragile as it had to assume which arguments were file arguments and which were flags. - - - - - 3ac80a86 by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Produce ar archives with L modifier on Windows Since object files may in fact be archive files, we must ensure that their contents are merged rather than constructing an archive-of-an-archive. See #21068. - - - - - 295c35c5 by Ben Gamari at 2022-04-06T13:01:28-04:00 Add a Note describing lack of object merging on Windows See #21068. - - - - - d2ae0a3a by Ben Gamari at 2022-04-06T13:01:28-04:00 Build ar archives with -L when "joining" objects Since there may be .o files which are in fact archives. - - - - - babb47d2 by Zubin Duggal at 2022-04-06T13:02:04-04:00 Add warnings for file header pragmas that appear in the body of a module (#20385) Once we are done parsing the header of a module to obtain the options, we look through the rest of the tokens in order to determine if they contain any misplaced file header pragmas that would usually be ignored, potentially resulting in bad error messages. The warnings are reported immediately so that later errors don't shadow over potentially helpful warnings. Metric Increase: T13719 - - - - - 3f31825b by Ben Gamari at 2022-04-06T13:02:40-04:00 rts/AdjustorPool: Generalize to allow arbitrary contexts Unfortunately the i386 adjustor logic needs this. - - - - - 9b645ee1 by Ben Gamari at 2022-04-06T13:02:40-04:00 adjustors/i386: Use AdjustorPool In !7511 (closed) I introduced a new allocator for adjustors, AdjustorPool, which eliminates the address space fragmentation issues which adjustors can introduce. In that work I focused on amd64 since that was the platform where I observed issues. However, in #21132 we noted that the size of adjustors is also a cause of CI fragility on i386. In this MR I port i386 to use AdjustorPool. Sadly the complexity of the i386 adjustor code does cause require a bit of generalization which makes the code a bit more opaque but such is the world. Closes #21132. - - - - - c657a616 by Ben Gamari at 2022-04-06T13:03:16-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 9ce273b9 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Drop dead HACKAGE_INDEX_STATE variable - - - - - 01845375 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab/darwin: Factor out bindists This makes it a bit easier to bump them. - - - - - c41c478e by Ben Gamari at 2022-04-06T13:03:16-04:00 Fix a few new warnings when booting with GHC 9.2.2 -Wuni-incomplete-patterns and apparent improvements in the pattern match checker surfaced these. - - - - - 6563cd24 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Bump bootstrap compiler to 9.2.2 This is necessary to build recent `text` commits. Bumps Hackage index state for a hashable which builds with GHC 9.2. - - - - - a62e983e by Ben Gamari at 2022-04-06T13:03:16-04:00 Bump text submodule to current `master` Addresses #21295. - - - - - 88d61031 by Vladislav Zavialov at 2022-04-06T13:03:53-04:00 Refactor OutputableBndrFlag instances The matching on GhcPass introduced by 95275a5f25a is not necessary. This patch reverts it to make the code simpler. - - - - - f601f002 by GHC GitLab CI at 2022-04-06T15:18:26-04:00 rts: Eliminate use of nested functions This is a gcc-specific extension. - - - - - d4c5f29c by Ben Gamari at 2022-04-06T15:18:26-04:00 driver: Drop hacks surrounding windres invocation Drop hack for #1828, among others as they appear to be unnecessary when using `llvm-windres`. - - - - - 6be2c5a7 by Ben Gamari at 2022-04-06T15:18:26-04:00 Windows/Clang: Build system adaptation * Bump win32-tarballs to 0.7 * Move Windows toolchain autoconf logic into separate file * Use clang and LLVM utilities as described in #21019 * Disable object merging as lld doesn't support -r * Drop --oformat=pe-bigobj-x86-64 arguments from ld flags as LLD detects that the output is large on its own. * Drop gcc wrapper since Clang finds its root fine on its own. - - - - - c6fb7aff by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Test that we can build bigobj PE objects - - - - - 79851c07 by Ben Gamari at 2022-04-06T15:18:26-04:00 Drop -static-libgcc This flag is not applicable when Clang is used. - - - - - 1f8a8264 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Port T16514 to C Previously this test was C++ which made it a bit of a portability problem. - - - - - d7e650d1 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark Windows as a libc++ platform - - - - - d7886c46 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark T9405 as fixed on Windows I have not seen it fail since moving to clang. Closes #12714. - - - - - 4c3fbb4e by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark FloatFnInverses as fixed The new toolchain has fixed it. Closes #15670. - - - - - 402c36ba by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Rework T13606 to avoid gcc dependence Previously we used libgcc_s's import library in T13606. However, now that we ship with clang we no longer have this library. Instead we now use gdi32. - - - - - 9934ad54 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Clean up tests depending on C++ std lib - - - - - 12fcdef2 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Split T13366 into two tests Split up the C and C++ uses since the latter is significantly more platform-dependent. - - - - - 3c08a198 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Fix mk-big-obj I'm a bit unclear on how this previously worked as it attempted to build an executable without defining `main`. - - - - - 7e97cc23 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Provide module definitions in T10955dyn Otherwise the linker will export all symbols, including those provided by the RTS, from the produced shared object. Consequently, attempting to link against multiple objects simultaneously will cause the linker to complain that RTS symbols are multiply defined. Avoid this by limiting the DLL exports with a module definition file. - - - - - 9a248afa by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark test-defaulting-plugin as fragile on Windows Currently llvm-ar does not handle long file paths, resulting in occassional failures of these tests and #21293. - - - - - 39371aa4 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite/driver: Treat framework failures of fragile tests as non-fatal Previously we would report framework failures of tests marked as fragile as failures. Now we rather treat them as fragile test failures, which are not fatal to the testsuite run. Noticed while investigating #21293. - - - - - a1e6661d by Ben Gamari at 2022-04-06T15:18:32-04:00 Bump Cabal submodule - Disable support for library-for-ghci on Windows as described in #21068. - Teach Cabal to use `ar -L` when available - - - - - f7b0f63c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump process submodule Fixes missing TEST_CC_OPTS in testsuite tests. - - - - - 109cee19 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Disable ghci libraries when object merging is not available - - - - - c22fba5c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump bytestring submodule - - - - - 6e2744cc by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump text submodule - - - - - 32333747 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Build wrappers using ghc rather than cc - - - - - 59787ba5 by Ben Gamari at 2022-04-06T15:18:37-04:00 linker/PEi386: More descriptive error message - - - - - 5e3c3c4f by Ben Gamari at 2022-04-06T15:18:37-04:00 testsuite: Mark TH_spliceE5_prof as unbroken on Windows It was previously failing due to #18721 and now passes with the new toolchain. Closes #18721. - - - - - 9eb0a9d9 by GHC GitLab CI at 2022-04-06T15:23:48-04:00 rts/PEi386: Move some debugging output to -DL - - - - - ce874595 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen/x86: Use %rip-relative addressing On Windows with high-entropy ASLR we must use %rip-relative addressing to avoid overflowing the signed 32-bit immediate size of x86-64. Since %rip-relative addressing comes essentially for free and can make linking significantly easier, we use it on all platforms. - - - - - 52deee64 by Ben Gamari at 2022-04-06T15:24:01-04:00 Generate LEA for label expressions - - - - - 105a0056 by Ben Gamari at 2022-04-06T15:24:01-04:00 Refactor is32BitLit to take Platform rather than Bool - - - - - ec4526b5 by Ben Gamari at 2022-04-06T15:24:01-04:00 Don't assume that labels are 32-bit on Windows - - - - - ffdbe457 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen: Note signed-extended nature of MOV - - - - - bfb79697 by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 5ad143fd by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - a59a66a8 by Ben Gamari at 2022-04-06T15:30:56-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - 42bf7528 by GHC GitLab CI at 2022-04-06T16:25:04-04:00 rts/PEi386: Fix memory leak Previously we would leak the section information of the `.bss` section. - - - - - d286a55c by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Preserve information about symbol types As noted in #20978, the linker would previously handle overflowed relocations by creating a jump island. While this is fine in the case of code symbols, it's very much not okay in the case of data symbols. To fix this we must keep track of whether each symbol is code or data and relocate them appropriately. This patch takes the first step in this direction, adding a symbol type field to the linker's symbol table. It doesn't yet change relocation behavior to take advantage of this knowledge. Fixes #20978. - - - - - e689e9d5 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Fix relocation overflow behavior This fixes handling of overflowed relocations on PEi386 targets: * Refuse to create jump islands for relocations of data symbols * Correctly handle the `__imp___acrt_iob_func` symbol, which is an new type of symbol: `SYM_TYPE_INDIRECT_DATA` - - - - - 655e7d8f by GHC GitLab CI at 2022-04-06T16:25:25-04:00 rts: Mark anything that might have an info table as data Tables-next-to-code mandates that we treat symbols with info tables like data since we cannot relocate them using a jump island. See #20983. - - - - - 7e8cc293 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Rework linker This is a significant rework of the PEi386 linker, making the linker compatible with high image base addresses. Specifically, we now use the m32 allocator instead of `HeapAllocate`. In addition I found a number of latent bugs in our handling of import libraries and relocations. I've added quite a few comments describing what I've learned about Windows import libraries while fixing these. Thanks to Tamar Christina (@Phyx) for providing the address space search logic, countless hours of help while debugging, and his boundless Windows knowledge. Co-Authored-By: Tamar Christina <tamar at zhox.com> - - - - - ff625218 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Move allocateBytes to MMap.c - - - - - f562b5ca by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Avoid accidentally-quadratic allocation cost We now preserve the address that we last mapped, allowing us to resume our search and avoiding quadratic allocation costs. This fixes the runtime of T10296a, which allocates many adjustors. - - - - - 3247b7db by Ben Gamari at 2022-04-06T16:25:25-04:00 Move msvcrt dep out of base - - - - - fa404335 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: More descriptive debug output - - - - - 140f338f by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PathUtils: Define pathprintf in terms of snwprintf on Windows swprintf deviates from usual `snprintf` semantics in that it does not guarantee reasonable behavior when the buffer is NULL (that is, returning the number of bytes that would have been emitted). - - - - - eb60565b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Report archive member index - - - - - 209fd61b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Split up object resolution and initialization Previously the RTS linker would call initializers during the "resolve" phase of linking. However, this is problematic in the case of cyclic dependencies between objects. In particular, consider the case where we have a situation where a static library contains a set of recursive objects: * object A has depends upon symbols in object B * object B has an initializer that depends upon object A * we try to load object A The linker would previously: 1. start resolving object A 2. encounter the reference to object B, loading it resolve object B 3. run object B's initializer 4. the initializer will attempt to call into object A, which hasn't been fully resolved (and therefore protected) Fix this by moving constructor execution to a new linking phase, which follows resolution. Fix #21253. - - - - - 8e8a1021 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker/LoadArchive: Fix leaking file handle Previously `isArchive` could leak a `FILE` handle if the `fread` returned a short read. - - - - - 429ea5d9 by sheaf at 2022-04-07T07:55:52-04:00 Remove Fun pattern from Typeable COMPLETE set GHC merge request !963 improved warnings in the presence of COMPLETE annotations. This allows the removal of the Fun pattern from the complete set. Doing so expectedly causes some redundant pattern match warnings, in particular in GHC.Utils.Binary.Typeable and Data.Binary.Class from the binary library; this commit addresses that. Updates binary submodule Fixes #20230 - - - - - 54b18824 by Alan Zimmerman at 2022-04-07T07:56:28-04:00 EPA: handling of con_bndrs in mkGadtDecl Get rid of unnnecessary case clause that always matched. Closes #20558 - - - - - 9c838429 by Ben Gamari at 2022-04-07T09:38:53-04:00 testsuite: Mark T10420 as broken on Windows Due to #21322. - - - - - 50739d2b by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Refactor and fix printf attributes on clang Clang on Windows does not understand the `gnu_printf` attribute; use `printf` instead. - - - - - 9eeaeca4 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Add missing newline in error message - - - - - fcef9a17 by Ben Gamari at 2022-04-07T09:42:42-04:00 configure: Make environ decl check more robust Some platforms (e.g. Windows/clang64) declare `environ` in `<stdlib.h>`, not `<unistd.h>` - - - - - 8162b4f3 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Adjust RTS symbol table on Windows for ucrt - - - - - 633280d7 by Ben Gamari at 2022-04-07T09:43:21-04:00 testsuite: Fix exit code of bounds checking tests on Windows `abort` exits with 255, not 134, on Windows. - - - - - cab4dc01 by Ben Gamari at 2022-04-07T09:43:31-04:00 testsuite: Update expected output from T5435 tests on Windows I'll admit, I don't currently see *why* this output is reordered but it is a fairly benign difference and I'm out of time to investigate. - - - - - edf5134e by Ben Gamari at 2022-04-07T09:43:35-04:00 testsuite: Mark T20918 as broken on Windows Our toolchain on Windows doesn't currently have Windows support. - - - - - d0ddeff3 by Ben Gamari at 2022-04-07T09:43:39-04:00 testsuite: Mark linker unloading tests as broken on Windows Due to #20354. We will need to investigate this prior the release. - - - - - 5a86da2b by Ben Gamari at 2022-04-07T09:43:43-04:00 testsuite: Mark T9405 as broken on Windows Due to #21361. - - - - - 4aa86dcf by Ben Gamari at 2022-04-07T09:44:18-04:00 Merge branches 'wip/windows-high-codegen', 'wip/windows-high-linker', 'wip/windows-clang-2' and 'wip/lint-rts-includes' into wip/windows-clang-join - - - - - 7206f055 by Ben Gamari at 2022-04-07T09:45:07-04:00 rts/CloneStack: Ensure that Rts.h is #included first As is necessary on Windows. - - - - - 9cfcb27b by Ben Gamari at 2022-04-07T09:45:07-04:00 rts: Fallback to ucrtbase not msvcrt Since we have switched to Clang the toolchain now links against ucrt rather than msvcrt. - - - - - d6665d85 by Ben Gamari at 2022-04-07T09:46:25-04:00 Accept spurious perf test shifts on Windows Metric Decrease: T16875 Metric Increase: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 83363c8b by Simon Peyton Jones at 2022-04-07T12:57:21-04:00 Use prepareBinding in tryCastWorkerWrapper As #21144 showed, tryCastWorkerWrapper was calling prepareRhs, and then unconditionally floating the bindings, without the checks of doFloatFromRhs. That led to floating an unlifted binding into a Rec group. This patch refactors prepareBinding to make these checks, and do them uniformly across all calls. A nice improvement. Other changes * Instead of passing around a RecFlag and a TopLevelFlag; and sometimes a (Maybe SimplCont) for join points, define a new Simplifier-specific data type BindContext: data BindContext = BC_Let TopLevelFlag RecFlag | BC_Join SimplCont and use it consistently. * Kill off completeNonRecX by inlining it. It was only called in one place. * Add a wrapper simplImpRules for simplRules. Compile time on T9630 drops by 4.7%; little else changes. Metric Decrease: T9630 - - - - - 02279a9c by Vladislav Zavialov at 2022-04-07T12:57:59-04:00 Rename [] to List (#21294) This patch implements a small part of GHC Proposal #475. The key change is in GHC.Types: - data [] a = [] | a : [a] + data List a = [] | a : List a And the rest of the patch makes sure that List is pretty-printed as [] in various contexts. Updates the haddock submodule. - - - - - 08480d2a by Simon Peyton Jones at 2022-04-07T12:58:36-04:00 Fix the free-var test in validDerivPred The free-var test (now documented as (VD3)) was too narrow, affecting only class predicates. #21302 demonstrated that this wasn't enough! Fixes #21302. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - b3d6d23d by Andreas Klebinger at 2022-04-07T12:59:12-04:00 Properly explain where INLINE pragmas can appear. Fixes #20676 - - - - - 23ef62b3 by Ben Gamari at 2022-04-07T14:28:28-04:00 rts: Fix off-by-one in snwprintf usage - - - - - b2dbcc7d by Simon Jakobi at 2022-04-08T03:00:38-04:00 Improve seq[D]VarSet Previously, the use of size[D]VarSet would involve a traversal of the entire underlying IntMap. Since IntMaps are already spine-strict, this is unnecessary. - - - - - 64ac20a7 by sheaf at 2022-04-08T03:01:16-04:00 Add test for #21338 This no-skolem-info bug was fixed by the no-skolem-info patch that will be part of GHC 9.4. This patch adds a regression test for the issue reported in issue #21338. Fixes #21338. - - - - - c32c4db6 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 56f85d62 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - cb1f31f5 by Ben Gamari at 2022-04-08T03:01:53-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - c44432db by Krzysztof Gogolewski at 2022-04-08T03:02:29-04:00 Fixes to 9.4 release notes - Mention -Wforall-identifier - Improve description of withDict - Fix formatting - - - - - 777365f1 by sheaf at 2022-04-08T09:43:35-04:00 Correctly report SrcLoc of redundant constraints We were accidentally dropping the source location information in certain circumstances when reporting redundant constraints. This patch makes sure that we set the TcLclEnv correctly before reporting the warning. Fixes #21315 - - - - - af300a43 by Vladislav Zavialov at 2022-04-08T09:44:11-04:00 Reject illegal quote mark in data con declarations (#17865) * Non-fatal (i.e. recoverable) parse error * Checking infix constructors * Extended the regression test - - - - - 56254e6b by Ben Gamari at 2022-04-08T09:59:46-04:00 Merge remote-tracking branch 'origin/master' - - - - - 6e2c3b7c by Matthew Pickering at 2022-04-08T13:55:15-04:00 driver: Introduce HomeModInfoCache abstraction The HomeModInfoCache is a mutable cache which is updated incrementally as the driver completes, this makes it robust to exceptions including (SIGINT) The interface for the cache is described by the `HomeMOdInfoCache` data type: ``` data HomeModInfoCache = HomeModInfoCache { hmi_clearCache :: IO [HomeModInfo] , hmi_addToCache :: HomeModInfo -> IO () } ``` The first operation clears the cache and returns its contents. This is designed so it's harder to end up in situations where the cache is retained throughout the execution of upsweep. The second operation allows a module to be added to the cache. The one slightly nasty part is in `interpretBuildPlan` where we have to be careful to ensure that the cache writes happen: 1. In parralel 2. Before the executation continues after upsweep. This requires some simple, localised MVar wrangling. Fixes #20780 - - - - - 85f4a3c9 by Andreas Klebinger at 2022-04-08T13:55:50-04:00 Add flag -fprof-manual which controls if GHC should honour manual cost centres. This allows disabling of manual control centres in code a user doesn't control like libraries. Fixes #18867 - - - - - 3415981c by Vladislav Zavialov at 2022-04-08T13:56:27-04:00 HsUniToken for :: in GADT constructors (#19623) One more step towards the new design of EPA. Updates the haddock submodule. - - - - - 23f95735 by sheaf at 2022-04-08T13:57:07-04:00 Docs: datacon eta-expansion, rep-poly checks The existing notes weren't very clear on how the eta-expansion of data constructors that occurs in tcInferDataCon/dsConLike interacts with the representation polymorphism invariants. So we explain with a few more details how we ensure that the representation-polymorphic lambdas introduced by tcInferDataCon/dsConLike don't end up causing problems, by checking they are properly instantiated and then relying on the simple optimiser to perform beta reduction. A few additional changes: - ConLikeTc just take type variables instead of binders, as we never actually used the binders. - Removed the FRRApp constructor of FRROrigin; it was no longer used now that we use ExpectedFunTyOrigin. - Adds a bit of documentation to the constructors of ExpectedFunTyOrigin. - - - - - d4480490 by Matthew Pickering at 2022-04-08T13:57:43-04:00 ci: Replace "always" with "on_success" to stop build jobs running before hadrian-ghci has finished See https://docs.gitlab.com/ee/ci/yaml/#when * always means, always run not matter what * on_success means, run if the dependencies have built successfully - - - - - 0736e949 by Vladislav Zavialov at 2022-04-08T13:58:19-04:00 Disallow (->) as a data constructor name (#16999) The code was misusing isLexCon, which was never meant for validation. In fact, its documentation states the following: Use these functions to figure what kind of name a 'FastString' represents; these functions do /not/ check that the identifier is valid. Ha! This sign can't stop me because I can't read. The fix is to use okConOcc instead. The other checks (isTcOcc or isDataOcc) seem superfluous, so I also removed those. - - - - - e58d5eeb by Simon Peyton Jones at 2022-04-08T13:58:55-04:00 Tiny documentation wibble This commit commit 83363c8b04837ee871a304cf85207cf79b299fb0 Author: Simon Peyton Jones <simon.peytonjones at gmail.com> Date: Fri Mar 11 16:55:38 2022 +0000 Use prepareBinding in tryCastWorkerWrapper refactored completeNonRecX away, but left a Note referring to it. This MR fixes that Note. - - - - - 4bb00839 by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Fix nightly head.hackage pipelines This also needs a corresponding commit to head.hackage, I also made the job explicitly depend on the fedora33 job so that it isn't blocked by a failing windows job, which causes docs-tarball to fail. - - - - - 3c48e12a by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Remove doc-tarball dependency from perf and perf-nofib jobs These don't depend on the contents of the tarball so we can run them straight after the fedora33 job finishes. - - - - - 27362265 by Matthew Pickering at 2022-04-09T07:41:04-04:00 Bump deepseq to 1.4.7.0 Updates deepseq submodule Fixes #20653 - - - - - dcf30da8 by Joachim Breitner at 2022-04-09T13:02:19-04:00 Drop the app invariant previously, GHC had the "let/app-invariant" which said that the RHS of a let or the argument of an application must be of lifted type or ok for speculation. We want this on let to freely float them around, and we wanted that on app to freely convert between the two (e.g. in beta-reduction or inlining). However, the app invariant meant that simple code didn't stay simple and this got in the way of rules matching. By removing the app invariant, this thus fixes #20554. The new invariant is now called "let-can-float invariant", which is hopefully easier to guess its meaning correctly. Dropping the app invariant means that everywhere where we effectively do beta-reduction (in the two simplifiers, but also in `exprIsConApp_maybe` and other innocent looking places) we now have to check if the argument must be evaluated (unlifted and side-effecting), and analyses have to be adjusted to the new semantics of `App`. Also, `LetFloats` in the simplifier can now also carry such non-floating bindings. The fix for DmdAnal, refine by Sebastian, makes functions with unlifted arguments strict in these arguments, which changes some signatures. This causes some extra calls to `exprType` and `exprOkForSpeculation`, so some perf benchmarks regress a bit (while others improve). Metric Decrease: T9020 Metric Increase: LargeRecord T12545 T15164 T16577 T18223 T5642 T9961 Co-authored-by: Sebastian Graf <sebastian.graf at kit.edu> - - - - - 6c6c5379 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add functions traceWith, traceShowWith, traceEventWith. As discussed at https://github.com/haskell/core-libraries-committee/issues/36 - - - - - 8fafacf7 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add tests for several trace functions. - - - - - 20bbf3ac by Philip Hazelden at 2022-04-09T13:02:59-04:00 Update changelog. - - - - - 47d18b0b by Andreas Klebinger at 2022-04-09T13:03:35-04:00 Add regression test for #19569 - - - - - 5f8d6e65 by sheaf at 2022-04-09T13:04:14-04:00 Fix missing SymCo in pushCoercionIntoLambda There was a missing SymCo in pushCoercionIntoLambda. Currently this codepath is only used with rewrite rules, so this bug managed to slip by, but trying to use pushCoercionIntoLambda in other contexts revealed the bug. - - - - - 20eca489 by Vladislav Zavialov at 2022-04-09T13:04:50-04:00 Refactor: simplify lexing of the dot Before this patch, the lexer did a truly roundabout thing with the dot: 1. look up the varsym in reservedSymsFM and turn it into ITdot 2. under OverloadedRecordDot, turn it into ITvarsym 3. in varsym_(prefix|suffix|...) turn it into ITvarsym, ITdot, or ITproj, depending on extensions and whitespace Turns out, the last step is sufficient to handle the dot correctly. This patch removes the first two steps. - - - - - 5440f63e by Hécate Moonlight at 2022-04-12T11:11:06-04:00 Document that DuplicateRecordFields doesn't tolerates ambiguous fields Fix #19891 - - - - - 0090ad7b by Sebastian Graf at 2022-04-12T11:11:42-04:00 Eta reduction based on evaluation context (#21261) I completely rewrote our Notes surrounding eta-reduction. The new entry point is `Note [Eta reduction makes sense]`. Then I went on to extend the Simplifier to maintain an evaluation context in the form of a `SubDemand` inside a `SimplCont`. That `SubDemand` is useful for doing eta reduction according to `Note [Eta reduction based on evaluation context]`, which describes how Demand analysis, Simplifier and `tryEtaReduce` interact to facilitate eta reduction in more scenarios. Thus we fix #21261. ghc/alloc perf marginally improves (-0.0%). A medium-sized win is when compiling T3064 (-3%). It seems that haddock improves by 0.6% to 1.0%, too. Metric Decrease: T3064 - - - - - 4d2ee313 by Sebastian Graf at 2022-04-12T17:54:57+02:00 Specialising through specialised method calls (#19644) In #19644, we discovered that the ClassOp/DFun rules from Note [ClassOp/DFun selection] inhibit transitive specialisation in a scenario like ``` class C a where m :: Show b => a -> b -> ...; n :: ... instance C Int where m = ... -- $cm :: Show b => Int -> b -> ... f :: forall a b. (C a, Show b) => ... f $dC $dShow = ... m @a $dC @b $dShow ... main = ... f @Int @Bool ... ``` After we specialise `f` for `Int`, we'll see `m @a $dC @b $dShow` in the body of `$sf`. But before this patch, Specialise doesn't apply the ClassOp/DFun rule to rewrite to a call of the instance method for `C Int`, e.g., `$cm @Bool $dShow`. As a result, Specialise couldn't further specialise `$cm` for `Bool`. There's a better example in `Note [Specialisation modulo dictionary selectors]`. This patch enables proper Specialisation, as follows: 1. In the App case of `specExpr`, try to apply the CalssOp/DictSel rule on the head of the application 2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and `$dShow` in `bindAuxiliaryDict` NB: Without (2), (1) would be pointless, because `lookupRule` wouldn't be able to look into the RHS of `$dC` to see the DFun. (2) triggered #21332, because the Specialiser floats around dictionaries without accounting for them in the `SpecEnv`'s `InScopeSet`, triggering a panic when rewriting dictionary unfoldings. Fixes #19644 and #21332. - - - - - b06f4f47 by Sebastian Graf at 2022-04-12T17:54:58+02:00 Specialise: Check `typeDeterminesValue` before specialising on an interesting dictionary I extracted the checks from `Note [Type determines value]` into its own function, so that we share the logic properly. Then I made sure that we actually call `typeDeterminesValue` everywhere we check for `interestingDict`. - - - - - a42dbc55 by Matthew Pickering at 2022-04-13T06:24:52-04:00 Refine warning about defining rules in SAFE modules This change makes it clear that it's the definition rather than any usage which is a problem, and that rules defined in other modules will still be used to do rewrites. Fixes #20923 - - - - - df893f66 by Andreas Klebinger at 2022-04-14T08:18:37-04:00 StgLint: Lint constructor applications and strict workers for arity. This will mean T9208 when run with lint will return a lint error instead of resulting in a panic. Fixes #21117 - - - - - 426ec446 by sheaf at 2022-04-14T08:19:16-04:00 Hadrian: use a set to keep track of ways The order in which ways are provided doesn't matter, so we use a data structure with the appropriate semantics to represent ways. Fixes #21378 - - - - - 7c639b9a by Dylan Yudaken at 2022-04-15T13:55:59-04:00 Only enable PROF_SPIN in DEBUG - - - - - 96b9e5ea by Ben Gamari at 2022-04-15T13:56:34-04:00 testsuite: Add test for #21390 - - - - - d8392f6a by Ben Gamari at 2022-04-15T13:56:34-04:00 rts: Ensure that the interpreter doesn't disregard tags Previously the interpreter's handling of `RET_BCO` stack frames would throw away the tag of the returned closure. This resulted in #21390. - - - - - 83c67f76 by Alan Zimmerman at 2022-04-20T11:49:28-04:00 Add -dkeep-comments flag to keep comments in the parser This provides a way to set the Opt_KeepRawTokenStream from the command line, allowing exact print annotation users to see exactly what is produced for a given parsed file, when used in conjunction with -ddump-parsed-ast Discussed in #19706, but this commit does not close the issue. - - - - - a5ea65c9 by Krzysztof Gogolewski at 2022-04-20T11:50:04-04:00 Remove LevityInfo Every Id was storing a boolean whether it could be levity-polymorphic. This information is no longer needed since representation-checking has been moved to the typechecker. - - - - - 49bd7584 by Andreas Klebinger at 2022-04-20T11:50:39-04:00 Fix a shadowing issue in StgUnarise. For I assume performance reasons we don't record no-op replacements during unarise. This lead to problems with code like this: f = \(Eta_B0 :: VoidType) x1 x2 -> ... let foo = \(Eta_B0 :: LiftedType) -> g x y Eta_B0 in ... Here we would record the outer Eta_B0 as void rep, but would not shadow Eta_B0 inside `foo` because this arg is single-rep and so doesn't need to replaced. But this means when looking at occurence sites we would check the env and assume it's void rep based on the entry we made for the (no longer in scope) outer `Eta_B0`. Fixes #21396 and the ticket has a few more details. - - - - - 0c02c919 by Simon Peyton Jones at 2022-04-20T11:51:15-04:00 Fix substitution in bindAuxiliaryDict In GHC.Core.Opt.Specialise.bindAuxiliaryDict we were unnecessarily calling `extendInScope` to bring into scope variables that were /already/ in scope. Worse, GHC.Core.Subst.extendInScope strangely deleted the newly-in-scope variables from the substitution -- and that was fatal in #21391. I removed the redundant calls to extendInScope. More ambitiously, I changed GHC.Core.Subst.extendInScope (and cousins) to stop deleting variables from the substitution. I even changed the names of the function to extendSubstInScope (and cousins) and audited all the calls to check that deleting from the substitution was wrong. In fact there are very few such calls, and they are all about introducing a fresh non-in-scope variable. These are "OutIds"; it is utterly wrong to mess with the "InId" substitution. I have not added a Note, because I'm deleting wrong code, and it'd be distracting to document a bug. - - - - - 0481a6af by Cheng Shao at 2022-04-21T11:06:06+00:00 [ci skip] Drop outdated TODO in RtsAPI.c - - - - - 1e062a8a by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Introduce ip_STACK_FRAME While debugging it is very useful to be able to determine whether a given info table is a stack frame or not. We have spare bits in the closure flags array anyways, use one for this information. - - - - - 08a6a2ee by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Mark closureFlags array as const - - - - - 8f9b8282 by Krzysztof Gogolewski at 2022-04-22T02:13:35-04:00 Check for zero-bit types in sizeExpr Fixes #20940 Metric Decrease: T18698a - - - - - fcf22883 by Andreas Klebinger at 2022-04-22T02:14:10-04:00 Include the way string in the file name for dump files. This can be disabled by `-fno-dump-with-ways` if not desired. Finally we will be able to look at both profiled and non-profiled dumps when compiling with dump flags and we compile in both ways. - - - - - 252394ce by Andrew Lelechenko at 2022-04-22T02:14:48-04:00 Improve error messages from GHC.IO.Encoding.Failure - - - - - 250f57c1 by Andrew Lelechenko at 2022-04-22T02:14:48-04:00 Update test baselines to match new error messages from GHC.IO.Encoding.Failure - - - - - 5ac9b321 by Ben Gamari at 2022-04-22T02:15:25-04:00 get-win32-tarballs: Drop i686 architecture As of #18487 we no longer support 32-bit Windows. Fixes #21372. - - - - - dd5fecb0 by Ben Gamari at 2022-04-22T02:16:00-04:00 hadrian: Don't rely on xxx not being present in installation path Previously Hadrian's installation makefile would assume that the string `xxx` did not appear in the installation path. This would of course break for some users. Fixes #21402. - - - - - 09e98859 by Ben Gamari at 2022-04-22T02:16:35-04:00 testsuite: Ensure that GHC doesn't pick up environment files Here we set GHC_ENVIRONMENT="-" to ensure that GHC invocations of tests don't pick up a user's local package environment. Fixes #21365. Metric Decrease: T10421 T12234 T12425 T13035 T16875 T9198 - - - - - 76bb8cb3 by Ben Gamari at 2022-04-22T02:17:11-04:00 hadrian: Enable -dlint in devel2 flavour Previously only -dcore-lint was enabled. - - - - - f435d55f by Krzysztof Gogolewski at 2022-04-22T08:00:18-04:00 Fixes to rubbish literals * In CoreToStg, the application 'RUBBISH[rep] x' was simplified to 'RUBBISH[rep]'. But it is possible that the result of the function is represented differently than the function. * In Unarise, 'LitRubbish (primRepToType prep)' is incorrect: LitRubbish takes a RuntimeRep such as IntRep, while primRepToType returns a type such as Any @(TYPE IntRep). Use primRepToRuntimeRep instead. This code is never run in the testsuite. * In StgToByteCode, all rubbish literals were assumed to be boxed. This code predates representation-polymorphic RubbishLit and I think it was not updated. I don't have a testcase for any of those issues, but the code looks wrong. - - - - - 93c16b94 by sheaf at 2022-04-22T08:00:57-04:00 Relax "suppressing errors" assert in reportWanteds The assertion in reportWanteds that we aren't suppressing all the Wanted constraints was too strong: it might be the case that we are inside an implication, and have already reported an unsolved Wanted from outside the implication. It is possible that all Wanteds inside the implication have been rewritten by the outer Wanted, so we shouldn't throw an assertion failure in that case. Fixes #21405 - - - - - 78ec692d by Andreas Klebinger at 2022-04-22T08:01:33-04:00 Mention new MutableByteArray# wrapper in base changelog. - - - - - 56d7cb53 by Eric Lindblad at 2022-04-22T14:13:32-04:00 unlist announce - - - - - 1e4dcf23 by sheaf at 2022-04-22T14:14:12-04:00 decideMonoTyVars: account for CoVars in candidates The "candidates" passed to decideMonoTyVars can contain coercion holes. This is because we might well decide to quantify over some unsolved equality constraints, as long as they are not definitely insoluble. In that situation, decideMonoTyVars was passing a set of type variables that was not closed over kinds to closeWrtFunDeps, which was tripping up an assertion failure. Fixes #21404 - - - - - 2c541f99 by Simon Peyton Jones at 2022-04-22T14:14:47-04:00 Improve floated dicts in Specialise Second fix to #21391. It turned out that we missed calling bringFloatedDictsIntoScope when specialising imports, which led to the same bug as before. I refactored to move that call to a single place, in specCalls, so we can't forget it. This meant making `FloatedDictBinds` into its own type, pairing the dictionary bindings themselves with the set of their binders. Nicer this way. - - - - - 0950e2c4 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Ensure that --extra-lib-dirs are used Previously we only took `extraLibDirs` and friends from the package description, ignoring any contribution from the `LocalBuildInfo`. Fix this. Fixes #20566. - - - - - 53cc93ae by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Drop redundant include directories The package-specific include directories in Settings.Builders.Common.cIncludeDirs are now redundant since they now come from Cabal. Closes #20566. - - - - - b2721819 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Clean up handling of libffi dependencies - - - - - 18e5103f by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: More robust library way detection Previously `test.mk` would try to determine whether the dynamic, profiling, and vanilla library ways are available by searching for `PrimOpWrappers.{,dyn_,p_}hi` in directory reported by `ghc-pkg field ghc-prim library-dirs`. However, this is extremely fragile as there is no guarantee that there is only one library directory. To handle the case of multiple `library-dirs` correct we would have to carry out the delicate task of tokenising the directory list (in shell, no less). Since this isn't a task that I am eager to solve, I have rather moved the detection logic into the testsuite driver and instead perform a test compilation in each of the ways. This should be more robust than the previous approach. I stumbled upon this while fixing #20579. - - - - - 6c7a4913 by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: Cabalify ghc-config To ensure that the build benefits from Hadrian's usual logic for building packages, avoiding #21409. Closes #21409. - - - - - 9af091f7 by Ben Gamari at 2022-04-25T10:18:53-04:00 rts: Factor out built-in GC roots - - - - - e7c4719d by Ben Gamari at 2022-04-25T10:18:54-04:00 Ensure that wired-in exception closures aren't GC'd As described in Note [Wired-in exceptions are not CAFfy], a small set of built-in exception closures get special treatment in the code generator, being declared as non-CAFfy despite potentially containing CAF references. The original intent of this treatment for the RTS to then add StablePtrs for each of the closures, ensuring that they are not GC'd. However, this logic was not applied consistently and eventually removed entirely in 951c1fb0. This lead to #21141. Here we fix this bug by reintroducing the StablePtrs and document the status quo. Closes #21141. - - - - - 9587726f by Ben Gamari at 2022-04-25T10:18:54-04:00 testsuite: Add testcase for #21141 - - - - - cb71226f by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop dead code in GHC.Linker.Static.linkBinary' Previously we supported building statically-linked executables using libtool. However, this was dropped in 91262e75dd1d80f8f28a3922934ec7e59290e28c in favor of using ar/ranlib directly. Consequently we can drop this logic. Fixes #18826. - - - - - 9420d26b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop libtool path from settings file GHC no longers uses libtool for linking and therefore this is no longer necessary. - - - - - 41cf758b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop remaining vestiges of libtool Drop libtool logic from gen-dll, allowing us to drop the remaining logic from the `configure` script. Strangely, this appears to reliably reduce compiler allocations of T16875 on Windows. Closes #18826. Metric Decrease: T16875 - - - - - e09afbf2 by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - e76705cf by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Improve documentation of closure types Also drops the unused TREC_COMMITTED transaction state. - - - - - f2c08124 by Andrew Lelechenko at 2022-04-25T10:20:44-04:00 Document behaviour of RULES with KnownNat - - - - - 360dc2bc by Li-yao Xia at 2022-04-25T19:13:06+00:00 Fix rendering of liftA haddock - - - - - 16df6058 by Ben Gamari at 2022-04-27T10:02:25-04:00 testsuite: Report minimum and maximum stat changes As suggested in #20733. - - - - - e39cab62 by Fabian Thorand at 2022-04-27T10:03:03-04:00 Defer freeing of mega block groups Solves the quadratic worst case performance of freeing megablocks that was described in issue #19897. During GC runs, we now keep a secondary free list for megablocks that is neither sorted, nor coalesced. That way, free becomes an O(1) operation at the expense of not being able to reuse memory for larger allocations. At the end of a GC run, the secondary free list is sorted and then merged into the actual free list in a single pass. That way, our worst case performance is O(n log(n)) rather than O(n^2). We postulate that temporarily losing coalescense during a single GC run won't have any adverse effects in practice because: - We would need to release enough memory during the GC, and then after that (but within the same GC run) allocate a megablock group of more than one megablock. This seems unlikely, as large objects are not copied during GC, and so we shouldn't need such large allocations during a GC run. - Allocations of megablock groups of more than one megablock are rare. They only happen when a single heap object is large enough to require that amount of space. Any allocation areas that are supposed to hold more than one heap object cannot use megablock groups, because only the first megablock of a megablock group has valid `bdescr`s. Thus, heap object can only start in the first megablock of a group, not in later ones. - - - - - 5de6be0c by Fabian Thorand at 2022-04-27T10:03:03-04:00 Add note about inefficiency in returnMemoryToOS - - - - - 8bef471a by sheaf at 2022-04-27T10:03:43-04:00 Ensure that Any is Boxed in FFI imports/exports We should only accept the type `Any` in foreign import/export declarations when it has type `Type` or `UnliftedType`. This patch adds a kind check, and a special error message triggered by occurrences of `Any` in foreign import/export declarations at other kinds. Fixes #21305 - - - - - ba3d4e1c by Ben Gamari at 2022-04-27T10:04:19-04:00 Basic response file support Here we introduce support into our command-line parsing infrastructure and driver for handling gnu-style response file arguments, typically used to work around platform command-line length limitations. Fixes #16476. - - - - - 3b6061be by Ben Gamari at 2022-04-27T10:04:19-04:00 testsuite: Add test for #16476 - - - - - 75bf1337 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix cabal-reinstall job It's quite nice we can do this by mostly deleting code Fixes #21373 - - - - - 2c00d904 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add test to check that release jobs have profiled libs - - - - - 50d78d3b by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Explicitly handle failures in test_hadrian We also disable the stage1 testing which is broken. Related to #21072 - - - - - 2dcdf091 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix shell command - - - - - 55c84123 by Matthew Pickering at 2022-04-27T10:04:55-04:00 bootstrap: Add bootstrapping files for ghc-9_2_2 Fixes #21373 - - - - - c7ee0be6 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add linting job which checks authors are not GHC CI - - - - - 23aad124 by Adam Sandberg Ericsson at 2022-04-27T10:05:31-04:00 rts: state explicitly what evacuate and scavange mean in the copying gc - - - - - 318e0005 by Ben Gamari at 2022-04-27T10:06:07-04:00 rts/eventlog: Don't attempt to flush if there is no writer If the user has not configured a writer then there is nothing to flush. - - - - - ee11d043 by Ben Gamari at 2022-04-27T10:06:07-04:00 Enable eventlog support in all ways by default Here we deprecate the eventlogging RTS ways and instead enable eventlog support in the remaining ways. This simplifies packaging and reduces GHC compilation times (as we can eliminate two whole compilations of the RTS) while simplifying the end-user story. The trade-off is a small increase in binary sizes in the case that the user does not want eventlogging support, but we think that this is a fine trade-off. This also revealed a latent RTS bug: some files which included `Cmm.h` also assumed that it defined various macros which were in fact defined by `Config.h`, which `Cmm.h` did not include. Fixing this in turn revealed that `StgMiscClosures.cmm` failed to import various spinlock statistics counters, as evidenced by the failed unregisterised build. Closes #18948. - - - - - a2e5ab70 by Andreas Klebinger at 2022-04-27T10:06:43-04:00 Change `-dsuppress-ticks` to only suppress non-code ticks. This means cost centres and coverage ticks will still be present in output. Makes using -dsuppress-all more convenient when looking at profiled builds. - - - - - ec9d7e04 by Ben Gamari at 2022-04-27T10:07:21-04:00 Bump text submodule. This should fix #21352 - - - - - c3105be4 by Andrew Lelechenko at 2022-04-27T10:08:01-04:00 Documentation for setLocaleEncoding - - - - - 7f618fd3 by sheaf at 2022-04-27T10:08:40-04:00 Update docs for change to type-checking plugins There was no mention of the changes to type-checking plugins in the 9.4.1 notes, and the extending_ghc documentation contained a reference to an outdated type. - - - - - 4419dd3a by Adam Sandberg Ericsson at 2022-04-27T10:09:18-04:00 rts: add some more documentation to StgWeak closure type - - - - - 5a7f0dee by Matthew Pickering at 2022-04-27T10:09:54-04:00 Give Cmm files fake ModuleNames which include full filepath This fixes the initialisation functions when using -prof or -finfo-table-map. Fixes #21370 - - - - - 81cf52bb by sheaf at 2022-04-27T10:10:33-04:00 Mark GHC.Prim.PtrEq as Unsafe This module exports unsafe pointer equality operations, so we accordingly mark it as Unsafe. Fixes #21433 - - - - - f6a8185d by Ben Gamari at 2022-04-28T09:10:31+00:00 testsuite: Add performance test for #14766 This distills the essence of the Sigs.hs program found in the ticket. - - - - - c7a3dc29 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Add Monoid instance to Way - - - - - 654bafea by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Enrich flavours to build profiled/debugged/threaded ghcs per stage - - - - - 4ad559c8 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: add debug_ghc and debug_stage1_ghc flavour transformers - - - - - f9728fdb by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Don't pass -rtsopts when building libraries - - - - - 769279e6 by Matthew Pickering at 2022-04-28T18:54:44-04:00 testsuite: Fix calculation about whether to pass -dynamic to compiler - - - - - da8ae7f2 by Ben Gamari at 2022-04-28T18:55:20-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 61305184 by Ben Gamari at 2022-04-28T18:55:56-04:00 Bump process submodule - - - - - a8c99391 by sheaf at 2022-04-28T18:56:37-04:00 Fix unification of ConcreteTvs, removing IsRefl# This patch fixes the unification of concrete type variables. The subtlety was that unifying concrete metavariables is more subtle than other metavariables, as decomposition is possible. See the Note [Unifying concrete metavariables], which explains how we unify a concrete type variable with a type 'ty' by concretising 'ty', using the function 'GHC.Tc.Utils.Concrete.concretise'. This can be used to perform an eager syntactic check for concreteness, allowing us to remove the IsRefl# special predicate. Instead of emitting two constraints `rr ~# concrete_tv` and `IsRefl# rr concrete_tv`, we instead concretise 'rr'. If this succeeds we can fill 'concrete_tv', and otherwise we directly emit an error message to the typechecker environment instead of deferring. We still need the error message to be passed on (instead of directly thrown), as we might benefit from further unification in which case we will need to zonk the stored types. To achieve this, we change the 'wc_holes' field of 'WantedConstraints' to 'wc_errors', which stores general delayed errors. For the moement, a delayed error is either a hole, or a syntactic equality error. hasFixedRuntimeRep_MustBeRefl is now hasFixedRuntimeRep_syntactic, and hasFixedRuntimeRep has been refactored to directly return the most useful coercion for PHASE 2 of FixedRuntimeRep. This patch also adds a field ir_frr to the InferResult datatype, holding a value of type Maybe FRROrigin. When this value is not Nothing, this means that we must fill the ir_ref field with a type which has a fixed RuntimeRep. When it comes time to fill such an ExpType, we ensure that the type has a fixed RuntimeRep by performing a representation-polymorphism check with the given FRROrigin This is similar to what we already do to ensure we fill an Infer ExpType with a type of the correct TcLevel. This allows us to properly perform representation-polymorphism checks on 'Infer' 'ExpTypes'. The fillInferResult function had to be moved to GHC.Tc.Utils.Unify to avoid a cyclic import now that it calls hasFixedRuntimeRep. This patch also changes the code in matchExpectedFunTys to make use of the coercions, which is now possible thanks to the previous change. This implements PHASE 2 of FixedRuntimeRep in some situations. For example, the test cases T13105 and T17536b are now both accepted. Fixes #21239 and #21325 ------------------------- Metric Decrease: T18223 T5631 ------------------------- - - - - - 43bd897d by Simon Peyton Jones at 2022-04-28T18:57:13-04:00 Add INLINE pragmas for Enum helper methods As #21343 showed, we need to be super-certain that the "helper methods" for Enum instances are actually inlined or specialised. I also tripped over this when I discovered that numericEnumFromTo and friends had no pragmas at all, so their performance was very fragile. If they weren't inlined, all bets were off. So I've added INLINE pragmas for them too. See new Note [Inline Enum method helpers] in GHC.Enum. I also expanded Note [Checking for INLINE loop breakers] in GHC.Core.Lint to explain why an INLINE function might temporarily be a loop breaker -- this was the initial bug report in #21343. Strangely we get a 16% runtime allocation decrease in perf/should_run/T15185, but only on i386. Since it moves in the right direction I'm disinclined to investigate, so I'll accept it. Metric Decrease: T15185 - - - - - ca1434e3 by Ben Gamari at 2022-04-28T18:57:49-04:00 configure: Bump GHC version to 9.5 Bumps haddock submodule. - - - - - 292e3971 by Teo Camarasu at 2022-04-28T18:58:28-04:00 add since annotation for GHC.Stack.CCS.whereFrom - - - - - 905206d6 by Tamar Christina at 2022-04-28T22:19:34-04:00 winio: add support to iserv. - - - - - d182897e by Tamar Christina at 2022-04-28T22:19:34-04:00 Remove unused line - - - - - 22cf4698 by Matthew Pickering at 2022-04-28T22:20:10-04:00 Revert "rts: Refactor handling of dead threads' stacks" This reverts commit e09afbf2a998beea7783e3de5dce5dd3c6ff23db. - - - - - 8ed57135 by Matthew Pickering at 2022-04-29T04:11:29-04:00 Provide efficient unionMG function for combining two module graphs. This function is used by API clients (hls). This supercedes !6922 - - - - - 0235ff02 by Ben Gamari at 2022-04-29T04:12:05-04:00 Bump bytestring submodule Update to current `master`. - - - - - 01988418 by Matthew Pickering at 2022-04-29T04:12:05-04:00 testsuite: Normalise package versions in UnusedPackages test - - - - - 724d0dc0 by Matthew Pickering at 2022-04-29T08:59:42+00:00 testsuite: Deduplicate ways correctly This was leading to a bug where we would run a profasm test twice which led to invalid junit.xml which meant the test results database was not being populated for the fedora33-perf job. - - - - - 5630dde6 by Ben Gamari at 2022-04-29T13:06:20-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - 0cdef807 by parsonsmatt at 2022-04-30T16:51:12-04:00 Add a note about instance visibility across component boundaries In principle, the *visible* instances are * all instances defined in a prior top-level declaration group (see docs on `newDeclarationGroup`), or * all instances defined in any module transitively imported by the module being compiled However, actually searching all modules transitively below the one being compiled is unreasonably expensive, so `reifyInstances` will report only the instance for modules that GHC has had some cause to visit during this compilation. This is a shortcoming: `reifyInstances` might fail to report instances for a type that is otherwise unusued, or instances defined in a different component. You can work around this shortcoming by explicitly importing the modules whose instances you want to be visible. GHC issue #20529 has some discussion around this. Fixes #20529 - - - - - e2dd884a by Ryan Scott at 2022-04-30T16:51:47-04:00 Make mkFunCo take AnonArgFlags into account Previously, whenever `mkFunCo` would produce reflexive coercions, it would use `mkVisFunTy` to produce the kind of the coercion. However, `mkFunCo` is also used to produce coercions between types of the form `ty1 => ty2` in certain places. This has the unfortunate side effect of causing the type of the coercion to appear as `ty1 -> ty2` in certain error messages, as spotted in #21328. This patch address this by changing replacing the use of `mkVisFunTy` with `mkFunctionType` in `mkFunCo`. `mkFunctionType` checks the kind of `ty1` and makes the function arrow `=>` instead of `->` if `ty1` has kind `Constraint`, so this should always produce the correct `AnonArgFlag`. As a result, this patch fixes part (2) of #21328. This is not the only possible way to fix #21328, as the discussion on that issue lists some possible alternatives. Ultimately, it was concluded that the alternatives would be difficult to maintain, and since we already use `mkFunctionType` in `coercionLKind` and `coercionRKind`, using `mkFunctionType` in `mkFunCo` is consistent with this choice. Moreover, using `mkFunctionType` does not regress the performance of any test case we have in GHC's test suite. - - - - - 170da54f by Ben Gamari at 2022-04-30T16:52:27-04:00 Convert More Diagnostics (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors. - - - - - 39edc7b4 by Marius Ghita at 2022-04-30T16:53:06-04:00 Update user guide example rewrite rules formatting Change the rewrite rule examples to include a space between the composition of `f` and `g` in the map rewrite rule examples. Without this change, if the user has locally enabled the extension OverloadedRecordDot the copied example will result in a compile time error that `g` is not a field of `f`. ``` • Could not deduce (GHC.Records.HasField "g" (a -> b) (a1 -> b)) arising from selecting the field ‘g’ ``` - - - - - 2e951e48 by Adam Sandberg Ericsson at 2022-04-30T16:53:42-04:00 ghc-boot: export typesynonyms from GHC.Utils.Encoding This makes the Haddocks easier to understand. - - - - - d8cbc77e by Adam Sandberg Ericsson at 2022-04-30T16:54:18-04:00 users guide: add categories to some flags - - - - - d0f14fad by Chris Martin at 2022-04-30T16:54:57-04:00 hacking guide: mention the core libraries committee - - - - - 34b28200 by Matthew Pickering at 2022-04-30T16:55:32-04:00 Revert "Make the specialiser handle polymorphic specialisation" This reverts commit ef0135934fe32da5b5bb730dbce74262e23e72e8. See ticket #21229 ------------------------- Metric Decrease: T15164 Metric Increase: T13056 ------------------------- - - - - - ee891c1e by Matthew Pickering at 2022-04-30T16:55:32-04:00 Add test for T21229 - - - - - ab677cc8 by Matthew Pickering at 2022-04-30T16:56:08-04:00 Hadrian: Update README about the flavour/testsuite contract There have been a number of tickets about non-tested flavours not passing the testsuite.. this is expected and now noted in the documentation. You use other flavours to run the testsuite at your own risk. Fixes #21418 - - - - - b57b5b92 by Ben Gamari at 2022-04-30T16:56:44-04:00 rts/m32: Fix assertion failure This fixes an assertion failure in the m32 allocator due to the imprecisely specified preconditions of `m32_allocator_push_filled_list`. Specifically, the caller must ensure that the page type is set to filled prior to calling `m32_allocator_push_filled_list`. While this issue did result in an assertion failure in the debug RTS, the issue is in fact benign. - - - - - a7053a6c by sheaf at 2022-04-30T16:57:23-04:00 Testsuite driver: don't crash on empty metrics The testsuite driver crashed when trying to display minimum/maximum performance changes when there are no metrics (i.e. there is no baseline available). This patch fixes that. - - - - - 636f7c62 by Andreas Klebinger at 2022-05-01T22:21:17-04:00 StgLint: Check that functions are applied to compatible runtime reps We use compatibleRep to compare reps, and avoid checking functions with levity polymorphic types because of #21399. - - - - - 60071076 by Hécate Moonlight at 2022-05-01T22:21:55-04:00 Add documentation to the ByteArray# primetype. close #21417 - - - - - 2b2e3020 by Andreas Klebinger at 2022-05-01T22:22:31-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. - - - - - 4eaf0f33 by Eric Lindblad at 2022-05-01T22:23:11-04:00 typos - - - - - fc58df90 by Niklas Hambüchen at 2022-05-02T08:59:27+00:00 libraries/base: docs: Explain relationshipt between `finalizeForeignPtr` and `*Conc*` creation Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/21420 - - - - - 3e400f20 by Krzysztof Gogolewski at 2022-05-02T18:29:23-04:00 Remove obsolete code in CoreToStg Note [Nullary unboxed tuple] was removed in e9e61f18a548b70693f4. This codepath is tested by T15696_3. - - - - - 4a780928 by Krzysztof Gogolewski at 2022-05-02T18:29:24-04:00 Fix several note references - - - - - 15ffe2b0 by Sebastian Graf at 2022-05-03T20:11:51+02:00 Assume at least one evaluation for nested SubDemands (#21081, #21133) See the new `Note [SubDemand denotes at least one evaluation]`. A demand `n :* sd` on a let binder `x=e` now means > "`x` was evaluated `n` times and in any program trace it is evaluated, `e` is > evaluated deeply in sub-demand `sd`." The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081) ```hs f :: (Bool, Bool) -> (Bool, Bool) f pr = (case pr of (a,b) -> a /= b, True) -- before: <MP(L,L)> -- after: <MP(SL,SL)> g :: Int -> (Bool, Bool) g x = let y = let z = odd x in (z,z) in f y ``` The change in demand signature "before" to "after" allows us to case-bind `z` here. Similarly good things happen for the `sd` in call sub-demands `Cn(sd)`, which allows for more eta-reduction (which is only sound with `-fno-pedantic-bottoms`, albeit). We also fix #21085, a surprising inconsistency with `Poly` to `Call` sub-demand expansion. In an attempt to fix a regression caused by less inlining due to eta-reduction in T15426, I eta-expanded the definition of `elemIndex` and `elemIndices`, thus fixing #21345 on the go. The main point of this patch is that it fixes #21081 and #21133. Annoyingly, I discovered that more precise demand signatures for join points can transform a program into a lazier program if that join point gets floated to the top-level, see #21392. There is no simple fix at the moment, but !5349 might. Thus, we accept a ~5% regression in `MultiLayerModulesTH_OneShot`, where #21392 bites us in `addListToUniqDSet`. T21392 reliably reproduces the issue. Surprisingly, ghc/alloc perf on Windows improves much more than on other jobs, by 0.4% in the geometric mean and by 2% in T16875. Metric Increase: MultiLayerModulesTH_OneShot Metric Decrease: T16875 - - - - - 948c7e40 by Andreas Klebinger at 2022-05-04T09:57:34-04:00 CoreLint - When checking for levity polymorphism look through more ticks. For expressions like `(scc<cc_name> primOp#) arg1` we should also look at arg1 to determine if we call primOp# at a fixed runtime rep. This is what corePrep already does but CoreLint didn't yet. This patch will bring them in sync in this regard. It also uses tickishFloatable in CorePrep instead of CorePrep having it's own slightly differing definition of when a tick is floatable. - - - - - 85bc73bd by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Support Unicode properly - - - - - 063d485e by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Replace LaTeX documentation syntax with Haddock The LaTeX documentation generator does not seem to have been used for quite some time, so the LaTeX-to-Haddock preprocessing step has become a pointless complication that makes documenting the contents of GHC.Prim needlessly difficult. This commit replaces the LaTeX syntax with the Haddock it would have been converted into, anyway, though with an additional distinction: it uses single quotes in places to instruct Haddock to generate hyperlinks to bindings. This improves the quality of the generated output. - - - - - d61f7428 by Ben Gamari at 2022-05-04T09:58:50-04:00 rts/ghc.mk: Only build StgCRunAsm.S when it is needed Previously the make build system unconditionally included StgCRunAsm.S in the link, meaning that the RTS would require an execstack unnecessarily. Fixes #21478. - - - - - 934a90dd by Simon Peyton Jones at 2022-05-04T16:15:34-04:00 Improve error reporting in generated code Our error reporting in generated code (via desugaring before typechecking) only worked when the generated code was just a simple call. This commit makes it work in nested cases. - - - - - 445d3657 by sheaf at 2022-05-04T16:16:12-04:00 Ensure Any is not levity-polymorphic in FFI The previous patch forgot to account for a type such as Any @(TYPE (BoxedRep l)) for a quantified levity variable l. - - - - - ddd2591c by Ben Gamari at 2022-05-04T16:16:48-04:00 Update supported LLVM versions Pull forward minimum version to match 9.2. (cherry picked from commit c26faa54c5fbe902ccb74e79d87e3fa705e270d1) - - - - - f9698d79 by Ben Gamari at 2022-05-04T16:16:48-04:00 testsuite/T7275: Use sed -r Darwin requires the `-r` flag to be compatible with GNU sed. (cherry picked from commit 512338c8feec96c38ef0cf799f3a01b77c967c56) - - - - - 8635323b by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Use ld.lld on ARMv7/Linux Due to #16177. Also cleanup some code style issues. (cherry picked from commit cc1c3861e2372f464bf9e3c9c4d4bd83f275a1a6) - - - - - 4f6370c7 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Always preserve artifacts, even in failed jobs (cherry picked from commit fd08b0c91ea3cab39184f1b1b1aafcd63ce6973f) - - - - - 6f662754 by Ben Gamari at 2022-05-04T16:16:48-04:00 configure: Make sphinx version check more robust It appears that the version of sphinx shipped on CentOS 7 reports a version string of `Sphinx v1...`. Accept the `v`. (cherry picked from commit a9197a292fd4b13308dc6664c01351c7239357ed) - - - - - 0032dc38 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Don't run make job in release pipelines (cherry picked from commit 16d6a8ff011f2194485387dcca1c00f8ddcdbdeb) - - - - - 27f9aab3 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab/ci: Fix name of bootstrap compiler directory Windows binary distributions built with Hadrian have a target platform suffix in the name of their root directory. Teach `ci.sh` about this fact. (cherry picked from commit df5752f39671f6d04d8cd743003469ae5eb67235) - - - - - b528f0f6 by Krzysztof Gogolewski at 2022-05-05T09:05:43-04:00 Fix several note references, part 2 - - - - - 691aacf6 by Adam Sandberg Ericsson at 2022-05-05T09:06:19-04:00 adjustors: align comment about number of integer like arguments with implementation for Amd4+MinGW implementation - - - - - f050557e by Simon Jakobi at 2022-05-05T12:47:32-04:00 Remove two uses of IntMap.size IntMap.size is O(n). The new code should be slightly more efficient. The transformation of GHC.CmmToAsm.CFG.calcFreqs.nodeCount can be described formally as the transformation: (\sum_{0}^{n-1} \sum_{0}^{k-1} i_nk) + n ==> (\sum_{0}^{n-1} 1 + \sum_{0}^{k-1} i_nk) - - - - - 7da90ae3 by Tom Ellis at 2022-05-05T12:48:09-04:00 Explain that 'fail s' should run in the monad itself - - - - - 610d0283 by Matthew Craven at 2022-05-05T12:48:47-04:00 Add a test for the bracketing in rules for (^) - - - - - 016f9ca6 by Matthew Craven at 2022-05-05T12:48:47-04:00 Fix broken rules for (^) with known small powers - - - - - 9372aaab by Matthew Craven at 2022-05-05T12:48:47-04:00 Give the two T19569 tests different names - - - - - 61901b32 by Andreas Klebinger at 2022-05-05T12:49:23-04:00 SpecConstr: Properly create rules for call patterns representing partial applications The main fix is that in addVoidWorkerArg we now add the argument to the front. This fixes #21448. ------------------------- Metric Decrease: T16875 ------------------------- - - - - - 71278dc7 by Teo Camarasu at 2022-05-05T12:50:03-04:00 add since annotations for instances of ByteArray - - - - - 962ff90b by sheaf at 2022-05-05T12:50:42-04:00 Start 9.6.1-notes Updates the documentation notes to start tracking changes for the 9.6.1 release (instead of 9.4). - - - - - aacb15a3 by Matthew Pickering at 2022-05-05T20:24:01-04:00 ci: Add job to check that jobs.yaml is up-to-date There have been quite a few situations where jobs.yaml has been out of date. It's better to add a CI job which checks that it's right. We don't want to use a staged pipeline because it obfuscates the structure of the pipeline. - - - - - be7102e5 by Ben Gamari at 2022-05-05T20:24:37-04:00 rts: Ensure that XMM registers are preserved on Win64 Previously we only preserved the bottom 64-bits of the callee-saved 128-bit XMM registers, in violation of the Win64 calling convention. Fix this. Fixes #21465. - - - - - 73b22ff1 by Ben Gamari at 2022-05-05T20:24:37-04:00 testsuite: Add test for #21465 - - - - - e2ae9518 by Ziyang Liu at 2022-05-06T19:22:22-04:00 Allow `let` just before pure/return in ApplicativeDo The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case. - - - - - 0415449a by Matthew Pickering at 2022-05-06T19:22:58-04:00 template-haskell: Fix representation of OPAQUE pragmas There is a mis-match between the TH representation of OPAQUE pragmas and GHC's internal representation due to how OPAQUE pragmas disallow phase annotations. It seemed most in keeping to just fix the wired in name issue by adding a special case to the desugaring of INLINE pragmas rather than making TH/GHC agree with how the representation should look. Fixes #21463 - - - - - 4de887e2 by Simon Peyton Jones at 2022-05-06T19:23:34-04:00 Comments only: Note [AppCtxt] - - - - - 6e69964d by Matthew Pickering at 2022-05-06T19:24:10-04:00 Fix name of windows release bindist in doc-tarball job - - - - - ced4689e by Matthew Pickering at 2022-05-06T19:24:46-04:00 ci: Generate source-tarball in release jobs We need to distribute the source tarball so we should generate it in the CI pipeline. - - - - - 3c91de21 by Rob at 2022-05-08T13:40:53+02:00 Change Specialise to use OrdList. Fixes #21362 Metric Decrease: T16875 - - - - - 67072c31 by Simon Jakobi at 2022-05-08T12:23:43-04:00 Tweak GHC.CmmToAsm.CFG.delEdge mapAdjust is more efficient than mapAlter. - - - - - 374554bb by Teo Camarasu at 2022-05-09T16:24:37-04:00 Respect -po when heap profiling (#21446) - - - - - 1ea414b6 by Teo Camarasu at 2022-05-09T16:24:37-04:00 add test case for #21446 - - - - - c7902078 by Jens Petersen at 2022-05-09T16:25:17-04:00 avoid hadrian/bindist/Makefile install_docs error when --docs=none When docs are disabled the bindist does not have docs/ and hence docs-utils/ is not generated. Here we just test that docs-utils exists before attempting to install prologue.txt and gen_contents_index to avoid the error: /usr/bin/install: cannot stat 'docs-utils/prologue.txt': No such file or directory make: *** [Makefile:195: install_docs] Error 1 - - - - - 158bd659 by Hécate Moonlight at 2022-05-09T16:25:56-04:00 Correct base's changelog for 4.16.1.0 This commit reaffects the new Ix instances of the foreign integral types from base 4.17 to 4.16.1.0 closes #21529 - - - - - a4fbb589 by Sylvain Henry at 2022-05-09T16:26:36-04:00 STG: only print cost-center if asked to - - - - - 50347ded by Gergő Érdi at 2022-05-10T11:43:33+00:00 Improve "Glomming" note Add a paragraph that clarifies that `occurAnalysePgm` finding out-of-order references, and thus needing to glom, is not a cause for concern when its root cause is rewrite rules. - - - - - df2e3373 by Eric Lindblad at 2022-05-10T20:45:41-04:00 update INSTALL - - - - - dcac3833 by Matthew Pickering at 2022-05-10T20:46:16-04:00 driver: Make -no-keep-o-files -no-keep-hi-files work in --make mode It seems like it was just an oversight to use the incorrect DynFlags (global rather than local) when implementing these two options. Using the local flags allows users to request these intermediate files get cleaned up, which works fine in --make mode because 1. Interface files are stored in memory 2. Object files are only cleaned at the end of session (after link) Fixes #21349 - - - - - 35da81f8 by Ben Gamari at 2022-05-10T20:46:52-04:00 configure: Check for ffi.h As noted in #21485, we checked for ffi.h yet then failed to throw an error if it is missing. Fixes #21485. - - - - - bdc99cc2 by Simon Peyton Jones at 2022-05-10T20:47:28-04:00 Check for uninferrable variables in tcInferPatSynDecl This fixes #21479 See Note [Unquantified tyvars in a pattern synonym] While doing this, I found that some error messages pointed at the pattern synonym /name/, rather than the /declaration/ so I widened the SrcSpan to encompass the declaration. - - - - - 142a73d9 by Matthew Pickering at 2022-05-10T20:48:04-04:00 hadrian: Fix split-sections transformer The splitSections transformer has been broken since -dynamic-too support was implemented in hadrian. This is because we actually build the dynamic way when building the dynamic way, so the predicate would always fail. The fix is to just always pass `split-sections` even if it doesn't do anything for a particular way. Fixes #21138 - - - - - 699f5935 by Matthew Pickering at 2022-05-10T20:48:04-04:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. Closes #21135 - - - - - 21feece2 by Simon Peyton Jones at 2022-05-10T20:48:39-04:00 Use the wrapper for an unlifted binding We assumed the wrapper for an unlifted binding is the identity, but as #21516 showed, that is no always true. Solution is simple: use it. - - - - - 68d1ea5f by Matthew Pickering at 2022-05-10T20:49:15-04:00 docs: Fix path to GHC API docs in index.html In the make bindists we generate documentation in docs/ghc-<VER> but the hadrian bindists generate docs/ghc/ so the path to the GHC API docs was wrong in the index.html file. Rather than make the hadrian and make bindists the same it was easier to assume that if you're using the mkDocs script that you're using hadrian bindists. Fixes #21509 - - - - - 9d8f44a9 by Matthew Pickering at 2022-05-10T20:49:51-04:00 hadrian: Don't pass -j to haddock This has high potential for oversubcribing as many haddock jobs can be spawned in parralel which will each request the given number of capabilities. Once -jsem is implemented (#19416, !5176) we can expose that haddock via haddock and use that to pass a semaphore. Ticket #21136 - - - - - fec3e7aa by Matthew Pickering at 2022-05-10T20:50:27-04:00 hadrian: Only copy and install libffi headers when using in-tree libffi When passed `--use-system-libffi` then we shouldn't copy and install the headers from the system package. Instead the headers are expected to be available as a runtime dependency on the users system. Fixes #21485 #21487 - - - - - 5b791ed3 by mikael at 2022-05-11T08:22:13-04:00 FIND_LLVM_PROG: Recognize llvm suffix used by FreeBSD, ie llc10. - - - - - 8500206e by ARATA Mizuki at 2022-05-11T08:22:57-04:00 Make floating-point abs IEEE 754 compliant The old code used by via-C backend didn't handle the sign bit of NaN. See #21043. - - - - - 4a4c77ed by Alan Zimmerman at 2022-05-11T08:23:33-04:00 EPA: do statement with leading semicolon has wrong anchor The code do; a <- doAsync; b Generated an incorrect Anchor for the statement list that starts after the first semicolon. This commit fixes it. Closes #20256 - - - - - e3ca8dac by Simon Peyton Jones at 2022-05-11T08:24:08-04:00 Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. - - - - - fcc7dc4c by Ben Gamari at 2022-05-11T20:05:41-04:00 gitlab-ci: Check for dynamic msys2 dependencies Both #20878 and #21196 were caused by unwanted dynamic dependencies being introduced by boot libraries. Ensure that we catch this in CI by attempting to run GHC in an environment with a minimal PATH. - - - - - 3c998f0d by Matthew Pickering at 2022-05-11T20:06:16-04:00 Add back Debian9 CI jobs We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19 not being at EOL until April 2023 and they still need tinfo5. Fixes #21469 - - - - - dea9a3d9 by Ben Gamari at 2022-05-11T20:06:51-04:00 rts: Drop setExecutable Since f6e366c058b136f0789a42222b8189510a3693d1 setExecutable has been dead code. Drop it. - - - - - 32cdf62d by Simon Peyton Jones at 2022-05-11T20:07:27-04:00 Add a missing guard in GHC.HsToCore.Utils.is_flat_prod_pat This missing guard gave rise to #21519. - - - - - 2c00a8d0 by Matthew Pickering at 2022-05-11T20:08:02-04:00 Add mention of -hi to RTS --help Fixes #21546 - - - - - a2dcad4e by Andre Marianiello at 2022-05-12T02:15:48+00:00 Decouple dynflags in Cmm parser (related to #17957) - - - - - 3a022baa by Andre Marianiello at 2022-05-12T02:15:48+00:00 Remove Module argument from initCmmParserConfig - - - - - 2fc8d76b by Andre Marianiello at 2022-05-12T02:15:48+00:00 Move CmmParserConfig and PDConfig into GHC.Cmm.Parser.Config - - - - - b8c5ffab by Andre Marianiello at 2022-05-12T18:13:55-04:00 Decouple dynflags in GHC.Core.Opt.Arity (related to #17957) Metric Decrease: T16875 - - - - - 3bf938b6 by sheaf at 2022-05-12T18:14:34-04:00 Update extending_ghc for TcPlugin changes The documentation still mentioned Derived constraints and an outdated datatype TcPluginResult. - - - - - 668a9ef4 by jackohughes at 2022-05-13T12:10:34-04:00 Fix printing of brackets in multiplicities (#20315) Change mulArrow to allow for printing of correct application precedence where necessary and update callers of mulArrow to reflect this. As part of this, move mulArrow from GHC/Utils/Outputtable to GHC/Iface/Type. Fixes #20315 - - - - - 30b8b7f1 by Ben Gamari at 2022-05-13T12:11:09-04:00 rts: Add debug output on ocResolve failure This makes it easier to see how resolution failures nest. - - - - - 53b3fa1c by Ben Gamari at 2022-05-13T12:11:09-04:00 rts/PEi386: Fix handling of weak symbols Previously we would flag the symbol as weak but failed to set its address, which must be computed from an "auxiliary" symbol entry the follows the weak symbol. Fixes #21556. - - - - - 5678f017 by Ben Gamari at 2022-05-13T12:11:09-04:00 testsuite: Add tests for #21556 - - - - - 49af0e52 by Ben Gamari at 2022-05-13T22:23:26-04:00 Re-export augment and build from GHC.List Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/19127 - - - - - aed356e1 by Simon Peyton Jones at 2022-05-13T22:24:02-04:00 Comments only around HsWrapper - - - - - 27b90409 by Ben Gamari at 2022-05-16T08:30:44-04:00 hadrian: Introduce linting flavour transformer (+lint) The linting flavour enables -dlint uniformly across anything build by the stage1 compiler. -dcmm-lint is not currently enabled because it fails on i386 (see #21563) - - - - - 3f316776 by Matthew Pickering at 2022-05-16T08:30:44-04:00 hadrian: Uniformly enable -dlint with enableLinting transformer This fixes some bugs where * -dcore-lint was being passed when building stage1 libraries with the boot compiler * -dcore-lint was not being passed when building executables. Fixes #20135 - - - - - 3d74cfca by Andreas Klebinger at 2022-05-16T08:31:20-04:00 Make closure macros EXTERN_INLINE to make debugging easier Implements #21424. The RTS macros get_itbl and friends are extremely helpful during debugging. However only a select few of those were available in the compiled RTS as actual symbols as the rest were INLINE macros. This commit marks all of them as EXTERN_INLINE. This will still inline them at use sites but allow us to use their compiled counterparts during debugging. This allows us to use things like `p get_fun_itbl(ptr)` in the gdb shell since `get_fun_itbl` will now be available as symbol! - - - - - 93153aab by Matthew Pickering at 2022-05-16T08:31:55-04:00 packaging: Introduce CI job for generating hackage documentation This adds a CI job (hackage-doc-tarball) which generates the necessary tarballs for uploading libraries and documentation to hackage. The release script knows to download this folder and the upload script will also upload the release to hackage as part of the release. The `ghc_upload_libs` script is moved from ghc-utils into .gitlab/ghc_upload_libs There are two modes, preparation and upload. * The `prepare` mode takes a link to a bindist and creates a folder containing the source and doc tarballs ready to upload to hackage. * The `upload` mode takes the folder created by prepare and performs the upload to hackage. Fixes #21493 Related to #21512 - - - - - 65d31d05 by Simon Peyton Jones at 2022-05-16T15:32:50-04:00 Add arity to the INLINE pragmas for pattern synonyms The lack of INLNE arity was exposed by #21531. The fix is simple enough, if a bit clumsy. - - - - - 43c018aa by Krzysztof Gogolewski at 2022-05-16T15:33:25-04:00 Misc cleanup - Remove groupWithName (unused) - Use the RuntimeRepType synonym where possible - Replace getUniqueM + mkSysLocalOrCoVar with mkSysLocalOrCoVarM No functional changes. - - - - - 8dfea078 by Pavol Vargovcik at 2022-05-16T15:34:04-04:00 TcPlugin: access to irreducible givens + fix passed ev_binds_var - - - - - fb579e15 by Ben Gamari at 2022-05-17T00:25:02-04:00 driver: Introduce pgmcxx Here we introduce proper support for compilation of C++ objects. This includes: * logic in `configure` to detect the C++ toolchain and propagating this information into the `settings` file * logic in the driver to use the C++ toolchain when compiling C++ sources - - - - - 43628ed4 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Build T20918 with HC, not CXX - - - - - 0ef249aa by Ben Gamari at 2022-05-17T00:25:02-04:00 Introduce package to capture dependency on C++ stdlib Here we introduce a new "virtual" package into the initial package database, `system-cxx-std-lib`. This gives users a convenient, platform agnostic way to link against C++ libraries, addressing #20010. Fixes #20010. - - - - - 03efe283 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Add tests for system-cxx-std-lib package Test that we can successfully link against C++ code both in GHCi and batch compilation. See #20010 - - - - - 5f6527e0 by nineonine at 2022-05-17T00:25:38-04:00 OverloadedRecordFields: mention parent name in 'ambiguous occurrence' error for better disambiguation (#17420) - - - - - eccdb208 by Simon Peyton Jones at 2022-05-17T07:16:39-04:00 Adjust flags for pprTrace We were using defaultSDocContext for pprTrace, which suppresses lots of useful infomation. This small MR adds GHC.Utils.Outputable.traceSDocContext and uses it for pprTrace and pprTraceUserWarning. traceSDocContext is a global, and hence not influenced by flags, but that seems unavoidable. But I made the sdocPprDebug bit controlled by unsafeHasPprDebug, since we have the latter for exactly this purpose. Fixes #21569 - - - - - d2284c4c by Simon Peyton Jones at 2022-05-17T07:17:15-04:00 Fix bad interaction between withDict and the Specialiser This MR fixes a bad bug, where the withDict was inlined too vigorously, which in turn made the type-class Specialiser generate a bogus specialisation, because it saw the same overloaded function applied to two /different/ dictionaries. Solution: inline `withDict` later. See (WD8) of Note [withDict] in GHC.HsToCore.Expr See #21575, which is fixed by this change. - - - - - 70f52443 by Matthew Pickering at 2022-05-17T07:17:50-04:00 Bump time submodule to 1.12.2 This bumps the time submodule to the 1.12.2 release. Fixes #21571 - - - - - 2343457d by Vladislav Zavialov at 2022-05-17T07:18:26-04:00 Remove unused test files (#21582) Those files were moved to the perf/ subtree in 11c9a469, and then accidentally reintroduced in 680ef2c8. - - - - - cb52b4ae by Ben Gamari at 2022-05-17T16:00:14-04:00 CafAnal: Improve code clarity Here we implement a few measures to improve the clarity of the CAF analysis implementation. Specifically: * Use CafInfo instead of Bool since the former is more descriptive * Rename CAFLabel to CAFfyLabel, since not all CAFfyLabels are in fact CAFs * Add numerous comments - - - - - b048a9f4 by Ben Gamari at 2022-05-17T16:00:14-04:00 codeGen: Ensure that static datacon apps are included in SRTs When generating an SRT for a recursive group, GHC.Cmm.Info.Build.oneSRT filters out recursive references, as described in Note [recursive SRTs]. However, doing so for static functions would be unsound, for the reason described in Note [Invalid optimisation: shortcutting]. However, the same argument applies to static data constructor applications, as we discovered in #20959. Fix this by ensuring that static data constructor applications are included in recursive SRTs. The approach here is not entirely satisfactory, but it is a starting point. Fixes #20959. - - - - - 0e2d16eb by Matthew Pickering at 2022-05-17T16:00:50-04:00 Add test for #21558 This is now fixed on master and 9.2 branch. Closes #21558 - - - - - ef3c8d9e by Sylvain Henry at 2022-05-17T20:22:02-04:00 Don't store LlvmConfig into DynFlags LlvmConfig contains information read from llvm-passes and llvm-targets files in GHC's top directory. Reading these files is done only when needed (i.e. when the LLVM backend is used) and cached for the whole compiler session. This patch changes the way this is done: - Split LlvmConfig into LlvmConfig and LlvmConfigCache - Store LlvmConfigCache in HscEnv instead of DynFlags: there is no good reason to store it in DynFlags. As it is fixed per session, we store it in the session state instead (HscEnv). - Initializing LlvmConfigCache required some changes to driver functions such as newHscEnv. I've used the opportunity to untangle initHscEnv from initGhcMonad (in top-level GHC module) and to move it to GHC.Driver.Main, close to newHscEnv. - I've also made `cmmPipeline` independent of HscEnv in order to remove the call to newHscEnv in regalloc_unit_tests. - - - - - 828fbd8a by Andreas Klebinger at 2022-05-17T20:22:38-04:00 Give all EXTERN_INLINE closure macros prototypes - - - - - cfc8e2e2 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Introduce [sg]etFinalizerExceptionHandler This introduces a global hook which is called when an exception is thrown during finalization. - - - - - 372cf730 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Throw exceptions raised while closing finalized Handles Fixes #21336. - - - - - 3dd2f944 by Ben Gamari at 2022-05-19T04:57:51-04:00 testsuite: Add tests for #21336 - - - - - 297156e0 by Matthew Pickering at 2022-05-19T04:58:27-04:00 Add release flavour and use it for the release jobs The release flavour is essentially the same as the perf flavour currently but also enables `-haddock`. I have hopefully updated all the relevant places where the `-perf` flavour was hardcoded. Fixes #21486 - - - - - a05b6293 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Don't build sphinx documentation on centos The centos docker image lacks the sphinx builder so we disable building sphinx docs for these jobs. Fixes #21580 - - - - - 209d7c69 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Use correct syntax when args list is empty This seems to fail on the ancient version of bash present on CentOS - - - - - 02d16334 by Matthew Pickering at 2022-05-19T04:59:03-04:00 hadrian: Don't attempt to build dynamic profiling libraries We only support building static profiling libraries, the transformer was requesting things like a dynamic, threaded, debug, profiling RTS, which we have never produced nor distributed. Fixes #21567 - - - - - 35bdab1c by Ben Gamari at 2022-05-19T04:59:39-04:00 configure: Check CC_STAGE0 for --target support We previously only checked the stage 1/2 compiler for --target support. We got away with this for quite a while but it eventually caught up with us in #21579, where `bytestring`'s new NEON implementation was unbuildable on Darwin due to Rosetta's seemingly random logic for determining which executable image to execute. This lead to a confusing failure to build `bytestring`'s cbits, when `clang` tried to compile NEON builtins while targetting x86-64. Fix this by checking CC_STAGE0 for --target support. Fixes #21579. - - - - - 0ccca94b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator analysis of `CmmGraph` This commit adds module `GHC.Cmm.Dominators`, which provides a wrapper around two existing algorithms in GHC: the Lengauer-Tarjan dominator analysis from the X86 back end and the reverse postorder ordering from the Cmm Dataflow framework. Issue #20726 proposes that we evaluate some alternatives for dominator analysis, but for the time being, the best path forward is simply to use the existing analysis on `CmmGraph`s. This commit addresses a bullet in #21200. - - - - - 54f0b578 by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator-tree function - - - - - 05ed917b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add HasDebugCallStack; remove unneeded extensions - - - - - 0b848136 by Andreas Klebinger at 2022-05-20T05:32:32-04:00 document fields of `DominatorSet` - - - - - 8a26e8d6 by Ben Gamari at 2022-05-20T05:33:08-04:00 nonmoving: Fix documentation of GC statistics fields These were previously incorrect. Fixes #21553. - - - - - c1e24e61 by Matthew Pickering at 2022-05-20T05:33:44-04:00 Remove pprTrace from pushCoercionIntoLambda (#21555) This firstly caused spurious output to be emitted (as evidenced by #21555) but even worse caused a massive coercion to be attempted to be printed (> 200k terms) which would invariably eats up all the memory of your computer. The good news is that removing this trace allows the program to compile to completion, the bad news is that the program exhibits a core lint error (on 9.0.2) but not any other releases it seems. Fixes #21577 and #21555 - - - - - a36d12ee by Zubin Duggal at 2022-05-20T10:44:35-04:00 docs: Fix LlvmVersion in manpage (#21280) - - - - - 36b8a57c by Matthew Pickering at 2022-05-20T10:45:10-04:00 validate: Use $make rather than make In the validate script we are careful to use the $make variable as this stores whether we are using gmake, make, quiet mode etc. There was just this one place where we failed to use it. Fixes #21598 - - - - - 4aa3c5bd by Norman Ramsey at 2022-05-21T03:11:04+00:00 Change `Backend` type and remove direct dependencies With this change, `Backend` becomes an abstract type (there are no more exposed value constructors). Decisions that were formerly made by asking "is the current back end equal to (or different from) this named value constructor?" are now made by interrogating the back end about its properties, which are functions exported by `GHC.Driver.Backend`. There is a description of how to migrate code using `Backend` in the user guide. Clients using the GHC API can find a backdoor to access the Backend datatype in GHC.Driver.Backend.Internal. Bumps haddock submodule. Fixes #20927 - - - - - ecf5f363 by Julian Ospald at 2022-05-21T12:51:16-04:00 Respect DESTDIR in hadrian bindist Makefile, fixes #19646 - - - - - 7edd991e by Julian Ospald at 2022-05-21T12:51:16-04:00 Test DESTDIR in test_hadrian() - - - - - ea895b94 by Matthew Pickering at 2022-05-22T21:57:47-04:00 Consider the stage of typeable evidence when checking stage restriction We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547 - - - - - ffbe28e5 by Dominik Peteler at 2022-05-22T21:58:23-04:00 Modularize GHC.Core.Opt.LiberateCase Progress towards #17957 - - - - - bc723ac2 by Simon Peyton Jones at 2022-05-23T17:09:34+01:00 Improve FloatOut and SpecConstr This patch addresses a relatively obscure situation that arose when chasing perf regressions in !7847, which itself is fixing It does two things: * SpecConstr can specialise on ($df d1 d2) dictionary arguments * FloatOut no longer checks argument strictness See Note [Specialising on dictionaries] in GHC.Core.Opt.SpecConstr. A test case is difficult to construct, but it makes a big difference in nofib/real/eff/VSM, at least when we have the patch for #21286 installed. (The latter stops worker/wrapper for dictionary arguments). There is a spectacular, but slightly illusory, improvement in runtime perf on T15426. I have documented the specifics in T15426 itself. Metric Decrease: T15426 - - - - - 1a4195b0 by John Ericson at 2022-05-23T17:33:59-04:00 Make debug a `Bool` not an `Int` in `StgToCmmConfig` We don't need any more resolution than this. Rename the field to `stgToCmmEmitDebugInfo` to indicate it is no longer conveying any "level" information. - - - - - e9fff12b by Alan Zimmerman at 2022-05-23T21:04:49-04:00 EPA : Remove duplicate comments in DataFamInstD The code data instance Method PGMigration = MigrationQuery Query -- ^ Run a query against the database | MigrationCode (Connection -> IO (Either String ())) -- ^ Run any arbitrary IO code Resulted in two instances of the "-- ^ Run a query against the database" comment appearing in the Exact Print Annotations when it was parsed. Ensure only one is kept. Closes #20239 - - - - - e2520df3 by Alan Zimmerman at 2022-05-23T21:05:27-04:00 EPA: Comment Order Reversed Make sure comments captured in the exact print annotations are in order of increasing location Closes #20718 - - - - - 4b45fd72 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Add test for T21455 - - - - - e2cd1d43 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Allow passing -po outside profiling way Resolves #21455 - - - - - 3b8c413a by Greg Steuck at 2022-05-24T10:49:52-04:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 1db877a3 by Ben Gamari at 2022-05-24T10:50:28-04:00 hadrian/bindist: Drop redundant include of install.mk `install.mk` is already included by `config.mk`. Moreover, `install.mk` depends upon `config.mk` to set `RelocatableBuild`, making this first include incorrect. - - - - - f485d267 by Greg Steuck at 2022-05-24T10:51:08-04:00 Remove -z wxneeded for OpenBSD With all the recent W^X fixes in the loader this workaround is not necessary any longer. I verified that the only tests failing for me on OpenBSD 7.1-current are the same (libc++ related) before and after this commit (with --fast). - - - - - 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Andrew Lelechenko at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergő Érdi at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Andrew Lelechenko at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Andrew Lelechenko at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by Matthew Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Andrew Lelechenko at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by Matthew Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Andrew Lelechenko at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Andrew Lelechenko at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Andrew Lelechenko at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Andrew Lelechenko at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Andrew Lelechenko at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Andrew Lelechenko at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Andrew Lelechenko at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 8c72411d by Gergő Érdi at 2022-10-17T19:20:04-04:00 Add `Enum (Down a)` instance that swaps `succ` and `pred` See https://github.com/haskell/core-libraries-committee/issues/51 for discussion. The key points driving the implementation are the following two ideas: * For the `Int` type, `comparing (complement @Int)` behaves exactly as an order-swapping `compare @Int`. * `enumFrom @(Down a)` can be implemented in terms of `enumFromThen @a`, if only the corner case of starting at the very end is handled specially - - - - - d80ad2f4 by Alan Zimmerman at 2022-10-17T19:20:40-04:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 08ab5419 by Andreas Klebinger at 2022-10-17T19:21:15-04:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - ff6275ef by Andreas Klebinger at 2022-10-17T19:21:52-04:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - abb82f38 by Eric Lindblad at 2022-10-17T19:22:33-04:00 example rewrite - - - - - 39beb801 by Eric Lindblad at 2022-10-17T19:22:33-04:00 remove redirect - - - - - 0d9fb651 by Eric Lindblad at 2022-10-17T19:22:33-04:00 use heredoc - - - - - 0fa2d185 by Matthew Pickering at 2022-10-17T19:23:10-04:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - ced664a2 by Krzysztof Gogolewski at 2022-10-17T19:23:10-04:00 Fix T15155l not getting -fllvm - - - - - 0ac60423 by Andreas Klebinger at 2022-10-18T03:34:47-04:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 9ecd1ac0 by M Farkas-Dyck at 2022-10-18T03:35:38-04:00 Make `Functor` a superclass of `TrieMap`, which lets us derive the `map` functions. - - - - - f60244d7 by Ben Gamari at 2022-10-18T03:36:15-04:00 configure: Bump minimum bootstrap GHC version Fixes #22245 - - - - - ba4bd4a4 by Matthew Pickering at 2022-10-18T03:36:55-04:00 Build System: Remove out-of-date comment about make build system Both make and hadrian interleave compilation of modules of different modules and don't respect the package boundaries. Therefore I just remove this comment which points out this "difference". Fixes #22253 - - - - - e1bbd368 by Matthew Pickering at 2022-10-18T16:15:49+02:00 Allow configuration of error message printing This MR implements the idea of #21731 that the printing of a diagnostic method should be configurable at the printing time. The interface of the `Diagnostic` class is modified from: ``` class Diagnostic a where diagnosticMessage :: a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` to ``` class Diagnostic a where type DiagnosticOpts a defaultDiagnosticOpts :: DiagnosticOpts a diagnosticMessage :: DiagnosticOpts a -> a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` and so each `Diagnostic` can implement their own configuration record which can then be supplied by a client in order to dictate how to print out the error message. At the moment this only allows us to implement #21722 nicely but in future it is more natural to separate the configuration of how much information we put into an error message and how much we decide to print out of it. Updates Haddock submodule - - - - - 99dc3e3d by Matthew Pickering at 2022-10-18T16:15:53+02:00 Add -fsuppress-error-contexts to disable printing error contexts in errors In many development environments, the source span is the primary means of seeing what an error message relates to, and the In the expression: and In an equation for: clauses are not particularly relevant. However, they can grow to be quite long, which can make the message itself both feel overwhelming and interact badly with limited-space areas. It's simple to implement this flag so we might as well do it and give the user control about how they see their messages. Fixes #21722 - - - - - 5b3a992f by Dai at 2022-10-19T10:45:45-04:00 Add VecSlot for unboxed sums of SIMD vectors This patch adds the missing `VecRep` case to `primRepSlot` function and all the necessary machinery to carry this new `VecSlot` through code generation. This allows programs involving unboxed sums of SIMD vectors to be written and compiled. Fixes #22187 - - - - - 6d7d9181 by sheaf at 2022-10-19T10:45:45-04:00 Remove SIMD conversions This patch makes it so that packing/unpacking SIMD vectors always uses the right sized types, e.g. unpacking a Word16X4# will give a tuple of Word16#s. As a result, we can get rid of the conversion instructions that were previously required. Fixes #22296 - - - - - 3be48877 by sheaf at 2022-10-19T10:45:45-04:00 Cmm Lint: relax SIMD register assignment check As noted in #22297, SIMD vector registers can be used to store different kinds of values, e.g. xmm1 can be used both to store integer and floating point values. The Cmm type system doesn't properly account for this, so we weaken the Cmm register assignment lint check to only compare widths when comparing a vector type with its allocated vector register. - - - - - f7b7a312 by sheaf at 2022-10-19T10:45:45-04:00 Disable some SIMD tests on non-X86 architectures - - - - - 83638dce by M Farkas-Dyck at 2022-10-19T10:46:29-04:00 Scrub various partiality involving lists (again). Lets us avoid some use of `head` and `tail`, and some panics. - - - - - c3732c62 by M Farkas-Dyck at 2022-10-19T10:47:13-04:00 Enforce invariant of `ListBag` constructor. - - - - - 488d3631 by Andrew Lelechenko at 2022-10-19T10:47:52-04:00 More precise types for fields of OverlappingInstances and UnsafeOverlap in TcSolverReportMsg It's clear from asserts in `GHC.Tc.Errors` that `overlappingInstances_matches` and `unsafeOverlapped` are supposed to be non-empty, and `unsafeOverlap_matches` contains a single instance, but these invariants are immediately lost afterwards and not encoded in types. This patch enforces the invariants by pattern matching and makes types more precise, avoiding asserts and partial functions such as `head`. - - - - - 607ce263 by sheaf at 2022-10-19T10:47:52-04:00 Rename unsafeOverlap_matches -> unsafeOverlap_match in UnsafeOverlap - - - - - 1fab9598 by Matthew Pickering at 2022-10-19T10:48:29-04:00 Add SpliceTypes test for hie files This test checks that typed splices and quotes get the right type information when used in hiefiles. See #21619 - - - - - a8b52786 by Jan Hrček at 2022-10-19T10:49:09-04:00 Small language fixes in 'Using GHC' - - - - - 1dab1167 by Gergő Érdi at 2022-10-19T10:49:51-04:00 Fix typo in `Opt_WriteIfSimplifiedCore`'s name - - - - - b17cfc9c by sheaf at 2022-10-19T10:50:37-04:00 TyEq:N assertion: only for saturated applications The assertion that checked TyEq:N in canEqCanLHSFinish incorrectly triggered in the case of an unsaturated newtype TyCon heading the RHS, even though we can't unwrap such an application. Now, we only trigger an assertion failure in case of a saturated application of a newtype TyCon. Fixes #22310 - - - - - ff6f2228 by M Farkas-Dyck at 2022-10-20T16:15:51-04:00 CoreToStg: purge `DynFlags`. - - - - - 1ebd521f by Matthew Pickering at 2022-10-20T16:16:27-04:00 ci: Make fat014 test robust For some reason I implemented this as a makefile test rather than a ghci_script test. Hopefully making it a ghci_script test makes it more robust. Fixes #22313 - - - - - 8cd6f435 by Curran McConnell at 2022-10-21T02:58:01-04:00 remove a no-warn directive from GHC.Cmm.ContFlowOpt This patch is motivated by the desire to remove the {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} directive at the top of GHC.Cmm.ContFlowOpt. (Based on the text in this coding standards doc, I understand it's a goal of the project to remove such directives.) I chose this task because I'm a new contributor to GHC, and it seemed like a good way to get acquainted with the patching process. In order to address the warning that arose when I removed the no-warn directive, I added a case to removeUnreachableBlocksProc to handle the CmmData constructor. Clearly, since this partial function has not been erroring out in the wild, its inputs are always in practice wrapped by the CmmProc constructor. Therefore the CmmData case is handled by a precise panic (which is an improvement over the partial pattern match from before). - - - - - a2af7c4c by Nicolas Trangez at 2022-10-21T02:58:39-04:00 build: get rid of `HAVE_TIME_H` As advertized by `autoreconf`: > All current systems provide time.h; it need not be checked for. Hence, remove the check for it in `configure.ac` and remove conditional inclusion of the header in `HAVE_TIME_H` blocks where applicable. The `time.h` header was being included in various source files without a `HAVE_TIME_H` guard already anyway. - - - - - 25cdc630 by Nicolas Trangez at 2022-10-21T02:58:39-04:00 rts: remove use of `TIME_WITH_SYS_TIME` `autoreconf` will insert an `m4_warning` when the obsolescent `AC_HEADER_TIME` macro is used: > Update your code to rely only on HAVE_SYS_TIME_H, > then remove this warning and the obsolete code below it. > All current systems provide time.h; it need not be checked for. > Not all systems provide sys/time.h, but those that do, all allow > you to include it and time.h simultaneously. Presence of `sys/time.h` was already checked in an earlier `AC_CHECK_HEADERS` invocation, so `AC_HEADER_TIME` can be dropped and guards relying on `TIME_WITH_SYS_TIME` can be reworked to (unconditionally) include `time.h` and include `sys/time.h` based on `HAVE_SYS_TIME_H`. Note the documentation of `AC_HEADER_TIME` in (at least) Autoconf 2.67 says > This macro is obsolescent, as current systems can include both files > when they exist. New programs need not use this macro. - - - - - 1fe7921c by Eric Lindblad at 2022-10-21T02:59:21-04:00 runhaskell - - - - - e3b3986e by David Feuer at 2022-10-21T03:00:00-04:00 Document how to quote certain names with spaces Quoting a name for Template Haskell is a bit tricky if the second character of that name is a single quote. The User's Guide falsely claimed that it was impossible. Document how to do it. Fixes #22236 - - - - - 0eba81e8 by Krzysztof Gogolewski at 2022-10-21T03:00:00-04:00 Fix syntax - - - - - a4dbd102 by Ben Gamari at 2022-10-21T09:11:12-04:00 Fix manifest filename when writing Windows .rc files As noted in #12971, we previously used `show` which resulted in inappropriate escaping of non-ASCII characters. - - - - - 30f0d9a9 by Ben Gamari at 2022-10-21T09:11:12-04:00 Write response files in UTF-8 on Windows This reverts the workaround introduced in f63c8ef33ec9666688163abe4ccf2d6c0428a7e7, which taught our response file logic to write response files with the `latin1` encoding to workaround `gcc`'s lacking Unicode support. This is now no longer necessary (and in fact actively unhelpful) since we rather use Clang. - - - - - b8304648 by Matthew Farkas-Dyck at 2022-10-21T09:11:56-04:00 Scrub some partiality in `GHC.Core.Opt.Simplify.Utils`. - - - - - 09ec7de2 by Teo Camarasu at 2022-10-21T13:23:07-04:00 template-haskell: Improve documentation of strictness annotation types Before it was undocumentated that DecidedLazy can be returned by reifyConStrictness for strict fields. This can happen when a field has an unlifted type or its the single field of a newtype constructor. Fixes #21380 - - - - - 88172069 by M Farkas-Dyck at 2022-10-21T13:23:51-04:00 Delete `eqExpr`, since GHC 9.4 has been released. - - - - - 86e6549e by Ömer Sinan Ağacan at 2022-10-22T07:41:30-04:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const 0; // padding for indirectee const 0; // static link const 0; // saved info const hey1_r1Gg_bytes; // the payload } This is much smaller in code. Metric Decrease: T10421 T11195 T12150 T12425 T16577 T18282 T18698a T18698b Co-Authored By: Ben Gamari <ben at well-typed.com> - - - - - 1937016b by Andreas Klebinger at 2022-10-22T07:42:06-04:00 hadrian: Improve error for wrong key/value errors. - - - - - 11fe42d8 by Vladislav Zavialov at 2022-10-23T00:11:50+03:00 Class layout info (#19623) Updates the haddock submodule. - - - - - f0a90c11 by Sven Tennie at 2022-10-24T00:12:51-04:00 Pin used way for test cloneMyStack (#21977) cloneMyStack checks the order of closures on the cloned stack. This may change for different ways. Thus we limit this test to one way (normal). - - - - - 0614e74d by Aaron Allen at 2022-10-24T17:11:21+02:00 Convert Diagnostics in GHC.Tc.Gen.Splice (#20116) Replaces uses of `TcRnUnknownMessage` in `GHC.Tc.Gen.Splice` with structured diagnostics. closes #20116 - - - - - 8d2dbe2d by Andreas Klebinger at 2022-10-24T15:59:41-04:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 41406da5 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 5a997e16 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 7f203d00 by Sylvain Henry at 2022-10-25T18:07:43-04:00 Numeric exceptions: replace FFI calls with primops ghc-bignum needs a way to raise numerical exceptions defined in base package. At the time we used FFI calls into primops defined in the RTS. These FFI calls had to be wrapped into hacky bottoming functions because "foreign import prim" syntax doesn't support giving a bottoming demand to the foreign call (cf #16929). These hacky wrapper functions trip up the JavaScript backend (#21078) because they are polymorphic in their return type. This commit replaces them with primops very similar to raise# but raising predefined exceptions. - - - - - 0988a23d by Sylvain Henry at 2022-10-25T18:08:24-04:00 Enable popcount rewrite rule when cross-compiling The comment applies only when host's word size < target's word size. So we can relax the guard. - - - - - a2f53ac8 by Sylvain Henry at 2022-10-25T18:09:05-04:00 Add GHC.SysTools.Cpp module Move doCpp out of the driver to be able to use it in the upcoming JS backend. - - - - - 1fd7f201 by Ben Gamari at 2022-10-25T18:09:42-04:00 llvm-targets: Add datalayouts for big-endian AArch64 targets Fixes #22311. Thanks to @zeldin for the patch. - - - - - f5a486eb by Krzysztof Gogolewski at 2022-10-25T18:10:19-04:00 Cleanup String/FastString conversions Remove unused mkPtrString and isUnderscoreFS. We no longer use mkPtrString since 1d03d8bef96. Remove unnecessary conversions between FastString and String and back. - - - - - f7bfb40c by Ryan Scott at 2022-10-26T00:01:24-04:00 Broaden the in-scope sets for liftEnvSubst and composeTCvSubst This patch fixes two distinct (but closely related) buglets that were uncovered in #22235: * `liftEnvSubst` used an empty in-scope set, which was not wide enough to cover the variables in the range of the substitution. This patch fixes this by populating the in-scope set from the free variables in the range of the substitution. * `composeTCvSubst` applied the first substitution argument to the range of the second substitution argument, but the first substitution's in-scope set was not wide enough to cover the range of the second substutition. We similarly fix this issue in this patch by widening the first substitution's in-scope set before applying it. Fixes #22235. - - - - - 0270cc54 by Vladislav Zavialov at 2022-10-26T00:02:01-04:00 Introduce TcRnWithHsDocContext (#22346) Before this patch, GHC used withHsDocContext to attach an HsDocContext to an error message: addErr $ mkTcRnUnknownMessage $ mkPlainError noHints (withHsDocContext ctxt msg) The problem with this approach is that it only works with TcRnUnknownMessage. But could we attach an HsDocContext to a structured error message in a generic way? This patch solves the problem by introducing a new constructor to TcRnMessage: data TcRnMessage where ... TcRnWithHsDocContext :: !HsDocContext -> !TcRnMessage -> TcRnMessage ... - - - - - 9ab31f42 by Sylvain Henry at 2022-10-26T09:32:20+02:00 Testsuite: more precise test options Necessary for newer cross-compiling backends (JS, Wasm) that don't support TH yet. - - - - - f60a1a62 by Vladislav Zavialov at 2022-10-26T12:17:14-04:00 Use TcRnVDQInTermType in noNestedForallsContextsErr (#20115) When faced with VDQ in the type of a term, GHC generates the following error message: Illegal visible, dependent quantification in the type of a term (GHC does not yet support this) Prior to this patch, there were two ways this message could have been generated and represented: 1. with the dedicated constructor TcRnVDQInTermType (see check_type in GHC.Tc.Validity) 2. with the transitional constructor TcRnUnknownMessage (see noNestedForallsContextsErr in GHC.Rename.Utils) Not only this led to duplication of code generating the final SDoc, it also made it tricky to track the origin of the error message. This patch fixes the problem by using TcRnVDQInTermType exclusively. - - - - - 223e159d by Owen Shepherd at 2022-10-27T13:54:33-04:00 Remove source location information from interface files This change aims to minimize source location information leaking into interface files, which makes ABI hashes dependent on the build location. The `Binary (Located a)` instance has been removed completely. It seems that the HIE interface still needs the ability to serialize SrcSpans, but by wrapping the instances, it should be a lot more difficult to inadvertently add source location information. - - - - - 22e3deb9 by Simon Peyton Jones at 2022-10-27T13:55:37-04:00 Add missing dict binds to specialiser I had forgotten to add the auxiliary dict bindings to the /unfolding/ of a specialised function. This caused #22358, which reports failures when compiling Hackage packages fixed-vector indexed-traversable Regression test T22357 is snarfed from indexed-traversable - - - - - a8ed36f9 by Evan Relf at 2022-10-27T13:56:36-04:00 Fix broken link to `async` package - - - - - 750846cd by Zubin Duggal at 2022-10-28T00:49:22-04:00 Pass correct package db when testing stage1. It used to pick the db for stage-2 which obviously didn't work. - - - - - ad612f55 by Krzysztof Gogolewski at 2022-10-28T00:50:00-04:00 Minor SDoc-related cleanup * Rename pprCLabel to pprCLabelStyle, and use the name pprCLabel for a function using CStyle (analogous to pprAsmLabel) * Move LabelStyle to the CLabel module, it no longer needs to be in Outputable. * Move calls to 'text' right next to literals, to make sure the text/str rule is triggered. * Remove FastString/String roundtrip in Tc.Deriv.Generate * Introduce showSDocForUser', which abstracts over a pattern in GHCi.UI - - - - - c2872f3f by Bryan Richter at 2022-10-28T11:36:34+03:00 CI: Don't run lint-submods on nightly Fixes #22325 - - - - - 270037fa by Hécate Moonlight at 2022-10-28T19:46:12-04:00 Start the deprecation process for GHC.Pack - - - - - d45d8cb3 by M Farkas-Dyck at 2022-11-01T12:47:21-04:00 Drop a kludge for binutils<2.17, which is now over 10 years old. - - - - - 8ee8b418 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: `name` argument of `createOSThread` can be `const` Since we don't intend to ever change the incoming string, declare this to be true. Also, in the POSIX implementation, the argument is no longer `STG_UNUSED` (since ee0deb8054da2a597fc5624469b4c44fd769ada2) in any code path. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 - - - - - 13b5f102 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix lifetime of `start_thread`s `name` value Since, unlike the code in ee0deb8054da2^, usage of the `name` value passed to `createOSThread` now outlives said function's lifetime, and could hence be released by the caller by the time the new thread runs `start_thread`, it needs to be copied. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - edd175c9 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix OS thread naming in ticker Since ee0deb805, the use of `pthread_setname_np` on Darwin was fixed when invoking `createOSThread`. However, the 'ticker' has some thread-creation code which doesn't rely on `createOSThread`, yet also uses `pthread_setname_np`. This patch enforces all thread creation to go through a single function, which uses the (correct) thread-naming code introduced in ee0deb805. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22206 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - b7a00113 by Krzysztof Gogolewski at 2022-11-01T12:48:35-04:00 Typo: rename -fwrite-if-simplfied-core to -fwrite-if-simplified-core - - - - - 30e625e6 by Vladislav Zavialov at 2022-11-01T12:49:10-04:00 ThToHs: fix overzealous parenthesization Before this patch, when converting from TH.Exp to LHsExpr GhcPs, the compiler inserted more parentheses than required: ((f a) (b + c)) d This was happening because the LHS of the function application was parenthesized as if it was the RHS. Now we use funPrec and appPrec appropriately and produce sensibly parenthesized expressions: f a (b + c) d I also took the opportunity to remove the special case for LamE, which was not special at all and simply duplicated code. - - - - - 0560821f by Simon Peyton Jones at 2022-11-01T12:49:47-04:00 Add accurate skolem info when quantifying Ticket #22379 revealed that skolemiseQuantifiedTyVar was dropping the passed-in skol_info on the floor when it encountered a SkolemTv. Bad! Several TyCons thereby share a single SkolemInfo on their binders, which lead to bogus error reports. - - - - - 38d19668 by Fendor at 2022-11-01T12:50:25-04:00 Expose UnitEnvGraphKey for user-code - - - - - 77e24902 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Shrink test case for #22357 Ryan Scott offered a cut-down repro case (60 lines instead of more than 700 lines) - - - - - 4521f649 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Add two tests for #17366 - - - - - 6b400d26 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_NORETURN` Instead of sprinkling the codebase with `GNU(C3)_ATTRIBUTE(__noreturn__)`, add a `STG_NORETURN` macro (for, basically, the same thing) similar to `STG_UNUSED` and others, and update the code to use this macro where applicable. - - - - - f9638654 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: consistently use `STG_UNUSED` - - - - - 81a58433 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_USED` Similar to `STG_UNUSED`, have a specific macro for `__attribute__(used)`. - - - - - 41e1f748 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_MALLOC` Instead of using `GNUC3_ATTRIBUTE(__malloc__)`, provide a `STG_MALLOC` macro definition and use it instead. - - - - - 3a9a8bde by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `STG_UNUSED` - - - - - 9ab999de by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: specify deallocator of allocating functions This patch adds a new `STG_MALLOC1` macro (and its counterpart `STG_MALLOC2` for completeness) which allows to specify the deallocation function to be used with allocations of allocating functions, and applies it to `stg*allocBytes`. It also fixes a case where `free` was used to free up an `stgMallocBytes` allocation, found by the above change. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 81c0c7c9 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `alloc_size` attribute This patch adds the `STG_ALLOC_SIZE1` and `STG_ALLOC_SIZE2` macros which allow to set the `alloc_size` attribute on functions, when available. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 99a1d896 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: add and use `STG_RETURNS_NONNULL` See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - c235b399 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: tag `stgStrndup` as `STG_MALLOC` See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - ed81b448 by Oleg Grenrus at 2022-11-02T12:07:27-04:00 Move Symbol implementation note out of public haddock - - - - - 284fd39c by Ben Gamari at 2022-11-03T01:58:54-04:00 gen-dll: Drop it Currently it is only used by the make build system, which is soon to be retired, and it has not built since 41cf758b. We may need to reintroduce it when dynamic-linking support is introduced on Windows, but we will cross that bridge once we get there. Fixes #21753. - - - - - 24f4f54f by Matthew Pickering at 2022-11-03T01:59:30-04:00 Port foundation numeric tests to GHC testsuite This commit ports the numeric tests which found a regression in GHC-9.4. https://github.com/haskell-foundation/foundation/issues/571 Included in the commit is a simple random number generator and simplified QuickCheck implementation. In future these could be factored out of this standalone file and reused as a general purpose library which could be used for other QuickCheck style tests in the testsuite. See #22282 - - - - - d51bf7bd by M Farkas-Dyck at 2022-11-03T02:00:13-04:00 git: ignore HIE files. Cleans up git status if one sets -fwrite-ide-info in hadrian/ghci. - - - - - a9fc15b1 by Matthew Pickering at 2022-11-03T02:00:49-04:00 Clarify status of bindings in WholeCoreBindings Gergo points out that these bindings are tidied, rather than prepd as the variable claims. Therefore we update the name of the variable to reflect reality and add a comment to the data type to try to erase any future confusion. Fixes #22307 - - - - - 634da448 by Andrew Lelechenko at 2022-11-03T21:25:02+00:00 Fix haddocks for GHC.IORef - - - - - 31125154 by Andreas Klebinger at 2022-11-03T23:08:09-04:00 Export pprTrace and friends from GHC.Prelude. Introduces GHC.Prelude.Basic which can be used in modules which are a dependency of the ppr code. - - - - - bdc8cbb3 by Bryan Richter at 2022-11-04T10:27:37+02:00 CI: Allow hadrian-ghc-in-ghci to run in nightlies Since lint-submods doesn't run in nightlies, hadrian-ghc-in-ghci needs to mark it as "optional" so it can run if the job doesn't exist. Fixes #22396. - - - - - 3c0e3793 by Krzysztof Gogolewski at 2022-11-05T00:29:57-04:00 Minor refactor around FastStrings Pass FastStrings to functions directly, to make sure the rule for fsLit "literal" fires. Remove SDoc indirection in GHCi.UI.Tags and GHC.Unit.Module.Graph. - - - - - e41b2f55 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump unix submodule to 2.8.0.0 Also bumps process and ghc-boot bounds on unix. For hadrian, when cross-compiling, we add -Wwarn=unused-imports -Wwarn=unused-top-binds to validation flavour. Further fixes in unix and/or hsc2hs is needed to make it completely free of warnings; for the time being, this change is needed to unblock other cross-compilation related work. - - - - - 42938a58 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump Win32 submodule to 2.13.4.0 Fixes #22098 - - - - - e7372bc5 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump ci-images revision ci-images has recently been updated, including changes needed for wasm32-wasi CI. - - - - - 88cb9492 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump gmp-tarballs submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 69427ce9 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump haskeline submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 5fe11fe6 by Carter Schonwald at 2022-11-07T13:22:14-05:00 bump llvm upper bound - - - - - 68f49874 by M Farkas-Dyck at 2022-11-08T12:53:55-05:00 Define `Infinite` list and use where appropriate. Also add perf test for infinite list fusion. In particular, in `GHC.Core`, often we deal with infinite lists of roles. Also in a few locations we deal with infinite lists of names. Thanks to simonpj for helping to write the Note [Fusion for `Infinite` lists]. - - - - - ce726cd2 by Ross Paterson at 2022-11-08T12:54:34-05:00 Fix TypeData issues (fixes #22315 and #22332) There were two bugs here: 1. Treating type-level constructors as PromotedDataCon doesn't always work, in particular because constructors promoted via DataKinds are called both T and 'T. (Tests T22332a, T22332b, T22315a, T22315b) Fix: guard these cases with isDataKindsPromotedDataCon. 2. Type-level constructors were sent to the code generator, producing things like constructor wrappers. (Tests T22332a, T22332b) Fix: test for them in isDataTyCon. Other changes: * changed the marking of "type data" DataCon's as suggested by SPJ. * added a test TDGADT for a type-level GADT. * comment tweaks * change tcIfaceTyCon to ignore IfaceTyConInfo, so that IfaceTyConInfo is used only for pretty printing, not for typechecking. (SPJ) - - - - - 132f8908 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Clarify msum/asum documentation - - - - - bb5888c5 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Add example for (<$) - - - - - 080fffa1 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Document what Alternative/MonadPlus instances actually do - - - - - 92ccb8de by Giles Anderson at 2022-11-09T09:27:52-05:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Instance (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnWarnUnsatisfiedMinimalDefinition TcRnMisplacedInstSig TcRnBadBootFamInstDeclErr TcRnIllegalFamilyInstance TcRnAssocInClassErr TcRnBadFamInstDecl TcRnNotOpenFamily - - - - - 90c5abd4 by Hécate Moonlight at 2022-11-09T09:28:30-05:00 GHCi tags generation phase 2 see #19884 - - - - - f9f17b68 by Simon Peyton Jones at 2022-11-10T12:20:03+00:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. The reorganisation in the Simplifier improve compile times a bit (geom mean -0.1%), but T9961 is an outlier Metric Decrease: T9961 - - - - - 2b3d0bee by Simon Peyton Jones at 2022-11-10T12:21:13+00:00 Make indexError work better The problem here is described at some length in Note [Boxity for bottoming functions] and Note [Reboxed crud for bottoming calls] in GHC.Core.Opt.DmdAnal. This patch adds a SPECIALISE pragma for indexError, which makes it much less vulnerable to the problem described in these Notes. (This came up in another line of work, where a small change made indexError do reboxing (in nofib/spectral/simple/table_sort) that didn't happen before my change. I've opened #22404 to document the fagility. - - - - - 399e921b by Simon Peyton Jones at 2022-11-10T12:21:14+00:00 Fix DsUselessSpecialiseForClassMethodSelector msg The error message for DsUselessSpecialiseForClassMethodSelector was just wrong (a typo in some earlier work); trivial fix - - - - - dac0682a by Sebastian Graf at 2022-11-10T21:16:01-05:00 WorkWrap: Unboxing unboxed tuples is not always useful (#22388) See Note [Unboxing through unboxed tuples]. Fixes #22388. - - - - - 1230c268 by Sebastian Graf at 2022-11-10T21:16:01-05:00 Boxity: Handle argument budget of unboxed tuples correctly (#21737) Now Budget roughly tracks the combined width of all arguments after unarisation. See the changes to `Note [Worker argument budgets]`. Fixes #21737. - - - - - 2829fd92 by Cheng Shao at 2022-11-11T00:26:54-05:00 autoconf: check getpid getuid raise This patch adds checks for getpid, getuid and raise in autoconf. These functions are absent in wasm32-wasi and thus needs to be checked. - - - - - f5dfd1b4 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add -Wwarn only for cross-compiling unix - - - - - 2e6ab453 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add targetSupportsThreadedRts flag This patch adds a targetSupportsThreadedRts flag to indicate whether the target supports the threaded rts at all, different from existing targetSupportsSMP that checks whether -N is supported by the RTS. All existing flavours have also been updated accordingly to respect this flags. Some targets (e.g. wasm32-wasi) does not support the threaded rts, therefore this flag is needed for the default flavours to work. It makes more sense to have proper autoconf logic to check for threading support, but for the time being, we just set the flag to False iff the target is wasm32. - - - - - 8104f6f5 by Cheng Shao at 2022-11-11T00:26:55-05:00 Fix Cmm symbol kind - - - - - b2035823 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add the two key graph modules from Martin Erwig's FGL Martin Erwig's FGL (Functional Graph Library) provides an "inductive" representation of graphs. A general graph has labeled nodes and labeled edges. The key operation on a graph is to decompose it by removing one node, together with the edges that connect the node to the rest of the graph. There is also an inverse composition operation. The decomposition and composition operations make this representation of graphs exceptionally well suited to implement graph algorithms in which the graph is continually changing, as alluded to in #21259. This commit adds `GHC.Data.Graph.Inductive.Graph`, which defines the interface, and `GHC.Data.Graph.Inductive.PatriciaTree`, which provides an implementation. Both modules are taken from `fgl-5.7.0.3` on Hackage, with these changes: - Copyright and license text have been copied into the files themselves, not stored separately. - Some calls to `error` have been replaced with calls to `panic`. - Conditional-compilation support for older versions of GHC, `containers`, and `base` has been removed. - - - - - 3633a5f5 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add new modules for reducibility and WebAssembly translation - - - - - df7bfef8 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add support for the wasm32-wasi target tuple This patch adds the wasm32-wasi tuple support to various places in the tree: autoconf, hadrian, ghc-boot and also the compiler. The codegen logic will come in subsequent commits. - - - - - 32ae62e6 by Cheng Shao at 2022-11-11T00:26:55-05:00 deriveConstants: parse .ll output for wasm32 due to broken nm This patch makes deriveConstants emit and parse an .ll file when targeting wasm. It's a necessary workaround for broken llvm-nm on wasm, which isn't capable of reporting correct constant values when parsing an object. - - - - - 07e92c92 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: workaround cmm's improper variadic ccall breaking wasm32 typechecking Unlike other targets, wasm requires the function signature of the call site and callee to strictly match. So in Cmm, when we call a C function that actually returns a value, we need to add an _unused local variable to receive it, otherwise type error awaits. An even bigger problem is calling variadic functions like barf() and such. Cmm doesn't support CAPI calling convention yet, so calls to variadic functions just happen to work in some cases with some target's ABI. But again, it doesn't work with wasm. Fortunately, the wasm C ABI lowers varargs to a stack pointer argument, and it can be passed NULL when no other arguments are expected to be passed. So we also add the additional unused NULL arguments to those functions, so to fix wasm, while not affecting behavior on other targets. - - - - - 00124d12 by Cheng Shao at 2022-11-11T00:26:55-05:00 testsuite: correct sleep() signature in T5611 In libc, sleep() returns an integer. The ccall type signature should match the libc definition, otherwise it causes linker error on wasm. - - - - - d72466a9 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: prefer ffi_type_void over FFI_TYPE_VOID This patch uses ffi_type_void instead of FFI_TYPE_VOID in the interpreter code, since the FFI_TYPE_* macros are not available in libffi-wasm32 yet. The libffi public documentation also only mentions the lower-case ffi_type_* symbols, so we should prefer the lower-case API here. - - - - - 4d36a1d3 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't define RTS_USER_SIGNALS when signal.h is not present In the rts, we have a RTS_USER_SIGNALS macro, and most signal-related logic is guarded with RTS_USER_SIGNALS. This patch extends the range of code guarded with RTS_USER_SIGNALS, and define RTS_USER_SIGNALS iff signal.h is actually detected by autoconf. This is required for wasm32-wasi to work, which lacks signals. - - - - - 3f1e164f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: use HAVE_GETPID to guard subprocess related logic We've previously added detection of getpid() in autoconf. This patch uses HAVE_GETPID to guard some subprocess related logic in the RTS. This is required for certain targets like wasm32-wasi, where there isn't a process model at all. - - - - - 50bf5e77 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: IPE.c: don't do mutex stuff when THREADED_RTS is not defined This patch adds the missing THREADED_RTS CPP guard to mutex logic in IPE.c. - - - - - ed3b3da0 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: genericRaise: use exit() instead when not HAVE_RAISE We check existence of raise() in autoconf, and here, if not HAVE_RAISE, we should use exit() instead in genericRaise. - - - - - c0ba1547 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: checkSuid: don't do it when not HAVE_GETUID When getuid() is not present, don't do checkSuid since it doesn't make sense anyway on that target. - - - - - d2d6dfd2 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 placeholder linker This patch adds minimal placeholder linker logic for wasm32, just enough to unblock compiling rts on wasm32. RTS linker functionality is not properly implemented yet for wasm32. - - - - - 65ba3285 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: chdir to PWD on wasm32 This patch adds a wasm32-specific behavior to RtsStartup logic. When the PWD environment variable is present, we chdir() to it first. The point is to workaround an issue in wasi-libc: it's currently not possible to specify the initial working directory, it always defaults to / (in the virtual filesystem mapped from some host directory). For some use cases this is sufficient, but there are some other cases (e.g. in the testsuite) where the program needs to access files outside. - - - - - 65b82542 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: no timer for wasm32 Due to the lack of threads, on wasm32 there can't be a background timer that periodically resets the context switch flag. This patch disables timer for wasm32, and also makes the scheduler default to -C0 on wasm32 to avoid starving threads. - - - - - e007586f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsSymbols: empty RTS_POSIX_ONLY_SYMBOLS for wasm32 The default RTS_POSIX_ONLY_SYMBOLS doesn't make sense on wasm32. - - - - - 0e33f667 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: Schedule: no FORKPROCESS_PRIMOP_SUPPORTED on wasm32 On wasm32 there isn't a process model at all, so no FORKPROCESS_PRIMOP_SUPPORTED. - - - - - 88bbdb31 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: LibffiAdjustor: adapt to ffi_alloc_prep_closure interface for wasm32 libffi-wasm32 only supports non-standard libffi closure api via ffi_alloc_prep_closure(). This patch implements ffi_alloc_prep_closure() via standard libffi closure api on other targets, and uses it to implement adjustor functionality. - - - - - 15138746 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't return memory to OS on wasm32 This patch makes the storage manager not return any memory on wasm32. The detailed reason is described in Note [Megablock allocator on wasm]. - - - - - 631af3cc by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: make flushExec a no-op on wasm32 This patch makes flushExec a no-op on wasm32, since there's no such thing as executable memory on wasm32 in the first place. - - - - - 654a3d46 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: don't call resetTerminalSettings, freeThreadingResources on wasm32 This patch prevents resetTerminalSettings and freeThreadingResources to be called on wasm32, since there is no TTY or threading on wasm32 at all. - - - - - f271e7ca by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: OSThreads.h: stub types for wasm32 This patch defines stub Condition/Mutex/OSThreadId/ThreadLocalKey types for wasm32, just enough to unblock compiling RTS. Any threading-related functionality has been patched to be disabled on wasm32. - - - - - a6ac67b0 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add register mapping for wasm32 This patch adds register mapping logic for wasm32. See Note [Register mapping on WebAssembly] in wasm32 NCG for more description. - - - - - d7b33982 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 specific logic This patch adds the rest of wasm32 specific logic in rts. - - - - - 7f59b0f3 by Cheng Shao at 2022-11-11T00:26:55-05:00 base: fall back to using monotonic clock to emulate cputime on wasm32 On wasm32, we have to fall back to using monotonic clock to emulate cputime, since there's no native support for cputime as a clock id. - - - - - 5fcbae0b by Cheng Shao at 2022-11-11T00:26:55-05:00 base: more autoconf checks for wasm32 This patch adds more autoconf checks to base, since those functions and headers may exist on other POSIX systems but don't exist on wasm32. - - - - - 00a9359f by Cheng Shao at 2022-11-11T00:26:55-05:00 base: avoid using unsupported posix functionality on wasm32 This base patch avoids using unsupported posix functionality on wasm32. - - - - - 34b8f611 by Cheng Shao at 2022-11-11T00:26:55-05:00 autoconf: set CrossCompiling=YES in cross bindist configure This patch fixes the bindist autoconf logic to properly set CrossCompiling=YES when it's a cross GHC bindist. - - - - - 5ebeaa45 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: add util functions for UniqFM and UniqMap This patch adds addToUFM_L (backed by insertLookupWithKey), addToUniqMap_L and intersectUniqMap_C. These UniqFM/UniqMap util functions are used by the wasm32 NCG. - - - - - 177c56c1 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: avoid -Wl,--no-as-needed for wasm32 The driver used to pass -Wl,--no-as-needed for LLD linking. This is actually only supported for ELF targets, and must be avoided when linking for wasm32. - - - - - 06f01c74 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: allow big arith for wasm32 This patch enables Cmm big arithmetic on wasm32, since 64-bit arithmetic can be efficiently lowered to wasm32 opcodes. - - - - - df6bb112 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: pass -Wa,--no-type-check for wasm32 when runAsPhase This patch passes -Wa,--no-type-check for wasm32 when compiling assembly. See the added note for more detailed explanation. - - - - - c1fe4ab6 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: enforce cmm switch planning for wasm32 This patch forcibly enable Cmm switch planning for wasm32, since otherwise the switch tables we generate may exceed the br_table maximum allowed size. - - - - - a8adc71e by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: annotate CmmFileEmbed with blob length This patch adds the blob length field to CmmFileEmbed. The wasm32 NCG needs to know the precise size of each data segment. - - - - - 36340328 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: wasm32 NCG This patch adds the wasm32 NCG. - - - - - 435f42ea by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add wasm32-wasi release bindist job - - - - - d8262fdc by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add a stronger test for cross bindists This commit adds a simple GHC API program that parses and reprints the original hello world program used for basic testing of cross bindists. Before there's full cross-compilation support in the test suite driver, this provides better coverage than the original test. - - - - - 8e6ae882 by Cheng Shao at 2022-11-11T00:26:55-05:00 CODEOWNERS: add wasm-specific maintainers - - - - - 707d5651 by Zubin Duggal at 2022-11-11T00:27:31-05:00 Clarify that LLVM upper bound is non-inclusive during configure (#22411) - - - - - 430eccef by Ben Gamari at 2022-11-11T13:16:45-05:00 rts: Check for program_invocation_short_name via autoconf Instead of assuming support on all Linuxes. - - - - - 6dab0046 by Matthew Pickering at 2022-11-11T13:17:22-05:00 driver: Fix -fdefer-diagnostics flag The `withDeferredDiagnostics` wrapper wasn't doing anything because the session it was modifying wasn't used in hsc_env. Therefore the fix is simple, just push the `getSession` call into the scope of `withDeferredDiagnostics`. Fixes #22391 - - - - - d0c691b6 by Simon Peyton Jones at 2022-11-11T13:18:07-05:00 Add a fast path for data constructor workers See Note [Fast path for data constructors] in GHC.Core.Opt.Simplify.Iteration This bypasses lots of expensive logic, in the special case of applications of data constructors. It is a surprisingly worthwhile improvement, as you can see in the figures below. Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Read(normal) -2.0% CoOpt_Singletons(normal) -2.0% ManyConstructors(normal) -1.3% T10421(normal) -1.9% GOOD T10421a(normal) -1.5% T10858(normal) -1.6% T11545(normal) -1.7% T12234(optasm) -1.3% T12425(optasm) -1.9% GOOD T13035(normal) -1.0% GOOD T13056(optasm) -1.8% T13253(normal) -3.3% GOOD T15164(normal) -1.7% T15304(normal) -3.4% T15630(normal) -2.8% T16577(normal) -4.3% GOOD T17096(normal) -1.1% T17516(normal) -3.1% T18282(normal) -1.9% T18304(normal) -1.2% T18698a(normal) -1.2% GOOD T18698b(normal) -1.5% GOOD T18923(normal) -1.3% T1969(normal) -1.3% GOOD T19695(normal) -4.4% GOOD T21839c(normal) -2.7% GOOD T21839r(normal) -2.7% GOOD T4801(normal) -3.8% GOOD T5642(normal) -3.1% GOOD T6048(optasm) -2.5% GOOD T9020(optasm) -2.7% GOOD T9630(normal) -2.1% GOOD T9961(normal) -11.7% GOOD WWRec(normal) -1.0% geo. mean -1.1% minimum -11.7% maximum +0.1% Metric Decrease: T10421 T12425 T13035 T13253 T16577 T18698a T18698b T1969 T19695 T21839c T21839r T4801 T5642 T6048 T9020 T9630 T9961 - - - - - 3c37d30b by Krzysztof Gogolewski at 2022-11-11T19:18:39+01:00 Use a more efficient printer for code generation (#21853) The changes in `GHC.Utils.Outputable` are the bulk of the patch and drive the rest. The types `HLine` and `HDoc` in Outputable can be used instead of `SDoc` and support printing directly to a handle with `bPutHDoc`. See Note [SDoc versus HDoc] and Note [HLine versus HDoc]. The classes `IsLine` and `IsDoc` are used to make the existing code polymorphic over `HLine`/`HDoc` and `SDoc`. This is done for X86, PPC, AArch64, DWARF and dependencies (printing module names, labels etc.). Co-authored-by: Alexis King <lexi.lambda at gmail.com> Metric Decrease: CoOpt_Read ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13379 T18140 T18282 T18698a T18698b T1969 T20049 T21839c T21839r T3064 T3294 T4801 T5321FD T5321Fun T5631 T6048 T783 T9198 T9233 - - - - - 6b92b47f by Matthew Craven at 2022-11-11T18:32:14-05:00 Weaken wrinkle 1 of Note [Scrutinee Constant Folding] Fixes #22375. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 154c70f6 by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Fix fragile RULE setup in GHC.Float In testing my type-vs-constraint patch I found that the handling of Natural literals was very fragile -- and I somehow tripped that fragility in my work. So this patch fixes the fragility. See Note [realToFrac natural-to-float] This made a big (9%) difference in one existing test in perf/should_run/T1-359 Metric Decrease: T10359 - - - - - 778c6adc by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Type vs Constraint: finally nailed This big patch addresses the rats-nest of issues that have plagued us for years, about the relationship between Type and Constraint. See #11715/#21623. The main payload of the patch is: * To introduce CONSTRAINT :: RuntimeRep -> Type * To make TYPE and CONSTRAINT distinct throughout the compiler Two overview Notes in GHC.Builtin.Types.Prim * Note [TYPE and CONSTRAINT] * Note [Type and Constraint are not apart] This is the main complication. The specifics * New primitive types (GHC.Builtin.Types.Prim) - CONSTRAINT - ctArrowTyCon (=>) - tcArrowTyCon (-=>) - ccArrowTyCon (==>) - funTyCon FUN -- Not new See Note [Function type constructors and FunTy] and Note [TYPE and CONSTRAINT] * GHC.Builtin.Types: - New type Constraint = CONSTRAINT LiftedRep - I also stopped nonEmptyTyCon being built-in; it only needs to be wired-in * Exploit the fact that Type and Constraint are distinct throughout GHC - Get rid of tcView in favour of coreView. - Many tcXX functions become XX functions. e.g. tcGetCastedTyVar --> getCastedTyVar * Kill off Note [ForAllTy and typechecker equality], in (old) GHC.Tc.Solver.Canonical. It said that typechecker-equality should ignore the specified/inferred distinction when comparein two ForAllTys. But that wsa only weakly supported and (worse) implies that we need a separate typechecker equality, different from core equality. No no no. * GHC.Core.TyCon: kill off FunTyCon in data TyCon. There was no need for it, and anyway now we have four of them! * GHC.Core.TyCo.Rep: add two FunTyFlags to FunCo See Note [FunCo] in that module. * GHC.Core.Type. Lots and lots of changes driven by adding CONSTRAINT. The key new function is sORTKind_maybe; most other changes are built on top of that. See also `funTyConAppTy_maybe` and `tyConAppFun_maybe`. * Fix a longstanding bug in GHC.Core.Type.typeKind, and Core Lint, in kinding ForAllTys. See new tules (FORALL1) and (FORALL2) in GHC.Core.Type. (The bug was that before (forall (cv::t1 ~# t2). blah), where blah::TYPE IntRep, would get kind (TYPE IntRep), but it should be (TYPE LiftedRep). See Note [Kinding rules for types] in GHC.Core.Type. * GHC.Core.TyCo.Compare is a new module in which we do eqType and cmpType. Of course, no tcEqType any more. * GHC.Core.TyCo.FVs. I moved some free-var-like function into this module: tyConsOfType, visVarsOfType, and occCheckExpand. Refactoring only. * GHC.Builtin.Types. Compiletely re-engineer boxingDataCon_maybe to have one for each /RuntimeRep/, rather than one for each /Type/. This dramatically widens the range of types we can auto-box. See Note [Boxing constructors] in GHC.Builtin.Types The boxing types themselves are declared in library ghc-prim:GHC.Types. GHC.Core.Make. Re-engineer the treatment of "big" tuples (mkBigCoreVarTup etc) GHC.Core.Make, so that it auto-boxes unboxed values and (crucially) types of kind Constraint. That allows the desugaring for arrows to work; it gathers up free variables (including dictionaries) into tuples. See Note [Big tuples] in GHC.Core.Make. There is still work to do here: #22336. But things are better than before. * GHC.Core.Make. We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and aBSENT_CONSTRAINT_ERROR_ID for vaues of kind Constraint. Ditto noInlineId vs noInlieConstraintId in GHC.Types.Id.Make; see Note [inlineId magic]. * GHC.Core.TyCo.Rep. Completely refactor the NthCo coercion. It is now called SelCo, and its fields are much more descriptive than the single Int we used to have. A great improvement. See Note [SelCo] in GHC.Core.TyCo.Rep. * GHC.Core.RoughMap.roughMatchTyConName. Collapse TYPE and CONSTRAINT to a single TyCon, so that the rough-map does not distinguish them. * GHC.Core.DataCon - Mainly just improve documentation * Some significant renamings: GHC.Core.Multiplicity: Many --> ManyTy (easier to grep for) One --> OneTy GHC.Core.TyCo.Rep TyCoBinder --> GHC.Core.Var.PiTyBinder GHC.Core.Var TyCoVarBinder --> ForAllTyBinder AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag GHC.Core.TyCon TyConTyCoBinder --> TyConPiTyBinder Many functions are renamed in consequence e.g. isinvisibleArgFlag becomes isInvisibleForAllTyFlag, etc * I refactored FunTyFlag (was AnonArgFlag) into a simple, flat data type data FunTyFlag = FTF_T_T -- (->) Type -> Type | FTF_T_C -- (-=>) Type -> Constraint | FTF_C_T -- (=>) Constraint -> Type | FTF_C_C -- (==>) Constraint -> Constraint * GHC.Tc.Errors.Ppr. Some significant refactoring in the TypeEqMisMatch case of pprMismatchMsg. * I made the tyConUnique field of TyCon strict, because I saw code with lots of silly eval's. That revealed that GHC.Settings.Constants.mAX_SUM_SIZE can only be 63, because we pack the sum tag into a 6-bit field. (Lurking bug squashed.) Fixes * #21530 Updates haddock submodule slightly. Performance changes ~~~~~~~~~~~~~~~~~~~ I was worried that compile times would get worse, but after some careful profiling we are down to a geometric mean 0.1% increase in allocation (in perf/compiler). That seems fine. There is a big runtime improvement in T10359 Metric Decrease: LargeRecord MultiLayerModulesTH_OneShot T13386 T13719 Metric Increase: T8095 - - - - - 360f5fec by Simon Peyton Jones at 2022-11-11T23:40:11+00:00 Indent closing "#-}" to silence HLint - - - - - e160cf47 by Krzysztof Gogolewski at 2022-11-12T08:05:28-05:00 Fix merge conflict in T18355.stderr Fixes #22446 - - - - - 294f9073 by Simon Peyton Jones at 2022-11-12T23:14:13+00:00 Fix a trivial typo in dataConNonlinearType Fixes #22416 - - - - - 268a3ce9 by Ben Gamari at 2022-11-14T09:36:57-05:00 eventlog: Ensure that IPE output contains actual info table pointers The refactoring in 866c736e introduced a rather subtle change in the semantics of the IPE eventlog output, changing the eventlog field from encoding info table pointers to "TNTC pointers" (which point to entry code when tables-next-to-code is enabled). Fix this. Fixes #22452. - - - - - d91db679 by Matthew Pickering at 2022-11-14T16:48:10-05:00 testsuite: Add tests for T22347 These are fixed in recent versions but might as well add regression tests. See #22347 - - - - - 8f6c576b by Matthew Pickering at 2022-11-14T16:48:45-05:00 testsuite: Improve output from tests which have failing pre_cmd There are two changes: * If a pre_cmd fails, then don't attempt to run the test. * If a pre_cmd fails, then print the stdout and stderr from running that command (which hopefully has a nice error message). For example: ``` =====> 1 of 1 [0, 0, 0] *** framework failure for test-defaulting-plugin(normal) pre_cmd failed: 2 ** pre_cmd was "$MAKE -s --no-print-directory -C defaulting-plugin package.test-defaulting-plugin TOP={top}". stdout: stderr: DefaultLifted.hs:19:13: error: [GHC-76037] Not in scope: type constructor or class ‘Typ’ Suggested fix: Perhaps use one of these: ‘Type’ (imported from GHC.Tc.Utils.TcType), data constructor ‘Type’ (imported from GHC.Plugins) | 19 | instance Eq Typ where | ^^^ make: *** [Makefile:17: package.test-defaulting-plugin] Error 1 Performance Metrics (test environment: local): ``` Fixes #22329 - - - - - 2b7d5ccc by Madeline Haraj at 2022-11-14T22:44:17+00:00 Implement UNPACK support for sum types. This is based on osa's unpack_sums PR from ages past. The meat of the patch is implemented in dataConArgUnpackSum and described in Note [UNPACK for sum types]. - - - - - 78f7ecb0 by Andreas Klebinger at 2022-11-14T22:20:29-05:00 Expand on the need to clone local binders. Fixes #22402. - - - - - 65ce43cc by Krzysztof Gogolewski at 2022-11-14T22:21:05-05:00 Fix :i Constraint printing "type Constraint = Constraint" Since Constraint became a synonym for CONSTRAINT 'LiftedRep, we need the same code for handling printing as for the synonym Type = TYPE 'LiftedRep. This addresses the same bug as #18594, so I'm reusing the test. - - - - - 94549f8f by ARATA Mizuki at 2022-11-15T21:36:03-05:00 configure: Don't check for an unsupported version of LLVM The upper bound is not inclusive. Fixes #22449 - - - - - 02d3511b by Andrew Lelechenko at 2022-11-15T21:36:41-05:00 Fix capitalization in haddock for TestEquality - - - - - 08bf2881 by Cheng Shao at 2022-11-16T09:16:29+00:00 base: make Foreign.Marshal.Pool use RTS internal arena for allocation `Foreign.Marshal.Pool` used to call `malloc` once for each allocation request. Each `Pool` maintained a list of allocated pointers, and traverses the list to `free` each one of those pointers. The extra O(n) overhead is apparently bad for a `Pool` that serves a lot of small allocation requests. This patch uses the RTS internal arena to implement `Pool`, with these benefits: - Gets rid of the extra O(n) overhead. - The RTS arena is simply a bump allocator backed by the block allocator, each allocation request is likely faster than a libc `malloc` call. Closes #14762 #18338. - - - - - 37cfe3c0 by Krzysztof Gogolewski at 2022-11-16T14:50:06-05:00 Misc cleanup * Replace catMaybes . map f with mapMaybe f * Use concatFS to concatenate multiple FastStrings * Fix documentation of -exclude-module * Cleanup getIgnoreCount in GHCi.UI - - - - - b0ac3813 by Lawton Nichols at 2022-11-19T03:22:14-05:00 Give better errors for code corrupted by Unicode smart quotes (#21843) Previously, we emitted a generic and potentially confusing error during lexical analysis on programs containing smart quotes (“/”/‘/’). This commit adds smart quote-aware lexer errors. - - - - - cb8430f8 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make OpaqueNo* tests less noisy to unrelated changes - - - - - b1a8af69 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Simplifier: Consider `seq` as a `BoringCtxt` (#22317) See `Note [Seq is boring]` for the rationale. Fixes #22317. - - - - - 9fd11585 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make T21839c's ghc/max threshold more forgiving - - - - - 4b6251ab by Simon Peyton Jones at 2022-11-19T03:23:24-05:00 Be more careful when reporting unbound RULE binders See Note [Variables unbound on the LHS] in GHC.HsToCore.Binds. Fixes #22471. - - - - - e8f2b80d by Peter Trommler at 2022-11-19T03:23:59-05:00 PPC NCG: Fix generating assembler code Fixes #22479 - - - - - f2f9ef07 by Andrew Lelechenko at 2022-11-20T18:39:30-05:00 Extend documentation for Data.IORef - - - - - ef511b23 by Simon Peyton Jones at 2022-11-20T18:40:05-05:00 Buglet in GHC.Tc.Module.checkBootTyCon This lurking bug used the wrong function to compare two types in GHC.Tc.Module.checkBootTyCon It's hard to trigger the bug, which only came up during !9343, so there's no regression test in this MR. - - - - - 451aeac3 by Andrew Lelechenko at 2022-11-20T18:40:44-05:00 Add since pragmas for c_interruptible_open and hostIsThreaded - - - - - 8d6aaa49 by Duncan Coutts at 2022-11-22T02:06:16-05:00 Introduce CapIOManager as the per-cap I/O mangager state Rather than each I/O manager adding things into the Capability structure ad-hoc, we should have a common CapIOManager iomgr member of the Capability structure, with a common interface to initialise etc. The content of the CapIOManager struct will be defined differently for each I/O manager implementation. Eventually we should be able to have the CapIOManager be opaque to the rest of the RTS, and known just to the I/O manager implementation. We plan for that by making the Capability contain a pointer to the CapIOManager rather than containing the structure directly. Initially just move the Unix threaded I/O manager's control FD. - - - - - 8901285e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Add hook markCapabilityIOManager To allow I/O managers to have GC roots in the Capability, within the CapIOManager structure. Not yet used in this patch. - - - - - 5cf709c5 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move APPEND_TO_BLOCKED_QUEUE from cmm to C The I/O and delay blocking primitives for the non-threaded way currently access the blocked_queue and sleeping_queue directly. We want to move where those queues are to make their ownership clearer: to have them clearly belong to the I/O manager impls rather than to the scheduler. Ultimately we will want to change their representation too. It's inconvenient to do that if these queues are accessed directly from cmm code. So as a first step, replace the APPEND_TO_BLOCKED_QUEUE with a C version appendToIOBlockedQueue(), and replace the open-coded sleeping_queue insertion with insertIntoSleepingQueue(). - - - - - ced9acdb by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move {blocked,sleeping}_queue from scheduler global vars to CapIOManager The blocked_queue_{hd,tl} and the sleeping_queue are currently cooperatively managed between the scheduler and (some but not all of) the non-threaded I/O manager implementations. They lived as global vars with the scheduler, but are poked by I/O primops and the I/O manager backends. This patch is a step on the path towards making the management of I/O or timer blocking belong to the I/O managers and not the scheduler. Specifically, this patch moves the {blocked,sleeping}_queue from being global vars in the scheduler to being members of the CapIOManager struct within each Capability. They are not yet exclusively used by the I/O managers: they are still poked from a couple other places, notably in the scheduler before calling awaitEvent. - - - - - 0f68919e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Remove the now-unused markScheduler The global vars {blocked,sleeping}_queue are now in the Capability and so get marked there via markCapabilityIOManager. - - - - - 39a91f60 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move macros for checking for pending IO or timers from Schedule.h to Schedule.c and IOManager.h This is just moving, the next step will be to rejig them slightly. For the non-threaded RTS the scheduler needs to be able to test for there being pending I/O operation or pending timers. The implementation of these tests should really be considered to be part of the I/O managers and not part of the scheduler. - - - - - 664b034b by Duncan Coutts at 2022-11-22T02:06:17-05:00 Replace EMPTY_{BLOCKED,SLEEPING}_QUEUE macros by function These are the macros originaly from Scheduler.h, previously moved to IOManager.h, and now replaced with a single inline function anyPendingTimeoutsOrIO(). We can use a single function since the two macros were always checked together. Note that since anyPendingTimeoutsOrIO is defined for all IO manager cases, including threaded, we do not need to guard its use by cpp #if !defined(THREADED_RTS) - - - - - 32946220 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Expand emptyThreadQueues inline for clarity It was not really adding anything. The name no longer meant anything since those I/O and timeout queues do not belong to the scheuler. In one of the two places it was used, the comments already had to explain what it did, whereas now the code matches the comment nicely. - - - - - 9943baf9 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move the awaitEvent declaration into IOManager.h And add or adjust comments at the use sites of awaitEvent. - - - - - 054dcc9d by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to awaitEvent It is currently only used in the non-threaded RTS so it works to use MainCapability, but it's a bit nicer to pass the cap anyway. It's certainly shorter. - - - - - 667fe5a4 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to appendToIOBlockedQueue And to insertIntoSleepingQueue. Again, it's a bit cleaner and simpler though not strictly necessary given that these primops are currently only used in the non-threaded RTS. - - - - - 7181b074 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Reveiew feedback: improve one of the TODO comments The one about the nonsense (const False) test on WinIO for there being any IO or timers pending, leading to unnecessary complication later in the scheduler. - - - - - e5b68183 by Andreas Klebinger at 2022-11-22T02:06:52-05:00 Optimize getLevity. Avoid the intermediate data structures allocated by splitTyConApp. This avoids ~0.5% of allocations for a build using -O2. Fixes #22254 - - - - - de5fb348 by Andreas Klebinger at 2022-11-22T02:07:28-05:00 hadrian:Set TNTC when running testsuite. - - - - - 9d61c182 by Oleg Grenrus at 2022-11-22T15:59:34-05:00 Add unsafePtrEquality# restricted to UnliftedTypes - - - - - e817c871 by Jonathan Dowland at 2022-11-22T16:00:14-05:00 utils/unlit: adjust parser to match Report spec The Haskell 2010 Report says that, for Latex-style Literate format, "Program code begins on the first line following a line that begins \begin{code}". (This is unchanged from the 98 Report) However the unlit.c implementation only matches a line that contains "\begin{code}" and nothing else. One consequence of this is that one cannot suffix Latex options to the code environment. I.e., this does not work: \begin{code}[label=foo,caption=Foo Code] Adjust the matcher to conform to the specification from the Report. The Haskell Wiki currently recommends suffixing a '%' to \begin{code} in order to deliberately hide a code block from Haskell. This is bad advice, as it's relying on an implementation quirk rather than specified behaviour. None-the-less, some people have tried to use it, c.f. <https://mail.haskell.org/pipermail/haskell-cafe/2009-September/066780.html> An alternative solution is to define a separate, equivalent Latex environment to "code", that is functionally identical in Latex but ignored by unlit. This should not be a burden: users are required to manually define the code environment anyway, as it is not provided by the Latex verbatim or lstlistings packages usually used for presenting code in documents. Fixes #3549. - - - - - 0b7fef11 by Teo Camarasu at 2022-11-23T12:44:33-05:00 Fix eventlog all option Previously it didn't enable/disable nonmoving_gc and ticky event types Fixes #21813 - - - - - 04d0618c by Arnaud Spiwack at 2022-11-23T12:45:14-05:00 Expand Note [Linear types] with the stance on linting linearity Per the discussion on #22123 - - - - - e1538516 by Lawton Nichols at 2022-11-23T12:45:55-05:00 Add documentation on custom Prelude modules (#22228) Specifically, custom Prelude modules that are named `Prelude`. - - - - - b5c71454 by Sylvain Henry at 2022-11-23T12:46:35-05:00 Don't let configure perform trivial substitutions (#21846) Hadrian now performs substitutions, especially to generate .cabal files from .cabal.in files. Two benefits: 1. We won't have to re-configure when we modify thing.cabal.in. Hadrian will take care of this for us. 2. It paves the way to allow the same package to be configured differently by Hadrian in the same session. This will be useful to fix #19174: we want to build a stage2 cross-compiler for the host platform and a stage1 compiler for the cross target platform in the same Hadrian session. - - - - - 99aca26b by nineonine at 2022-11-23T12:47:11-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043) Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043 - - - - - 040bfdc3 by M Farkas-Dyck at 2022-11-23T21:59:03-05:00 Scrub some no-warning pragmas. - - - - - 178c1fd8 by Vladislav Zavialov at 2022-11-23T21:59:39-05:00 Check if the SDoc starts with a single quote (#22488) This patch fixes pretty-printing of character literals inside promoted lists and tuples. When we pretty-print a promoted list or tuple whose first element starts with a single quote, we want to add a space between the opening bracket and the element: '[True] -- ok '[ 'True] -- ok '['True] -- not ok If we don't add the space, we accidentally produce a character literal '['. Before this patch, pprSpaceIfPromotedTyCon inspected the type as an AST and tried to guess if it would be rendered with a single quote. However, it missed the case when the inner type was itself a character literal: '[ 'x'] -- ok '['x'] -- not ok Instead of adding this particular case, I opted for a more future-proof solution: check the SDoc directly. This way we can detect if the single quote is actually there instead of trying to predict it from the AST. The new function is called spaceIfSingleQuote. - - - - - 11627c42 by Matthew Pickering at 2022-11-23T22:00:15-05:00 notes: Fix references to HPT space leak note Updating this note was missed when updating the HPT to the HUG. Fixes #22477 - - - - - 86ff1523 by Andrei Borzenkov at 2022-11-24T17:24:51-05:00 Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115) Problem: avoid usage of TcRnMessageUnknown Solution: The following `TcRnMessage` messages has been introduced: TcRnNoRebindableSyntaxRecordDot TcRnNoFieldPunsRecordDot TcRnIllegalStaticExpression TcRnIllegalStaticFormInSplice TcRnListComprehensionDuplicateBinding TcRnEmptyStmtsGroup TcRnLastStmtNotExpr TcRnUnexpectedStatementInContext TcRnIllegalTupleSection TcRnIllegalImplicitParameterBindings TcRnSectionWithoutParentheses Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - d198a19a by Cheng Shao at 2022-11-24T17:25:29-05:00 rts: fix missing Arena.h symbols in RtsSymbols.c It was an unfortunate oversight in !8961 and broke devel2 builds. - - - - - 5943e739 by Andrew Lelechenko at 2022-11-25T04:38:28-05:00 Assorted fixes to avoid Data.List.{head,tail} - - - - - 1f1b99b8 by sheaf at 2022-11-25T04:38:28-05:00 Review suggestions for assorted fixes to avoid Data.List.{head,tail} - - - - - 13d627bb by Vladislav Zavialov at 2022-11-25T04:39:04-05:00 Print unticked promoted data constructors (#20531) Before this patch, GHC unconditionally printed ticks before promoted data constructors: ghci> type T = True -- unticked (user-written) ghci> :kind! T T :: Bool = 'True -- ticked (compiler output) After this patch, GHC prints ticks only when necessary: ghci> type F = False -- unticked (user-written) ghci> :kind! F F :: Bool = False -- unticked (compiler output) ghci> data False -- introduce ambiguity ghci> :kind! F F :: Bool = 'False -- ticked by necessity (compiler output) The old behavior can be enabled by -fprint-redundant-promotion-ticks. Summary of changes: * Rename PrintUnqualified to NamePprCtx * Add QueryPromotionTick to it * Consult the GlobalRdrEnv to decide whether to print a tick (see mkPromTick) * Introduce -fprint-redundant-promotion-ticks Co-authored-by: Artyom Kuznetsov <hi at wzrd.ht> - - - - - d10dc6bd by Simon Peyton Jones at 2022-11-25T22:31:27+00:00 Fix decomposition of TyConApps Ticket #22331 showed that we were being too eager to decompose a Wanted TyConApp, leading to incompleteness in the solver. To understand all this I ended up doing a substantial rewrite of the old Note [Decomposing equalities], now reborn as Note [Decomposing TyConApp equalities]. Plus rewrites of other related Notes. The actual fix is very minor and actually simplifies the code: in `can_decompose` in `GHC.Tc.Solver.Canonical.canTyConApp`, we now call `noMatchableIrreds`. A closely related refactor: we stop trying to use the same "no matchable givens" function here as in `matchClassInst`. Instead split into two much simpler functions. - - - - - 2da5c38a by Will Hawkins at 2022-11-26T04:05:04-05:00 Redirect output of musttail attribute test Compilation output from test for support of musttail attribute leaked to the console. - - - - - 0eb1c331 by Cheng Shao at 2022-11-28T08:55:53+00:00 Move hs_mulIntMayOflo cbits to ghc-prim It's only used by wasm NCG at the moment, but ghc-prim is a more reasonable place for hosting out-of-line primops. Also, we only need a single version of hs_mulIntMayOflo. - - - - - 36b53a9d by Cheng Shao at 2022-11-28T09:05:57+00:00 compiler: generate ccalls for clz/ctz/popcnt in wasm NCG We used to generate a single wasm clz/ctz/popcnt opcode, but it's wrong when it comes to subwords, so might as well generate ccalls for them. See #22470 for details. - - - - - d4134e92 by Cheng Shao at 2022-11-28T23:48:14-05:00 compiler: remove unused MO_U_MulMayOflo We actually only emit MO_S_MulMayOflo and never emit MO_U_MulMayOflo anywhere. - - - - - 8d15eadc by Apoorv Ingle at 2022-11-29T03:09:31-05:00 Killing cc_fundeps, streamlining kind equality orientation, and type equality processing order Fixes: #217093 Associated to #19415 This change * Flips the orientation of the the generated kind equality coercion in canEqLHSHetero; * Removes `cc_fundeps` in CDictCan as the check was incomplete; * Changes `canDecomposableTyConAppOk` to ensure we process kind equalities before type equalities and avoiding a call to `canEqLHSHetero` while processing wanted TyConApp equalities * Adds 2 new tests for validating the change - testsuites/typecheck/should_compile/T21703.hs and - testsuites/typecheck/should_fail/T19415b.hs (a simpler version of T19415.hs) * Misc: Due to the change in the equality direction some error messages now have flipped type mismatch errors * Changes in Notes: - Note [Fundeps with instances, and equality orientation] supercedes Note [Fundeps with instances] - Added Note [Kind Equality Orientation] to visualize the kind flipping - Added Note [Decomposing Dependent TyCons and Processing Wanted Equalties] - - - - - 646969d4 by Krzysztof Gogolewski at 2022-11-29T03:10:13-05:00 Change printing of sized literals to match the proposal Literals in Core were printed as e.g. 0xFF#16 :: Int16#. The proposal 451 now specifies syntax 0xFF#Int16. This change affects the Core printer only - more to be done later. Part of #21422. - - - - - 02e282ec by Simon Peyton Jones at 2022-11-29T03:10:48-05:00 Be a bit more selective about floating bottoming expressions This MR arranges to float a bottoming expression to the top only if it escapes a value lambda. See #22494 and Note [Floating to the top] in SetLevels. This has a generally beneficial effect in nofib +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || -0.93% | | imaginary/rfib || -0.05% | | real/fem || -0.03% | | real/fluid || -0.01% | | real/fulsom || +0.05% | | real/gamteb || -0.27% | | real/gg || -0.10% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/scs || -11.13% | | shootout/k-nucleotide || -0.01% | | shootout/n-body || -0.08% | | shootout/reverse-complement || -0.00% | | shootout/spectral-norm || -0.02% | | spectral/fibheaps || -0.20% | | spectral/hartel/fft || -1.04% | | spectral/hartel/solid || +0.33% | | spectral/hartel/wave4main || -0.35% | | spectral/mate || +0.76% | +===============================++==========+ | geom mean || -0.12% | The effect on compile time is generally slightly beneficial Metrics: compile_time/bytes allocated ---------------------------------------------- MultiLayerModulesTH_OneShot(normal) +0.3% PmSeriesG(normal) -0.2% PmSeriesT(normal) -0.1% T10421(normal) -0.1% T10421a(normal) -0.1% T10858(normal) -0.1% T11276(normal) -0.1% T11303b(normal) -0.2% T11545(normal) -0.1% T11822(normal) -0.1% T12150(optasm) -0.1% T12234(optasm) -0.3% T13035(normal) -0.2% T16190(normal) -0.1% T16875(normal) -0.4% T17836b(normal) -0.2% T17977(normal) -0.2% T17977b(normal) -0.2% T18140(normal) -0.1% T18282(normal) -0.1% T18304(normal) -0.2% T18698a(normal) -0.1% T18923(normal) -0.1% T20049(normal) -0.1% T21839r(normal) -0.1% T5837(normal) -0.4% T6048(optasm) +3.2% BAD T9198(normal) -0.2% T9630(normal) -0.1% TcPlugin_RewritePerf(normal) -0.4% hard_hole_fits(normal) -0.1% geo. mean -0.0% minimum -0.4% maximum +3.2% The T6048 outlier is hard to pin down, but it may be the effect of reading in more interface files definitions. It's a small program for which compile time is very short, so I'm not bothered about it. Metric Increase: T6048 - - - - - ab23dc5e by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Mark unpack_sums_6 as fragile due to #22504 This test is explicitly dependent upon runtime, which is generally not appropriate given that the testsuite is run in parallel and generally saturates the CPU. - - - - - def47dd3 by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Don't use grep -q in unpack_sums_7 `grep -q` closes stdin as soon as it finds the pattern it is looking for, resulting in #22484. - - - - - cc25d52e by Sylvain Henry at 2022-11-29T09:44:31+01:00 Add Javascript backend Add JS backend adapted from the GHCJS project by Luite Stegeman. Some features haven't been ported or implemented yet. Tests for these features have been disabled with an associated gitlab ticket. Bump array submodule Work funded by IOG. Co-authored-by: Jeffrey Young <jeffrey.young at iohk.io> Co-authored-by: Luite Stegeman <stegeman at gmail.com> Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 68c966cd by sheaf at 2022-11-30T09:31:25-05:00 Fix @since annotations on WithDict and Coercible Fixes #22453 - - - - - a3a8e9e9 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. - - - - - a9d9b8c0 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Use mkNakedFunTy in tcPatSynSig As #22521 showed, in tcPatSynSig we make a "fake type" to kind-generalise; and that type has unzonked type variables in it. So we must not use `mkFunTy` (which checks FunTy's invariants) via `mkPhiTy` when building this type. Instead we need to use `mkNakedFunTy`. Easy fix. - - - - - 31462d98 by Andreas Klebinger at 2022-11-30T14:50:58-05:00 Properly cast values when writing/reading unboxed sums. Unboxed sums might store a Int8# value as Int64#. This patch makes sure we keep track of the actual value type. See Note [Casting slot arguments] for the details. - - - - - 10a2a7de by Oleg Grenrus at 2022-11-30T14:51:39-05:00 Move Void to GHC.Base... This change would allow `Void` to be used deeper in module graph. For example exported from `Prelude` (though that might be already possible). Also this change includes a change `stimes @Void _ x = x`, https://github.com/haskell/core-libraries-committee/issues/95 While the above is not required, maintaining old stimes behavior would be tricky as `GHC.Base` doesn't know about `Num` or `Integral`, which would require more hs-boot files. - - - - - b4cfa8e2 by Sebastian Graf at 2022-11-30T14:52:24-05:00 DmdAnal: Reflect the `seq` of strict fields of a DataCon worker (#22475) See the updated `Note [Data-con worker strictness]` and the new `Note [Demand transformer for data constructors]`. Fixes #22475. - - - - - d87f28d8 by Baldur Blöndal at 2022-11-30T21:16:36+01:00 Make Functor a quantified superclass of Bifunctor. See https://github.com/haskell/core-libraries-committee/issues/91 for discussion. This change relates Bifunctor with Functor by requiring second = fmap. Moreover this change is a step towards unblocking the major version bump of bifunctors and profunctors to major version 6. This paves the way to move the Profunctor class into base. For that Functor first similarly becomes a superclass of Profunctor in the new major version 6. - - - - - 72cf4c5d by doyougnu at 2022-12-01T12:36:44-05:00 FastString: SAT bucket_match Metric Decrease: MultiLayerModulesTH_OneShot - - - - - afc2540d by Simon Peyton Jones at 2022-12-01T12:37:20-05:00 Add a missing varToCoreExpr in etaBodyForJoinPoint This subtle bug showed up when compiling a library with 9.4. See #22491. The bug is present in master, but it is hard to trigger; the new regression test T22491 fails in 9.4. The fix was easy: just add a missing varToCoreExpr in etaBodyForJoinPoint. The fix is definitely right though! I also did some other minor refatoring: * Moved the preInlineUnconditionally test in simplExprF1 to before the call to joinPointBinding_maybe, to avoid fruitless eta-expansion. * Added a boolean from_lam flag to simplNonRecE, to avoid two fruitless tests, and commented it a bit better. These refactorings seem to save 0.1% on compile-time allocation in perf/compiler; with a max saving of 1.4% in T9961 Metric Decrease: T9961 - - - - - 81eeec7f by M Farkas-Dyck at 2022-12-01T12:37:56-05:00 CI: Forbid the fully static build on Alpine to fail. To do so, we mark some tests broken in this configuration. - - - - - c5d1bf29 by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Remove ARMv7 jobs These jobs fail (and are allowed to fail) nearly every time. Soon they won't even be able to run at all, as we won't currently have runners that can run them. Fixing the latter problem is tracked in #22409. I went ahead and removed all settings and configurations. - - - - - d82992fd by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Fix CI lint Failure was introduced by conflicting changes to gen_ci.hs that did *not* trigger git conflicts. - - - - - ce126993 by Simon Peyton Jones at 2022-12-02T01:22:12-05:00 Refactor TyCon to have a top-level product This patch changes the representation of TyCon so that it has a top-level product type, with a field that gives the details (newtype, type family etc), #22458. Not much change in allocation, but execution seems to be a bit faster. Includes a change to the haddock submodule to adjust for API changes. - - - - - 74c767df by Matthew Pickering at 2022-12-02T01:22:48-05:00 ApplicativeDo: Set pattern location before running exhaustiveness checker This improves the error messages of the exhaustiveness checker when checking statements which have been moved around with ApplicativeDo. Before: Test.hs:2:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 2 | let x = () | ^^^^^^^^^^ After: Test.hs:4:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 4 | ~(Just res1) <- seq x (pure $ Nothing @()) | Fixes #22483 - - - - - 85ecc1a0 by Matthew Pickering at 2022-12-02T19:46:43-05:00 Add special case for :Main module in `GHC.IfaceToCore.mk_top_id` See Note [Root-main Id] The `:Main` special binding is actually defined in the current module (hence don't go looking for it externally) but the module name is rOOT_MAIN rather than the current module so we need this special case. There was already some similar logic in `GHC.Rename.Env` for External Core, but now the "External Core" is in interface files it needs to be moved here instead. Fixes #22405 - - - - - 108c319f by Krzysztof Gogolewski at 2022-12-02T19:47:18-05:00 Fix linearity checking in Lint Lint was not able to see that x*y <= x*y, because this inequality was decomposed to x <= x*y && y <= x*y, but there was no rule to see that x <= x*y. Fixes #22546. - - - - - bb674262 by Bryan Richter at 2022-12-03T04:38:46-05:00 Mark T16916 fragile See https://gitlab.haskell.org/ghc/ghc/-/issues/16966 - - - - - 5d267d46 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 Refactor: FreshOrReuse instead of addTyClTyVarBinds This is a refactoring that should have no effect on observable behavior. Prior to this change, GHC.HsToCore.Quote contained a few closely related functions to process type variable bindings: addSimpleTyVarBinds, addHsTyVarBinds, addQTyVarBinds, and addTyClTyVarBinds. We can classify them by their input type and name generation strategy: Fresh names only Reuse bound names +---------------------+-------------------+ [Name] | addSimpleTyVarBinds | | [LHsTyVarBndr flag GhcRn] | addHsTyVarBinds | | LHsQTyVars GhcRn | addQTyVarBinds | addTyClTyVarBinds | +---------------------+-------------------+ Note how two functions are missing. Because of this omission, there were two places where a LHsQTyVars value was constructed just to be able to pass it to addTyClTyVarBinds: 1. mk_qtvs in addHsOuterFamEqnTyVarBinds -- bad 2. mkHsQTvs in repFamilyDecl -- bad This prevented me from making other changes to LHsQTyVars, so the main goal of this refactoring is to get rid of those workarounds. The most direct solution would be to define the missing functions. But that would lead to a certain amount of code duplication. To avoid code duplication, I factored out the name generation strategy into a function parameter: data FreshOrReuse = FreshNamesOnly | ReuseBoundNames addSimpleTyVarBinds :: FreshOrReuse -> ... addHsTyVarBinds :: FreshOrReuse -> ... addQTyVarBinds :: FreshOrReuse -> ... - - - - - c189b831 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 addHsOuterFamEqnTyVarBinds: use FreshNamesOnly for explicit binders Consider this example: [d| instance forall a. C [a] where type forall b. G [a] b = Proxy b |] When we process "forall b." in the associated type instance, it is unambiguously the binding site for "b" and we want a fresh name for it. Therefore, FreshNamesOnly is more fitting than ReuseBoundNames. This should not have any observable effect but it avoids pointless lookups in the MetaEnv. - - - - - 42512264 by Ross Paterson at 2022-12-03T10:32:45+00:00 Handle type data declarations in Template Haskell quotations and splices (fixes #22500) This adds a TypeDataD constructor to the Template Haskell Dec type, and ensures that the constructors it contains go in the TyCls namespace. - - - - - 1a767fa3 by Vladislav Zavialov at 2022-12-05T05:18:50-05:00 Add BufSpan to EpaLocation (#22319, #22558) The key part of this patch is the change to mkTokenLocation: - mkTokenLocation (RealSrcSpan r _) = TokenLoc (EpaSpan r) + mkTokenLocation (RealSrcSpan r mb) = TokenLoc (EpaSpan r mb) mkTokenLocation used to discard the BufSpan, but now it is saved and can be retrieved from LHsToken or LHsUniToken. This is made possible by the following change to EpaLocation: - data EpaLocation = EpaSpan !RealSrcSpan + data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | ... The end goal is to make use of the BufSpan in Parser/PostProcess/Haddock. - - - - - cd31acad by sheaf at 2022-12-06T15:45:58-05:00 Hadrian: fix ghcDebugAssertions off-by-one error Commit 6b2f7ffe changed the logic that decided whether to enable debug assertions. However, it had an off-by-one error, as the stage parameter to the function inconsistently referred to the stage of the compiler being used to build or the stage of the compiler we are building. This patch makes it consistent. Now the parameter always refers to the the compiler which is being built. In particular, this patch re-enables assertions in the stage 2 compiler when building with devel2 flavour, and disables assertions in the stage 2 compiler when building with validate flavour. Some extra performance tests are now run in the "validate" jobs because the stage2 compiler no longer contains assertions. ------------------------- Metric Decrease: CoOpt_Singletons MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot T11374 T12227 T12234 T13253-spj T13701 T14683 T14697 T15703 T17096 T17516 T18304 T18478 T18923 T5030 T9872b TcPlugin_RewritePerf Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T13386 T13719 T3294 T9233 T9675 parsing001 ------------------------- - - - - - 21d66db1 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInstallNameTool - - - - - aaaaa79b by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of askOtool - - - - - 4e28f49e by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInjectRPaths - - - - - a7422580 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of Linker.MacOS - - - - - e902d771 by Matthew Craven at 2022-12-08T08:30:23-05:00 Fix bounds-checking buglet in Data.Array.Byte ...another manifestation of #20851 which I unfortunately missed in my first pass. - - - - - 8d36c0c6 by Gergő Érdi at 2022-12-08T08:31:03-05:00 Remove copy-pasted definitions of `graphFromEdgedVertices*` - - - - - c5d8ed3a by Gergő Érdi at 2022-12-08T08:31:03-05:00 Add version of `reachableGraph` that avoids loop for cyclic inputs by building its result connected component by component Fixes #22512 - - - - - 90cd5396 by Krzysztof Gogolewski at 2022-12-08T08:31:39-05:00 Mark Type.Reflection.Unsafe as Unsafe This module can be used to construct ill-formed TypeReps, so it should be Unsafe. - - - - - 2057c77d by Ian-Woo Kim at 2022-12-08T08:32:19-05:00 Truncate eventlog event for large payload (#20221) RTS eventlog events for postCapsetVecEvent are truncated if payload is larger than EVENT_PAYLOAD_SIZE_MAX Previously, postCapsetVecEvent records eventlog event with payload of variable size larger than EVENT_PAYLOAD_SIZE_MAX (2^16) without any validation, resulting in corrupted data. For example, this happens when a Haskell binary is invoked with very long command line arguments exceeding 2^16 bytes (see #20221). Now we check the size of accumulated payload messages incrementally, and truncate the message just before the payload size exceeds EVENT_PAYLOAD_SIZE_MAX. RTS will warn the user with a message showing how many arguments are truncated. - - - - - 9ec76f61 by Cheng Shao at 2022-12-08T08:32:59-05:00 hadrian: don't add debug info to non-debug ways of rts Hadrian used to pass -g when building all ways of rts. It makes output binaries larger (especially so for wasm backend), and isn't needed by most users out there, so this patch removes that flag. In case the debug info is desired, we still pass -g3 when building the debug way, and there's also the debug_info flavour transformer which ensures -g3 is passed for all rts ways. - - - - - 7658cdd4 by Krzysztof Gogolewski at 2022-12-08T08:33:36-05:00 Restore show (typeRep @[]) == "[]" The Show instance for TypeRep [] has changed in 9.5 to output "List" because the name of the type constructor changed. This seems to be accidental and is inconsistent with TypeReps of saturated lists, which are printed as e.g. "[Int]". For now, I'm restoring the old behavior; in the future, maybe we should show TypeReps without puns (List, Tuple, Type). - - - - - 216deefd by Matthew Pickering at 2022-12-08T22:45:27-05:00 Add test for #22162 - - - - - 5d0a311f by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job to test interface file determinism guarantees In this job we can run on every commit we add a test which builds the Cabal library twice and checks that the ABI hash and interface hash is stable across the two builds. * We run the test 20 times to try to weed out any race conditions due to `-j` * We run the builds in different temporary directories to try to weed out anything related to build directory affecting ABI or interface file hash. Fixes #22180 - - - - - 0a76d7d4 by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job for testing interface stability across builds The idea is that both the bindists should product libraries with the same ABI and interface hash. So the job checks with ghc-pkg to make sure the computed ABI is the same. In future this job can be extended to check for the other facets of interface determinism. Fixes #22180 - - - - - 74c9bf91 by Matthew Pickering at 2022-12-08T22:45:27-05:00 backpack: Be more careful when adding together ImportAvails There was some code in the signature merging logic which added together the ImportAvails of the signature and the signature which was merged into it. This had the side-effect of making the merged signature depend on the signature (via a normal module dependency). The intention was to propagate orphan instances through the merge but this also messed up recompilation logic because we shouldn't be attempting to load B.hi when mergeing it. The fix is to just combine the part of ImportAvails that we intended to (transitive info, orphan instances and type family instances) rather than the whole thing. - - - - - d122e022 by Matthew Pickering at 2022-12-08T22:45:27-05:00 Fix mk_mod_usage_info if the interface file is not already loaded In #22217 it was observed that the order modules are compiled in affects the contents of an interface file. This was because a module dependended on another module indirectly, via a re-export but the interface file for this module was never loaded because the symbol was never used in the file. If we decide that we depend on a module then we jolly well ought to record this fact in the interface file! Otherwise it could lead to very subtle recompilation bugs if the dependency is not tracked and the module is updated. Therefore the best thing to do is just to make sure the file is loaded by calling the `loadSysInterface` function. This first checks the caches (like we did before) but then actually goes to find the interface on disk if it wasn't loaded. Fixes #22217 - - - - - ea25088d by lrzlin at 2022-12-08T22:46:06-05:00 Add initial support for LoongArch Architecture. - - - - - 9eb9d2f4 by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Update submodule mtl to 2.3.1, parsec to 3.1.15.1, haddock and Cabal to HEAD - - - - - 08d8fe2a by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Allow mtl-2.3 in hadrian - - - - - 3807a46c by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Support mtl-2.3 in check-exact - - - - - ef702a18 by Andrew Lelechenko at 2022-12-08T22:46:47-05:00 Fix tests - - - - - 3144e8ff by Sebastian Graf at 2022-12-08T22:47:22-05:00 Make (^) INLINE (#22324) So that we get to cancel away the allocation for the lazily used base. We can move `powImpl` (which *is* strict in the base) to the top-level so that we don't duplicate too much code and move the SPECIALISATION pragmas onto `powImpl`. The net effect of this change is that `(^)` plays along much better with inlining thresholds and loopification (#22227), for example in `x2n1`. Fixes #22324. - - - - - 1d3a8b8e by Matthew Pickering at 2022-12-08T22:47:59-05:00 Typeable: Fix module locations of some definitions in GHC.Types There was some confusion in Data.Typeable about which module certain wired-in things were defined in. Just because something is wired-in doesn't mean it comes from GHC.Prim, in particular things like LiftedRep and RuntimeRep are defined in GHC.Types and that's the end of the story. Things like Int#, Float# etc are defined in GHC.Prim as they have no Haskell definition site at all so we need to generate type representations for them (which live in GHC.Types). Fixes #22510 - - - - - 0f7588b5 by Sebastian Graf at 2022-12-08T22:48:34-05:00 Make `drop` and `dropWhile` fuse (#18964) I copied the fusion framework we have in place for `take`. T18964 asserts that we regress neither when fusion fires nor when it doesn't. Fixes #18964. - - - - - 26e71562 by Sebastian Graf at 2022-12-08T22:49:10-05:00 Do not strictify a DFun's parameter dictionaries (#22549) ... thus fixing #22549. The details are in the refurbished and no longer dead `Note [Do not strictify a DFun's parameter dictionaries]`. There's a regression test in T22549. - - - - - 36093407 by John Ericson at 2022-12-08T22:49:45-05:00 Delete `rts/package.conf.in` It is a relic of the Make build system. The RTS now uses a `package.conf` file generated the usual way by Cabal. - - - - - b0cc2fcf by Krzysztof Gogolewski at 2022-12-08T22:50:21-05:00 Fixes around primitive literals * The SourceText of primitive characters 'a'# did not include the #, unlike for other primitive literals 1#, 1##, 1.0#, 1.0##, "a"#. We can now remove the function pp_st_suffix, which was a hack to add the # back. * Negative primitive literals shouldn't use parentheses, as described in Note [Printing of literals in Core]. Added a testcase to T14681. - - - - - aacf616d by Bryan Richter at 2022-12-08T22:50:56-05:00 testsuite: Mark conc024 fragile on Windows - - - - - ed239a24 by Ryan Scott at 2022-12-09T09:42:16-05:00 Document TH splices' interaction with INCOHERENT instances Top-level declaration splices can having surprising interactions with `INCOHERENT` instances, as observed in #22492. This patch resolves #22492 by documenting this strange interaction in the GHC User's Guide. [ci skip] - - - - - 1023b432 by Mike Pilgrem at 2022-12-09T09:42:56-05:00 Fix #22300 Document GHC's extensions to valid whitespace - - - - - 79b0cec0 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Add support for environments that don't have setImmediate - - - - - 5b007ec5 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Fix bound thread status - - - - - 65335d10 by Matthew Pickering at 2022-12-09T20:15:45-05:00 Update containers submodule This contains a fix necessary for the multi-repl to work on GHC's code base where we try to load containers and template-haskell into the same session. - - - - - 4937c0bb by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-multi: Put interface files in separate directories Before we were putting all the interface files in the same directory which was leading to collisions if the files were called the same thing. - - - - - 8acb5b7b by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-toolargs: Add filepath to allowed repl targets - - - - - 5949d927 by Matthew Pickering at 2022-12-09T20:15:45-05:00 driver: Set correct UnitId when rehydrating modules We were not setting the UnitId before rehydrating modules which just led to us attempting to find things in the wrong HPT. The test for this is the hadrian-multi command (which is now added as a CI job). Fixes #22222 - - - - - ab06c0f0 by Matthew Pickering at 2022-12-09T20:15:45-05:00 ci: Add job to test hadrian-multi command I am not sure this job is good because it requires booting HEAD with HEAD, but it should be fine. - - - - - fac3e568 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hadrian: Update bootstrap plans to 9.2.* series and 9.4.* series. This updates the build plans for the most recent compiler versions, as well as fixing the hadrian-bootstrap-gen script to a specific GHC version. - - - - - 195b08b4 by Matthew Pickering at 2022-12-09T20:16:20-05:00 ci: Bump boot images to use ghc-9.4.3 Also updates the bootstrap jobs to test booting 9.2 and 9.4. - - - - - c658c580 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hlint: Removed redundant UnboxedSums pragmas UnboxedSums is quite confusingly implied by UnboxedTuples, alas, just the way it is. See #22485 - - - - - b3e98a92 by Oleg Grenrus at 2022-12-11T12:26:17-05:00 Add heqT, a kind-heterogeneous variant of heq CLC proposal https://github.com/haskell/core-libraries-committee/issues/99 - - - - - bfd7c1e6 by Andrew Lelechenko at 2022-12-11T12:26:55-05:00 Document that Bifunctor instances for tuples are lawful only up to laziness - - - - - 5d1a1881 by Bryan Richter at 2022-12-12T16:22:36-05:00 Mark T21336a fragile - - - - - c30accc2 by Matthew Pickering at 2022-12-12T16:23:11-05:00 Add test for #21476 This issues seems to have been fixed since the ticket was made, so let's add a test and move on. Fixes #21476 - - - - - e9d74a3e by Sebastian Graf at 2022-12-13T22:18:39-05:00 Respect -XStrict in the pattern-match checker (#21761) We were missing a call to `decideBangHood` in the pattern-match checker. There is another call in `matchWrapper.mk_eqn_info` which seems redundant but really is not; see `Note [Desugaring -XStrict matches in Pmc]`. Fixes #21761. - - - - - 884790e2 by Gergő Érdi at 2022-12-13T22:19:14-05:00 Fix loop in the interface representation of some `Unfolding` fields As discovered in #22272, dehydration of the unfolding info of a recursive definition used to involve a traversal of the definition itself, which in turn involves traversing the unfolding info. Hence, a loop. Instead, we now store enough data in the interface that we can produce the unfolding info without this traversal. See Note [Tying the 'CoreUnfolding' knot] for details. Fixes #22272 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 9f301189 by Alan Zimmerman at 2022-12-13T22:19:50-05:00 EPA: When splitting out header comments, keep ones for first decl Any comments immediately preceding the first declaration are no longer kept as header comments, but attach to the first declaration instead. - - - - - 8b1f1b45 by Sylvain Henry at 2022-12-13T22:20:28-05:00 JS: fix object file name comparison (#22578) - - - - - e9e161bb by Bryan Richter at 2022-12-13T22:21:03-05:00 configure: Bump min bootstrap GHC version to 9.2 - - - - - 75855643 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Don't enable TSAN in stage0 build - - - - - da7b51d8 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce blockConcat - - - - - 34f6b09c by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce MemoryOrderings - - - - - 43beaa7b by Ben Gamari at 2022-12-15T03:54:02-05:00 llvm: Respect memory specified orderings - - - - - 8faf74fc by Ben Gamari at 2022-12-15T03:54:02-05:00 Codegen/x86: Eliminate barrier for relaxed accesses - - - - - 6cc3944a by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Reduce some repetition - - - - - 6c9862c4 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Add syntax for ordered loads and stores - - - - - 748490d2 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Atomic load syntax Originally I had thought I would just use the `prim` call syntax instead of introducing new syntax for atomic loads. However, it turns out that `prim` call syntax tends to make things quite unreadable. This new syntax seems quite natural. - - - - - 28c6781a by Ben Gamari at 2022-12-15T03:54:02-05:00 codeGen: Introduce ThreadSanitizer instrumentation This introduces a new Cmm pass which instruments the program with ThreadSanitizer annotations, allowing full tracking of mutator memory accesses via TSAN. - - - - - d97aa311 by Ben Gamari at 2022-12-15T03:54:02-05:00 Hadrian: Drop TSAN_ENABLED define from flavour This is redundant since the TSANUtils.h already defines it. - - - - - 86974ef1 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Enable Cmm instrumentation in TSAN flavour - - - - - 93723290 by Ben Gamari at 2022-12-15T03:54:02-05:00 rts: Ensure that global regs are never passed as fun call args This is in general unsafe as they may be clobbered if they are mapped to caller-saved machine registers. See Note [Register parameter passing]. - - - - - 2eb0fb87 by Matthew Pickering at 2022-12-15T03:54:39-05:00 Package Imports: Get candidate packages also from re-exported modules Previously we were just looking at the direct imports to try and work out what a package qualifier could apply to but #22333 pointed out we also needed to look for reexported modules. Fixes #22333 - - - - - 552b7908 by Ben Gamari at 2022-12-15T03:55:15-05:00 compiler: Ensure that MutVar operations have necessary barriers Here we add acquire and release barriers in readMutVar# and writeMutVar#, which are necessary for soundness. Fixes #22468. - - - - - 933d61a4 by Simon Peyton Jones at 2022-12-15T03:55:51-05:00 Fix bogus test in Lint The Lint check for branch compatiblity within an axiom, in GHC.Core.Lint.compatible_branches was subtly different to the check made when contructing an axiom, in GHC.Core.FamInstEnv.compatibleBranches. The latter is correct, so I killed the former and am now using the latter. On the way I did some improvements to pretty-printing and documentation. - - - - - 03ed0b95 by Ryan Scott at 2022-12-15T03:56:26-05:00 checkValidInst: Don't expand synonyms when splitting sigma types Previously, the `checkValidInst` function (used when checking that an instance declaration is headed by an actual type class, not a type synonym) was using `tcSplitSigmaTy` to split apart the `forall`s and instance context. This is incorrect, however, as `tcSplitSigmaTy` expands type synonyms, which can cause instances headed by quantified constraint type synonyms to be accepted erroneously. This patch introduces `splitInstTyForValidity`, a variant of `tcSplitSigmaTy` specialized for validity checking that does _not_ expand type synonyms, and uses it in `checkValidInst`. Fixes #22570. - - - - - ed056bc3 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/Messages: Refactor This doesn't change behavior but makes the code a bit easier to follow. - - - - - 7356f8e0 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/ThreadPaused: Ordering fixes - - - - - 914f0025 by Ben Gamari at 2022-12-16T16:12:44-05:00 eventlog: Silence spurious data race - - - - - fbc84244 by Ben Gamari at 2022-12-16T16:12:44-05:00 Introduce SET_INFO_RELEASE for Cmm - - - - - 821b5472 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Use fences instead of explicit barriers - - - - - 2228c999 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/stm: Fix memory ordering in readTVarIO# See #22421. - - - - - 99269b9f by Ben Gamari at 2022-12-16T16:12:44-05:00 Improve heap memory barrier Note Also introduce MUT_FIELD marker in Closures.h to document mutable fields. - - - - - 70999283 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. - - - - - 98689f77 by Ben Gamari at 2022-12-16T16:12:44-05:00 ghc: Fix data race in dump file handling Previously the dump filename cache would use a non-atomic update which could potentially result in lost dump contents. Note that this is still a bit racy since the first writer may lag behind a later appending writer. - - - - - 605d9547 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. - - - - - 86f20258 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. - - - - - f8e901dc by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. - - - - - e0affaa9 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate access to capabilities array - - - - - 7ca683e4 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate sched_state - - - - - 1cf13bd0 by Ben Gamari at 2022-12-16T16:12:45-05:00 PrimOps: Fix benign MutVar race Relaxed ordering is fine here since the later CAS implies a release. - - - - - 3d2a7e08 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Style fix - - - - - 82c62074 by Ben Gamari at 2022-12-16T16:12:45-05:00 compiler: Use release store in eager blackholing - - - - - eb1a0136 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Fix ordering of makeStableName - - - - - ad0e260a by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Use ordered accesses instead of explicit barriers - - - - - a3eccf06 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Statically allocate capabilities This is a rather simplistic way of solving #17289. - - - - - 287fa3fb by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Ensure that all accesses to pending_sync are atomic - - - - - 351eae58 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Note race with wakeBlockingQueue - - - - - 5acf33dd by Andrew Lelechenko at 2022-12-16T16:13:22-05:00 Bump submodule directory to 1.3.8.0 and hpc to HEAD - - - - - 0dd95421 by Andrew Lelechenko at 2022-12-16T16:13:22-05:00 Accept allocations increase on Windows This is because of `filepath-1.4.100.0` and AFPP, causing increasing round-trips between lists and ByteArray. See #22625 for discussion. Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T10547 T12150 T12227 T12234 T12425 T13035 T13253 T13253-spj T13701 T13719 T15703 T16875 T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T21839r T5837 T6048 T9198 T9961 TcPlugin_RewritePerf hard_hole_fits - - - - - ef9ac9d2 by Cheng Shao at 2022-12-16T16:13:59-05:00 testsuite: Mark T9405 as fragile instead of broken on Windows It's starting to pass again, and the unexpected pass blocks CI. - - - - - 1f3abd85 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: remove obsolete commented code in wasm NCG It was just a temporary hack to workaround a bug in the relooper, that bug has been fixed long before the wasm backend is merged. - - - - - e3104eab by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add missing export list of GHC.CmmToAsm.Wasm.FromCmm Also removes some unreachable code here. - - - - - 1c6930bf by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: change fallback function signature to Cmm function signature in wasm NCG In the wasm NCG, when handling a `CLabel` of undefined function without knowing its function signature, we used to fallback to `() -> ()` which is accepted by `wasm-ld`. This patch changes it to the signature of Cmm functions, which equally works, but would be required when we emit tail call instructions. - - - - - 8a81d9d9 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add optional tail-call support in wasm NCG When the `-mtail-call` clang flag is passed at configure time, wasm tail-call extension is enabled, and the wasm NCG will emit `return_call`/`return_call_indirect` instructions to take advantage of it and avoid the `StgRun` trampoline overhead. Closes #22461. - - - - - d1431cc0 by Cheng Shao at 2022-12-17T08:07:15-05:00 base: add missing autoconf checks for waitpid/umask These are not present in wasi-libc. Required for fixing #22589 - - - - - da3f1e91 by Cheng Shao at 2022-12-17T08:07:51-05:00 compiler: make .wasm the default executable extension on wasm32 Following convention as in other wasm toolchains. Fixes #22594. - - - - - ad21f4ef by Cheng Shao at 2022-12-17T08:07:51-05:00 ci: support hello.wasm in ci.sh cross testing logic - - - - - 6fe2d778 by amesgen at 2022-12-18T19:33:49-05:00 Correct `exitWith` Haddocks The `IOError`-specific `catch` in the Prelude is long gone. - - - - - b3eacd64 by Ben Gamari at 2022-12-18T19:34:24-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 761c1f49 by Ben Gamari at 2022-12-18T19:35:00-05:00 rts/libdw: Silence uninitialized usage warnings As noted in #22538, previously some GCC versions warned that various locals in Libdw.c may be used uninitialized. Although this wasn't strictly true (since they were initialized in an inline assembler block) we fix this by providing explicit empty initializers. Fixes #22538 - - - - - 5e047eff by Matthew Pickering at 2022-12-20T15:12:04+00:00 testsuite: Mark T16392 as fragile on windows See #22649 - - - - - 703a4665 by M Farkas-Dyck at 2022-12-20T21:14:46-05:00 Scrub some partiality in `GHC.Cmm.Info.Build`: `doSRTs` takes a `[(CAFSet, CmmDecl)]` but truly wants a `[(CAFSet, CmmStatics)]`. - - - - - 9736ab74 by Matthew Pickering at 2022-12-20T21:15:22-05:00 packaging: Fix upload_ghc_libs.py script This change reflects the changes where .cabal files are now generated by hadrian rather than ./configure. Fixes #22518 - - - - - 7c6de18d by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Drop uses of AC_PROG_CC_C99 As noted in #22566, this macro is deprecated as of autoconf-2.70 `AC_PROG_CC` now sets `ac_cv_prog_cc_c99` itself. Closes #22566. - - - - - 36c5d98e by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Use AS_HELP_STRING instead of AC_HELP_STRING The latter has been deprecated. See #22566. - - - - - befe6ff8 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 GHCi.UI: fix various usages of head and tail - - - - - 666d0ba7 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 GHCi.UI: avoid head and tail in parseCallEscape and around - - - - - 5d96fd50 by Andrew Lelechenko at 2022-12-20T21:16:37-05:00 Make GHC.Driver.Main.hscTcRnLookupRdrName to return NonEmpty - - - - - 3ce2ab94 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Allow transformers-0.6 in ghc, ghci, ghc-bin and hadrian - - - - - 954de93a by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Update submodule haskeline to HEAD (to allow transformers-0.6) - - - - - cefbeec3 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Update submodule transformers to 0.6.0.4 - - - - - b4730b62 by Andrew Lelechenko at 2022-12-21T06:17:56-05:00 Fix tests T13253 imports MonadTrans, which acquired a quantified constraint in transformers-0.6, thus increase in allocations Metric Increase: T13253 - - - - - 0be75261 by Simon Peyton Jones at 2022-12-21T06:18:32-05:00 Abstract over the right free vars Fix #22459, in two ways: (1) Make the Specialiser not create a bogus specialisation if it is presented by strangely polymorphic dictionary. See Note [Weird special case in SpecDict] in GHC.Core.Opt.Specialise (2) Be more careful in abstractFloats See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. So (2) stops creating the excessively polymorphic dictionary in abstractFloats, while (1) stops crashing if some other pass should nevertheless create a weirdly polymorphic dictionary. - - - - - df7bc6b3 by Ying-Ruei Liang (TheKK) at 2022-12-21T14:31:54-05:00 rts: explicitly store return value of ccall checkClosure to prevent type error (#22617) - - - - - e193e537 by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. - - - - - 3d55d8ab by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 - - - - - ceb2e9b9 by Ben Gamari at 2022-12-21T15:26:08-05:00 configure: Bump version to 9.6 - - - - - fb4d36c4 by Ben Gamari at 2022-12-21T15:27:49-05:00 base: Bump version to 4.18 Requires various submodule bumps. - - - - - 93ee7e90 by Ben Gamari at 2022-12-21T15:27:49-05:00 ghc-boot: Fix bootstrapping - - - - - fc3a2232 by Ben Gamari at 2022-12-22T13:45:06-05:00 Bump GHC version to 9.7 - - - - - 914f7fe3 by Andreas Klebinger at 2022-12-22T23:36:10-05:00 Don't consider large byte arrays/compact regions pinned. Workaround for #22255 which showed how treating large/compact regions as pinned could cause segfaults. - - - - - 32b32d7f by Matthew Pickering at 2022-12-22T23:36:46-05:00 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 - - - - - b3ddf803 by Ben Gamari at 2022-12-22T23:37:23-05:00 rts: Drop paths from configure from cabal file A long time ago we would rely on substitutions from the configure script to inject paths of the include and library directories of libffi and libdw. However, now these are instead handled inside Hadrian when calling Cabal's `configure` (see the uses of `cabalExtraDirs` in Hadrian's `Settings.Packages.packageArgs`). While the occurrences in the cabal file were redundant, they did no harm. However, since b5c714545abc5f75a1ffdcc39b4bfdc7cd5e64b4 they have no longer been interpolated. @mpickering noticed the suspicious uninterpolated occurrence of `@FFIIncludeDir@` in #22595, prompting this commit to finally remove them. - - - - - b2c7523d by Ben Gamari at 2022-12-22T23:37:59-05:00 Bump libffi-tarballs submodule We will now use libffi-3.4.4. - - - - - 3699a554 by Alan Zimmerman at 2022-12-22T23:38:35-05:00 EPA: Make EOF position part of AnnsModule Closes #20951 Closes #19697 - - - - - 99757ce8 by Sylvain Henry at 2022-12-22T23:39:13-05:00 JS: fix support for -outputdir (#22641) The `-outputdir` option wasn't correctly handled with the JS backend because the same code path was used to handle both objects produced by the JS backend and foreign .js files. Now we clearly distinguish the two in the pipeline, fixing the bug. - - - - - 02ed7d78 by Simon Peyton Jones at 2022-12-22T23:39:49-05:00 Refactor mkRuntimeError This patch fixes #22634. Because we don't have TYPE/CONSTRAINT polymorphism, we need two error functions rather than one. I took the opportunity to rname runtimeError to impossibleError, to line up with mkImpossibleExpr, and avoid confusion with the genuine runtime-error-constructing functions. - - - - - 35267f07 by Ben Gamari at 2022-12-22T23:40:32-05:00 base: Fix event manager shutdown race on non-Linux platforms During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this. - - - - - 317f45c1 by Simon Peyton Jones at 2022-12-22T23:41:07-05:00 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 - - - - - 14b2e3d3 by Ben Gamari at 2022-12-22T23:41:42-05:00 rts/m32: Fix sanity checking Previously we would attempt to clear pages which were marked as read-only. Fix this. - - - - - 16a1bcd1 by Matthew Pickering at 2022-12-23T09:15:24+00:00 ci: Move wasm pipelines into nightly rather than master See #22664 for the changes which need to be made to bring one of these back to the validate pipeline. - - - - - 18d2acd2 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. - - - - - 11241efa by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix segment list races - - - - - 602455c9 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. - - - - - 9d63b160 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. - - - - - 26837523 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that mutable fields have acquire barrier - - - - - 8093264a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. - - - - - 387d4fcc by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make segment state updates atomic - - - - - 543cae00 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. - - - - - c9936718 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. - - - - - 0cd31f7d by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. - - - - - d3fe110a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. - - - - - ab6cf893 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. - - - - - 36c9f23c by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). - - - - - aebef31c by doyougnu at 2022-12-23T19:10:09-05:00 add GHC.Utils.Binary.foldGet' and use for Iface A minor optimization to remove lazy IO and a lazy accumulator strictify foldGet' IFace.Binary: use strict foldGet' remove superfluous bang - - - - - 5eb357d9 by Ben Gamari at 2022-12-24T00:41:05-05:00 compiler: Ensure that GHC toolchain is first in search path As noted in #22561, it is important that GHC's toolchain look first for its own headers and libraries to ensure that the system's are not found instead. If this happens things can break in surprising ways (e.g. see #22561). - - - - - cbaebfb9 by Matthew Pickering at 2022-12-24T00:41:40-05:00 head.hackage: Use slow-validate bindist for linting jobs This enables the SLOW_VALIDATE env var for the linting head.hackage jobs, namely the jobs enabled manually, by the label or on the nightly build now use the deb10-numa-slow-validate bindist which has assertions enabled. See #22623 for a ticket which was found by using this configuration already! The head.hackage jobs triggered by upstream CI are now thusly: hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. Runs head.hackage with -dlint and a slow-validate bindist hackage-label-lint: Trigged on MRs with "user-facing" label, runs the slow-validate head.hackage build with -dlint. nightly-hackage-lint: Runs automatically on nightly pipelines with slow-validate + dlint config. nightly-hackage-perf: Runs automaticaly on nightly pipelines with release build and eventlogging enabled. release-hackage-lint: Runs automatically on release pipelines with -dlint on a release bindist. - - - - - f4850f36 by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Don't run abi-test-nightly on release jobs The test is not configured to get the correct dependencies for the release pipelines (and indeed stops the release pipeline being run at all) - - - - - c264b06b by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Run head.hackage jobs on upstream-testing branch rather than master This change allows less priviledged users to trigger head.hackage jobs because less permissions are needed to trigger jobs on the upstream-testing branch, which is not protected. There is a CI job which updates upstream-testing each hour to the state of the master branch so it should always be relatively up-to-date. - - - - - 63b97430 by Ben Gamari at 2022-12-24T00:42:16-05:00 llvmGen: Fix relaxed ordering Previously I used LLVM's `unordered` ordering for the C11 `relaxed` ordering. However, this is wrong and should rather use the LLVM `monotonic` ordering. Fixes #22640 - - - - - f42ba88f by Ben Gamari at 2022-12-24T00:42:16-05:00 gitlab-ci: Introduce aarch64-linux-llvm job This nightly job will ensure that we don't break the LLVM backend on AArch64/Linux by bootstrapping GHC. This would have caught #22640. - - - - - 6d62f6bf by Matthew Pickering at 2022-12-24T00:42:51-05:00 Store RdrName rather than OccName in Holes In #20472 it was pointed out that you couldn't defer out of scope but the implementation collapsed a RdrName into an OccName to stuff it into a Hole. This leads to the error message for a deferred qualified name dropping the qualification which affects the quality of the error message. This commit adds a bit more structure to a hole, so a hole can replace a RdrName without losing information about what that RdrName was. This is important when printing error messages. I also added a test which checks the Template Haskell deferral of out of scope qualified names works properly. Fixes #22130 - - - - - 3c3060e4 by Richard Eisenberg at 2022-12-24T17:34:19+00:00 Drop support for kind constraints. This implements proposal 547 and closes ticket #22298. See the proposal and ticket for motivation. Compiler perf improves a bit Metrics: compile_time/bytes allocated ------------------------------------- CoOpt_Singletons(normal) -2.4% GOOD T12545(normal) +1.0% T13035(normal) -13.5% GOOD T18478(normal) +0.9% T9872d(normal) -2.2% GOOD geo. mean -0.2% minimum -13.5% maximum +1.0% Metric Decrease: CoOpt_Singletons T13035 T9872d - - - - - 6d7d4393 by Ben Gamari at 2022-12-24T21:09:56-05:00 hadrian: Ensure that linker scripts are used when merging objects In #22527 @rui314 inadvertantly pointed out a glaring bug in Hadrian's implementation of the object merging rules: unlike the old `make` build system we utterly failed to pass the needed linker scripts. Fix this. - - - - - a5bd0eb8 by Andrew Lelechenko at 2022-12-24T21:10:34-05:00 Document infelicities of instance Ord Double and workarounds - - - - - 62b9a7b2 by Zubin Duggal at 2023-01-03T12:22:11+00:00 Force the Docs structure to prevent leaks in GHCi with -haddock without -fwrite-interface Involves adding many new NFData instances. Without forcing Docs, references to the TcGblEnv for each module are retained by the Docs structure. Usually these are forced when the ModIface is serialised but not when we aren't writing the interface. - - - - - 21bedd84 by Facundo Domínguez at 2023-01-03T23:27:30-05:00 Explain the auxiliary functions of permutations - - - - - 32255d05 by Matthew Pickering at 2023-01-04T11:58:42+00:00 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. - - - - - e640940c by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Fix computation of tables_next_to_code for outOfTreeCompiler This copy-pasto was introduced in de5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b - - - - - 15bee123 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 - - - - - fec6638e by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. - - - - - 3dc05726 by Matthew Pickering at 2023-01-04T11:58:42+00:00 check-exact: Fix build with -Werror - - - - - 53a6ae7a by Matthew Pickering at 2023-01-04T11:58:42+00:00 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 - - - - - 32e264c1 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 - - - - - be9dd9b0 by Matthew Pickering at 2023-01-04T11:58:42+00:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 - - - - - 00dc5106 by Matthew Pickering at 2023-01-04T14:32:45-05:00 sphinx: Use modern syntax for extlinks This fixes the following build error: ``` Command line: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build -b man -d /private/tmp/extra-dir-55768274273/.doctrees-man -n -w /private/tmp/extra-dir-55768274273/.log docs/users_guide /private/tmp/extra-dir-55768274273 ===> Command failed with error code: 2 Exception occurred: File "/opt/homebrew/Cellar/sphinx-doc/6.0.0/libexec/lib/python3.11/site-packages/sphinx/ext/extlinks.py", line 101, in role title = caption % part ~~~~~~~~^~~~~~ TypeError: not all arguments converted during string formatting ``` I tested on Sphinx-5.1.1 and Sphinx-6.0.0 Thanks for sterni for providing instructions about how to test using sphinx-6.0.0. Fixes #22690 - - - - - 541aedcd by Krzysztof Gogolewski at 2023-01-05T10:48:34-05:00 Misc cleanup - Remove unused uniques and hs-boot declarations - Fix types of seq and unsafeCoerce# - Remove FastString/String roundtrip in JS - Use TTG to enforce totality - Remove enumeration in Heap/Inspect; the 'otherwise' clause serves the primitive types well. - - - - - 22bb8998 by Alan Zimmerman at 2023-01-05T10:49:09-05:00 EPA: Do not collect comments from end of file In Parser.y semis1 production triggers for the virtual semi at the end of the file. This is detected by it being zero length. In this case, do not extend the span being used to gather comments, so any final comments are allocated at the module level instead. - - - - - 9e077999 by Vladislav Zavialov at 2023-01-05T23:01:55-05:00 HsToken in TypeArg (#19623) Updates the haddock submodule. - - - - - b2a2db04 by Matthew Pickering at 2023-01-05T23:02:30-05:00 Revert "configure: Drop uses of AC_PROG_CC_C99" This reverts commit 7c6de18dd3151ead954c210336728e8686c91de6. Centos7 using a very old version of the toolchain (autotools-2.69) where the behaviour of these macros has not yet changed. I am reverting this without haste as it is blocking the 9.6 branch. Fixes #22704 - - - - - 28f8c0eb by Luite Stegeman at 2023-01-06T18:16:24+09:00 Add support for sized literals in the bytecode interpreter. The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945 - - - - - ac39e8e9 by Matthew Pickering at 2023-01-06T13:47:00-05:00 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 - - - - - c306d939 by Matthew Pickering at 2023-01-06T22:08:53-05:00 ci: Upgrade darwin, windows and freebsd CI to use GHC-9.4.3 Fixes #22599 - - - - - 0db496ff by Matthew Pickering at 2023-01-06T22:08:53-05:00 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 2459c358 by Ben Gamari at 2023-01-06T22:09:29-05:00 rts: MUT_VAR is not a StgMutArrPtrs There was previously a comment claiming that the MUT_VAR closure type had the layout of StgMutArrPtrs. - - - - - 6206cb92 by Simon Peyton Jones at 2023-01-07T12:14:40-05:00 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 - - - - - a960ca81 by Matthew Pickering at 2023-01-07T12:15:15-05:00 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s - - - - - 73484710 by Matthew Pickering at 2023-01-07T12:15:15-05:00 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. - - - - - 8c0ea25f by Matthew Pickering at 2023-01-07T12:15:15-05:00 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes - - - - - 365b3045 by Matthew Pickering at 2023-01-09T02:36:20-05:00 Disable split sections on aarch64-deb10 build See #22722 Failure on this job: https://gitlab.haskell.org/ghc/ghc/-/jobs/1287852 ``` Unexpected failures: /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T10828.run T10828 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T13123.run T13123 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T20590.run T20590 [exit code non-0] (ext-interp) Appending 232 stats to file: /builds/ghc/ghc/performance-metrics.tsv ``` ``` Compile failed (exit code 1) errors were: data family D_0 a_1 :: * -> * data instance D_0 GHC.Types.Int GHC.Types.Bool :: * where DInt_2 :: D_0 GHC.Types.Int GHC.Types.Bool data E_3 where MkE_4 :: a_5 -> E_3 data Foo_6 a_7 b_8 where MkFoo_9, MkFoo'_10 :: a_11 -> Foo_6 a_11 b_12 newtype Bar_13 :: * -> GHC.Types.Bool -> * where MkBar_14 :: a_15 -> Bar_13 a_15 b_16 data T10828.T (a_0 :: *) where T10828.MkT :: forall (a_1 :: *) . a_1 -> a_1 -> T10828.T a_1 T10828.MkC :: forall (a_2 :: *) (b_3 :: *) . (GHC.Types.~) a_2 GHC.Types.Int => {T10828.foo :: a_2, T10828.bar :: b_3} -> T10828.T GHC.Types.Int T10828.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: (do TyConI dec <- runQ $ reify (mkName "T") runIO $ putStrLn (pprint dec) >> hFlush stdout d <- runQ $ [d| data T' a :: Type where MkT' :: a -> a -> T' a MkC' :: forall a b. (a ~ Int) => {foo :: a, bar :: b} -> T' Int |] runIO $ putStrLn (pprint d) >> hFlush stdout ....) *** unexpected failure for T10828(ext-interp) =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] Compile failed (exit code 1) errors were: T13123.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data GADT where MkGADT :: forall k proxy (a :: k). proxy a -> GADT |]) *** unexpected failure for T13123(ext-interp) =====> 7100 of 9215 [0, 2, 0] =====> 7100 of 9215 [0, 2, 0] =====> 7200 of 9215 [0, 2, 0] Compile failed (exit code 1) errors were: T20590.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data T where MkT :: forall a. a -> T |]) *** unexpected failure for T20590(ext-interp) ``` Looks fairly worrying to me. - - - - - 965a2735 by Alan Zimmerman at 2023-01-09T02:36:20-05:00 EPA: exact print HsDocTy To match ghc-exactprint https://github.com/alanz/ghc-exactprint/pull/121 - - - - - 5d65773e by John Ericson at 2023-01-09T20:39:27-05:00 Remove RTS hack for configuring See the brand new Note [Undefined symbols in the RTS] for additional details. - - - - - e3fff751 by Sebastian Graf at 2023-01-09T20:40:02-05:00 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite - - - - - d53f6f4d by Oleg Grenrus at 2023-01-09T21:11:02-05:00 Add safe list indexing operator: !? With Joachim's amendments. Implements https://github.com/haskell/core-libraries-committee/issues/110 - - - - - cfaf1ad7 by Nicolas Trangez at 2023-01-09T21:11:03-05:00 rts, tests: limit thread name length to 15 bytes On Linux, `pthread_setname_np` (or rather, the kernel) only allows for thread names up to 16 bytes, including the terminating null byte. This commit adds a note pointing this out in `createOSThread`, and fixes up two instances where a thread name of more than 15 characters long was used (in the RTS, and in a test-case). Fixes: #22366 Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/22366 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22366#note_460796 - - - - - 64286132 by Matthew Pickering at 2023-01-09T21:11:03-05:00 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 - - - - - 4724e8d1 by Matthew Pickering at 2023-01-09T21:11:04-05:00 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 - - - - - 2e926b88 by Georgi Lyubenov at 2023-01-09T21:11:07-05:00 Fix outdated link to Happy section on sequences - - - - - 146a1458 by Matthew Pickering at 2023-01-09T21:11:07-05:00 Revert "NCG(x86): Compile add+shift as lea if possible." This reverts commit 20457d775885d6c3df020d204da9a7acfb3c2e5a. See #22666 and #21777 - - - - - 6e6adbe3 by Jade Lovelace at 2023-01-11T00:55:30-05:00 Fix tcPluginRewrite example - - - - - faa57138 by Jade Lovelace at 2023-01-11T00:55:31-05:00 fix missing haddock pipe - - - - - 0470ea7c by Florian Weimer at 2023-01-11T00:56:10-05:00 m4/fp_leading_underscore.m4: Avoid implicit exit function declaration And switch to a new-style function definition. Fixes build issues with compilers that do not accept implicit function declarations. - - - - - b2857df4 by HaskellMouse at 2023-01-11T00:56:52-05:00 Added a new warning about compatibility with RequiredTypeArguments This commit introduces a new warning that indicates code incompatible with future extension: RequiredTypeArguments. Enabling this extension may break some code and the warning will help to make it compatible in advance. - - - - - 5f17e21a by Ben Gamari at 2023-01-11T00:57:27-05:00 testsuite: Drop testheapalloced.c As noted in #22414, this file (which appears to be a benchmark for characterising the one-step allocator's MBlock cache) is currently unreferenced. Remove it. Closes #22414. - - - - - bc125775 by Vladislav Zavialov at 2023-01-11T00:58:03-05:00 Introduce the TypeAbstractions language flag GHC Proposals #448 "Modern scoped type variables" and #425 "Invisible binders in type declarations" introduce a new language extension flag: TypeAbstractions. Part of the functionality guarded by this flag has already been implemented, namely type abstractions in constructor patterns, but it was guarded by a combination of TypeApplications and ScopedTypeVariables instead of a dedicated language extension flag. This patch does the following: * introduces a new language extension flag TypeAbstractions * requires TypeAbstractions for @a-syntax in constructor patterns instead of TypeApplications and ScopedTypeVariables * creates a User's Guide page for TypeAbstractions and moves the "Type Applications in Patterns" section there To avoid a breaking change, the new flag is implied by ScopedTypeVariables and is retroactively added to GHC2021. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 083f7015 by Krzysztof Gogolewski at 2023-01-11T00:58:38-05:00 Misc cleanup - Remove unused mkWildEvBinder - Use typeTypeOrConstraint - more symmetric and asserts that that the type is Type or Constraint - Fix escape sequences in Python; they raise a deprecation warning with -Wdefault - - - - - aed1974e by Richard Eisenberg at 2023-01-11T08:30:42+00:00 Refactor the treatment of loopy superclass dicts This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows. - - - - - 300bcc15 by HaskellMouse at 2023-01-11T13:43:36-05:00 Parse qualified terms in type signatures This commit allows qualified terms in type signatures to pass the parser and to be cathced by renamer with more informative error message. Adds a few tests. Fixes #21605 - - - - - 964284fc by Simon Peyton Jones at 2023-01-11T13:44:12-05:00 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. - - - - - f7ceafc9 by Krzysztof Gogolewski at 2023-01-11T22:36:59-05:00 Add 'docWithStyle' to improve codegen This new combinator docWithStyle :: IsOutput doc => doc -> (PprStyle -> SDoc) -> doc let us remove the need for code to be polymorphic in HDoc when not used in code style. Metric Decrease: ManyConstructors T13035 T1969 - - - - - b3be0d18 by Simon Peyton Jones at 2023-01-11T22:37:35-05:00 Fix finaliseArgBoxities for OPAQUE function We never do worker wrapper for OPAQUE functions, so we must zap the unboxing info during strictness analysis. This patch fixes #22502 - - - - - db11f358 by Ben Gamari at 2023-01-12T07:49:04-05:00 Revert "rts: Drop racy assertion" The logic here was inverted. Reverting the commit to avoid confusion when examining the commit history. This reverts commit b3eacd64fb36724ed6c5d2d24a81211a161abef1. - - - - - 3242139f by Ben Gamari at 2023-01-12T07:49:04-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 9ffd5d57 by Ben Gamari at 2023-01-12T07:49:41-05:00 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. - - - - - 905d0b6e by Sebastian Graf at 2023-01-12T15:51:47-05:00 Fix contification with stable unfoldings (#22428) Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with a `JoinArity` that reflects the number of join point binders around the body for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by `occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`. I adjusted `Note [Join points and unfoldings/rules]` and `Note [Adjusting right-hand sides]` to account for the new machinery. I also wrote a new `Note [Join arity prediction based on joinRhsArity]` and refer to it when we combine `TailUsageDetails` for a recursive RHS. I also renamed * `occAnalLam` to `occAnalLamTail` * `adjustRhsUsage` to `adjustTailUsage` * a few other less important functions and properly documented the that each call of `occAnalLamTail` must pair up with `adjustTailUsage`. I removed `Note [Unfoldings and join points]` because it was redundant with `Note [Occurrences in stable unfoldings]`. While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed `NodeDetails` called `SimpleNodeDetails`. Fixes #22428. The refactoring seems to have quite beneficial effect on ghc/alloc performance: ``` CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2% T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6% T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2% T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0% T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5% T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6% T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9% T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD geo. mean -0.6% minimum -2.4% maximum -0.0% ``` Metric Decrease: CoOpt_Read T10421 T12150 T12425 T13056 T18698a T18698b T21839c T21839r T9961 - - - - - a1491c87 by Andreas Klebinger at 2023-01-12T15:52:23-05:00 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. - - - - - 8acfe930 by Cheng Shao at 2023-01-12T15:53:00-05:00 Change MSYSTEM to CLANG64 uniformly - - - - - 73bc162b by M Farkas-Dyck at 2023-01-12T15:53:42-05:00 Make `GHC.Tc.Errors.Reporter` take `NonEmpty ErrorItem` rather than `[ErrorItem]`, which lets us drop some panics. Also use the `BasicMismatch` constructor rather than `mkBasicMismatchMsg`, which lets us drop the "-Wno-incomplete-record-updates" flag. - - - - - 1b812b69 by Oleg Grenrus at 2023-01-12T15:54:21-05:00 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general - - - - - c79b2b65 by Matthew Pickering at 2023-01-12T15:54:58-05:00 Don't run hadrian-multi on fast-ci label Fixes #22667 - - - - - 9a3d6add by Andrew Lelechenko at 2023-01-13T00:46:36-05:00 Bump submodule bytestring to 0.11.4.0 Metric Decrease: T21839c T21839r - - - - - df33c13c by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Bump Darwin bootstrap toolchain This updates the bootstrap compiler on Darwin from 8.10.7 to 9.2.5, ensuring that we have the fix for #21964. - - - - - 756a66ec by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Pass -w to cabal update Due to cabal#8447, cabal-install 3.8.1.0 requires a compiler to run `cabal update`. - - - - - 1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump hsc2hs submodule - - - - - d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump process submodule - - - - - 84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: Bump DOCKER_REV - - - - - d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: enable xz parallel compression for x64 jobs - - - - - d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: use in-image emsdk for js jobs - - - - - 93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings - Add a ghc environment including prebuilt dependencies to the nix-shell. Get rid of the ad hoc cabal cache and all dependencies are now downloaded from the nixos binary cache. - Make gen_ci.hs a cabal package with HLS integration, to make future hacking of gen_ci.hs easier. - Fix some ghc/hlint warnings after I got HLS to work. - For the lint-ci-config job, do a shallow clone to save a few minutes of unnecessary git checkout time. - - - - - 8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: source the toolchain env file in wasm jobs - - - - - 87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: add wasm ci jobs via gen_ci.hs - There is one regular wasm job run in validate pipelines - Additionally, int-native/unreg wasm jobs run in nightly/release pipelines Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml. - - - - - b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00 wasm ci: Remove wasm release jobs This removes the wasm release jobs, as we do not yet intend to distribute these binaries. - - - - - 496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. - - - - - 7a9a1042 by Andreas Klebinger at 2023-01-16T20:48:19-05:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 33b58f77 by sheaf at 2023-01-16T20:48:57-05:00 Hadrian: generalise &%> to avoid warnings This patch introduces a more general version of &%> that works with general traversable shapes, instead of lists. This allows us to pass along the information that the length of the list of filepaths passed to the function exactly matches the length of the input list of filepath patterns, avoiding pattern match warnings. Fixes #22430 - - - - - 8c7a991c by Andreas Klebinger at 2023-01-16T20:49:34-05:00 Add regression test for #22611. A case were a function used to fail to specialize, but now does. - - - - - 6abea760 by Andreas Klebinger at 2023-01-16T20:50:10-05:00 Mark maximumBy/minimumBy as INLINE. The RHS was too large to inline which often prevented the overhead of the Maybe from being optimized away. By marking it as INLINE we can eliminate the overhead of both the maybe and are able to unpack the accumulator when possible. Fixes #22609 - - - - - 99d151bb by Matthew Pickering at 2023-01-16T20:50:50-05:00 ci: Bump CACHE_REV so that ghc-9.6 branch and HEAD have different caches Having the same CACHE_REV on both branches leads to issues where the darwin toolchain is different on ghc-9.6 and HEAD which leads to long darwin build times. In general we should ensure that each branch has a different CACHE_REV. - - - - - 6a5845fb by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in source-tarball job This fixes errors of the form: ``` fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc inferred 9.7.20230113 checking for GHC Git commit id... fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc ``` - - - - - 4afb952c by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't build aarch64-deb10-llvm job on release pipelines Closes #22721 - - - - - 8039feb9 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in test-bootstrap job - - - - - 0b358d0c by Matthew Pickering at 2023-01-16T20:51:25-05:00 rel_eng: Add release engineering scripts into ghc tree It is better to keep these scripts in the tree as they depend on the CI configuration and so on. By keeping them in tree we can keep them up-to-date as the CI config changes and also makes it easier to backport changes to the release script between release branches in future. The final motivation is that it makes generating GHCUp metadata possible. - - - - - 28cb2ed0 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't use complicated image or clone in not-interruptible job This job exists only for the meta-reason of not allowing nightly pipelines to be cancelled. It was taking two minutes to run as in order to run "true" we would also clone the whole GHC repo. - - - - - eeea59bb by Matthew Pickering at 2023-01-16T20:51:26-05:00 Add scripts to generate ghcup metadata on nightly and release pipelines 1. A python script in .gitlab/rel_eng/mk-ghcup-metadata which generates suitable metadata for consumption by GHCUp for the relevant pipelines. - The script generates the metadata just as the ghcup maintainers want, without taking into account platform/library combinations. It is updated manually when the mapping changes. - The script downloads the bindists which ghcup wants to distribute, calculates the hash and generates the yaml in the correct structure. - The script is documented in the .gitlab/rel_eng/mk-ghcup-metadata/README.mk file 1a. The script requires us to understand the mapping from platform -> job. To choose the preferred bindist for each platform the .gitlab/gen_ci.hs script is modified to allow outputting a metadata file which answers the question about which job produces the bindist which we want to distribute to users for a specific platform. 2. Pipelines to run on nightly and release jobs to generate metadata - ghcup-metadata-nightly: Generates metadata which points directly to artifacts in the nightly job. - ghcup-metadata-release: Generates metadata suitable for inclusion directly in ghcup by pointing to the downloads folder where the bindist will be uploaded to. 2a. Trigger jobs which test the generated metadata in the downstream `ghccup-ci` repo. See that repo for documentation about what is tested and how but essentially we test in a variety of clean images that ghcup can download and install the bindists we say exist in our metadata. - - - - - 97bd4d8c by Andrew Lelechenko at 2023-01-16T20:52:04-05:00 Bump submodule parsec to 3.1.16.1 - - - - - 97ac8230 by Alan Zimmerman at 2023-01-16T20:52:39-05:00 EPA: Add annotation for 'type' in DataDecl Closes #22765 - - - - - dbbab95d by Ben Gamari at 2023-01-17T06:36:06-05:00 compiler: Small optimisation of assertM In #22739 @AndreasK noticed that assertM performed the action to compute the asserted predicate regardless of whether DEBUG is enabled. This is inconsistent with the other assertion operations and general convention. Fix this. Closes #22739. - - - - - fc02f3bb by Viktor Dukhovni at 2023-01-17T06:36:47-05:00 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 - - - - - 003b6d44 by Simon Peyton Jones at 2023-01-17T16:33:05-05:00 Document the semantics of pattern bindings a bit better This MR is in response to the discussion on #22719 - - - - - f4d50baf by Vladislav Zavialov at 2023-01-17T16:33:41-05:00 Hadrian: fix warnings (#22783) This change fixes the following warnings when building Hadrian: src/Hadrian/Expression.hs:38:10: warning: [-Wredundant-constraints] src/Hadrian/Expression.hs:84:13: warning: [-Wtype-equality-requires-operators] src/Hadrian/Expression.hs:84:21: warning: [-Wtype-equality-requires-operators] src/Hadrian/Haskell/Cabal/Parse.hs:67:1: warning: [-Wunused-imports] - - - - - 06036d93 by Sylvain Henry at 2023-01-18T01:55:10-05:00 testsuite: req_smp --> req_target_smp, req_ghc_smp See #22630 and !9552 This commit: - splits req_smp into req_target_smp and req_ghc_smp - changes the testsuite driver to calculate req_ghc_smp - changes a handful of tests to use req_target_smp instead of req_smp - changes a handful of tests to use req_host_smp when needed The problem: - the problem this solves is the ambiguity surrounding req_smp - on master req_smp was used to express the constraint that the program being compiled supports smp _and_ that the host RTS (i.e., the RTS used to compile the program) supported smp. Normally that is fine, but in cross compilation this is not always the case as was discovered in #22630. The solution: - Differentiate the two constraints: - use req_target_smp to say the RTS the compiled program is linked with (and the platform) supports smp - use req_host_smp to say the RTS the host is linked with supports smp WIP: fix req_smp (target vs ghc) add flag to separate bootstrapper split req_smp -> req_target_smp and req_ghc_smp update tests smp flags cleanup and add some docstrings only set ghc_with_smp to bootstrapper on S1 or CC Only set ghc_with_smp to bootstrapperWithSMP of when testing stage 1 and cross compiling test the RTS in config/ghc not hadrian re-add ghc_with_smp fix and align req names fix T11760 to use req_host_smp test the rts directly, avoid python 3.5 limitation test the compiler in a try block align out of tree and in tree withSMP flags mark failing tests as host req smp testsuite: req_host_smp --> req_ghc_smp Fix ghc vs host, fix ghc_with_smp leftover - - - - - ee9b78aa by Krzysztof Gogolewski at 2023-01-18T01:55:45-05:00 Use -Wdefault when running Python testdriver (#22727) - - - - - e9c0537c by Vladislav Zavialov at 2023-01-18T01:56:22-05:00 Enable -Wstar-is-type by default (#22759) Following the plan in GHC Proposal #143 "Remove the * kind syntax", which states: In the next release (or 3 years in), enable -fwarn-star-is-type by default. The "next release" happens to be 9.6.1 I also moved the T21583 test case from should_fail to should_compile, because the only reason it was failing was -Werror=compat in our test suite configuration. - - - - - 4efee43d by Ryan Scott at 2023-01-18T01:56:59-05:00 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. - - - - - f891a442 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. - - - - - b13c6ea5 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. - - - - - c45a5fff by Cheng Shao at 2023-01-18T07:28:37-05:00 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. - - - - - b4c14c4b by Luite Stegeman at 2023-01-18T14:21:42-05:00 Add PrimCallConv support to GHCi This adds support for calling Cmm code from bytecode using the native calling convention, allowing modules that use `foreign import prim` to be loaded and debugged in GHCi. This patch introduces a new `PRIMCALL` bytecode instruction and a helper stack frame `stg_primcall`. The code is based on the existing functionality for dealing with unboxed tuples in bytecode, which has been generalised to handle arbitrary calls. Fixes #22051 - - - - - d0a63ef8 by Adam Gundry at 2023-01-18T14:22:26-05:00 Refactor warning flag parsing to add missing flags This adds `-Werror=<group>` and `-fwarn-<group>` flags for warning groups as well as individual warnings. Previously these were defined on an ad hoc basis so for example we had `-Werror=compat` but not `-Werror=unused-binds`, whereas we had `-fwarn-unused-binds` but not `-fwarn-compat`. Fixes #22182. - - - - - 7ed1b8ef by Adam Gundry at 2023-01-18T14:22:26-05:00 Minor corrections to comments - - - - - 5389681e by Adam Gundry at 2023-01-18T14:22:26-05:00 Revise warnings documentation in user's guide - - - - - ab0d5cda by Adam Gundry at 2023-01-18T14:22:26-05:00 Move documentation of deferred type error flags out of warnings section - - - - - eb5a6b91 by John Ericson at 2023-01-18T22:24:10-05:00 Give the RTS it's own configure script Currently it doesn't do much anything, we are just trying to introduce it without breaking the build. Later, we will move functionality from the top-level configure script over to it. We need to bump Cabal for https://github.com/haskell/cabal/pull/8649; to facilitate and existing hack of skipping some configure checks for the RTS we now need to skip just *part* not *all* of the "post configure" hook, as running the configure script (which we definitely want to do) is also implemented as part of the "post configure" hook. But doing this requires exposing functionality that wasn't exposed before. - - - - - 32ab07bf by Andrew Lelechenko at 2023-01-18T22:24:51-05:00 ghc package does not have to depend on terminfo - - - - - 981ff7c4 by Andrew Lelechenko at 2023-01-18T22:24:51-05:00 ghc-pkg does not have to depend on terminfo - - - - - f058e367 by Ben Gamari at 2023-01-18T22:25:27-05:00 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. - - - - - 154889db by Ryan Scott at 2023-01-18T22:26:03-05:00 Add regression test for #22151 Issue #22151 was coincidentally fixed in commit aed1974e92366ab8e117734f308505684f70cddf (`Refactor the treatment of loopy superclass dicts`). This adds a regression test to ensure that the issue remains fixed. Fixes #22151. - - - - - 14b5982a by Andrei Borzenkov at 2023-01-18T22:26:43-05:00 Fix printing of promoted MkSolo datacon (#22785) Problem: In 2463df2f, the Solo data constructor was renamed to MkSolo, and Solo was turned into a pattern synonym for backwards compatibility. Since pattern synonyms can not be promoted, the old code that pretty-printed promoted single-element tuples started producing ill-typed code: t :: Proxy ('Solo Int) This fails with "Pattern synonym ‘Solo’ used as a type" The solution is to track the distinction between type constructors and data constructors more carefully when printing single-element tuples. - - - - - 1fe806d3 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add hi_core flavour transformer The hi_core flavour transformer enables -fwrite-if-simplified-core for stage1 libraries, which emit core into interface files to make it possible to restart code generation. Building boot libs with it makes it easier to use GHC API to prototype experimental backends that needs core/stg at link time. - - - - - 317cad26 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add missing docs for recently added flavour transformers - - - - - 658f4446 by Ben Gamari at 2023-01-23T04:49:23-05:00 gitlab-ci: Add Rocky8 jobs Addresses #22268. - - - - - a83ec778 by Vladislav Zavialov at 2023-01-23T04:49:58-05:00 Set "since: 9.8" for TypeAbstractions and -Wterm-variable-capture These flags did not make it into the 9.6 release series, so the "since" annotations must be corrected. - - - - - fec7c2ea by Alan Zimmerman at 2023-01-23T04:50:33-05:00 EPA: Add SourceText to HsOverLabel To be able to capture string literals with possible escape codes as labels. Close #22771 - - - - - 3efd1e99 by Ben Gamari at 2023-01-23T04:51:08-05:00 template-haskell: Bump version to 2.20.0.0 Updates `text` and `exceptions` submodules for bounds bumps. Addresses #22767. - - - - - 0900b584 by Cheng Shao at 2023-01-23T04:51:45-05:00 hadrian: disable alloca for in-tree GMP on wasm32 When building in-tree GMP for wasm32, disable its alloca usage, since it may potentially cause stack overflow (e.g. #22602). - - - - - db0f1bfd by Cheng Shao at 2023-01-23T04:52:21-05:00 Bump process submodule Includes a critical fix for wasm32, see https://github.com/haskell/process/pull/272 for details. Also changes the existing cross test to include process stuff and avoid future regression here. - - - - - 9222b167 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Fix subdir for windows bindist - - - - - 9a9bec57 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Remove viPostRemove field from generated metadata This has been removed from the downstream metadata. - - - - - 82884ce0 by Simon Peyton Jones at 2023-01-23T04:53:32-05:00 Fix #22742 runtimeRepLevity_maybe was panicing unnecessarily; and the error printing code made use of the case when it should return Nothing rather than panicing. For some bizarre reason perf/compiler/T21839r shows a 10% bump in runtime peak-megagbytes-used, on a single architecture (alpine). See !9753 for commentary, but I'm going to accept it. Metric Increase: T21839r - - - - - 2c6deb18 by Bryan Richter at 2023-01-23T14:12:22+02:00 codeowners: Add Ben, Matt, and Bryan to CI - - - - - eee3bf05 by Matthew Craven at 2023-01-23T21:46:41-05:00 Do not collect compile-time metrics for T21839r ...the testsuite doesn't handle this properly since it also collects run-time metrics. Compile-time metrics for this test are already tracked via T21839c. Metric Decrease: T21839r - - - - - 1d1dd3fb by Matthew Pickering at 2023-01-24T05:37:52-05:00 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 - - - - - 7bfb30f9 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 - - - - - 69500dd4 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 - - - - - 336b2b1c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 - - - - - 6469fea7 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 - - - - - 06cc0a95 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 - - - - - 4fe9eaff by Matthew Pickering at 2023-01-24T05:37:52-05:00 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 - - - - - ada29f5c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p - - - - - be701cc6 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. - - - - - 34d2d463 by Krzysztof Gogolewski at 2023-01-24T05:38:32-05:00 Fix Lint check for duplicate external names Lint was checking for duplicate external names by calling removeDups, which needs a comparison function that is passed to Data.List.sortBy. But the comparison was not a valid ordering - it returned LT if one of the names was not external. For example, the previous implementation won't find a duplicate in [M.x, y, M.x]. Instead, we filter out non-external names before looking for duplicates. - - - - - 1c050ed2 by Matthew Pickering at 2023-01-24T05:39:08-05:00 Add test for T22671 This was fixed by b13c6ea5 Closes #22671 - - - - - 05e6a2d9 by Tom Ellis at 2023-01-24T12:10:52-05:00 Clarify where `f` is defined - - - - - d151546e by Cheng Shao at 2023-01-24T12:11:29-05:00 CmmToC: fix CmmRegOff for 64-bit register on a 32-bit target We used to print the offset value to a platform word sized integer. This is incorrect when the offset is negative (e.g. output of cmm constant folding) and the register is 64-bit but on a 32-bit target, and may lead to incorrect runtime result (e.g. #22607). The fix is simple: just treat it as a proper MO_Add, with the correct width info inferred from the register itself. Metric Increase: T12707 T13379 T4801 T5321FD T5321Fun - - - - - e5383a29 by Wander Hillen at 2023-01-24T20:02:26-05:00 Allow waiting for timerfd to be interrupted during rts shutdown - - - - - 1957eda1 by Ryan Scott at 2023-01-24T20:03:01-05:00 Restore Compose's Read/Show behavior to match Read1/Show1 instances Fixes #22816. - - - - - 30972827 by Matthew Pickering at 2023-01-25T03:54:14-05:00 docs: Update INSTALL.md Removes references to make. Fixes #22480 - - - - - bc038c3b by Cheng Shao at 2023-01-25T03:54:50-05:00 compiler: fix handling of MO_F_Neg in wasm NCG In the wasm NCG, we used to compile MO_F_Neg to 0.0-x. It was an oversight, there actually exists f32.neg/f64.neg opcodes in the wasm spec and those should be used instead! The old behavior almost works, expect when GHC compiles the -0.0 literal, which will incorrectly become 0.0. - - - - - e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. - - - - - 48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. - - - - - 288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. - - - - - 2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00 configure: support "windows" as an OS - - - - - 13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00 Fix in-scope set in specImports Nothing deep here; I had failed to bring some floated dictionary binders into scope. Exposed by -fspecialise-aggressively Fixes #22715. - - - - - b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00 ci: Disable HLint job due to excessive runtime The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91 Now the CI job will build the stage0 compiler before it generates the necessary RTS headers. We either need to: * Fix the linting rules so they take much less time * Revert the commit * Remove the linting of base from the hlint job * Remove the hlint job This is highest priority as it is affecting all CI pipelines. For now I am just disabling the job because there are many more pressing matters at hand. Ticket #22830 - - - - - 1bd32a35 by Sylvain Henry at 2023-01-26T12:34:21-05:00 Factorize hptModulesBelow Create and use moduleGraphModulesBelow in GHC.Unit.Module.Graph that doesn't need anything from the driver to be used. - - - - - 1262d3f8 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 - - - - - e27eb80c by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 - - - - - 3d004d5a by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 - - - - - f2a0fea0 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 - - - - - 5640cb1d by Sylvain Henry at 2023-01-26T12:35:36-05:00 Hadrian: fix doc generation Was missing dependencies on files generated by templates (e.g. ghc.cabal) - - - - - 3e827c3f by Richard Eisenberg at 2023-01-26T20:06:53-05:00 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. Close #22519. - - - - - b3ef5c89 by doyougnu at 2023-01-26T20:07:48-05:00 tryFillBuffer: strictify more speculative bangs - - - - - d0d7ba0f by Vladislav Zavialov at 2023-01-26T20:08:25-05:00 base: NoImplicitPrelude in Data.Void and Data.Kind This change removes an unnecessary dependency on Prelude from two modules in the base package. - - - - - fa1db923 by Matthew Pickering at 2023-01-26T20:09:00-05:00 ci: Add ubuntu18_04 nightly and release jobs This adds release jobs for ubuntu18_04 which uses glibc 2.27 which is older than the 2.28 which is used by Rocky8 bindists. Ticket #22268 - - - - - 807310a1 by Matthew Pickering at 2023-01-26T20:09:00-05:00 rel-eng: Add missing rocky8 bindist We intend to release rocky8 bindist so the fetching script needs to know about them. - - - - - c7116b10 by Ben Gamari at 2023-01-26T20:09:35-05:00 base: Make changelog proposal references more consistent Addresses #22773. - - - - - 6932cfc7 by Sylvain Henry at 2023-01-26T20:10:27-05:00 Fix spurious change from !9568 - - - - - e480fbc2 by Ben Gamari at 2023-01-27T05:01:24-05:00 rts: Use C11-compliant static assertion syntax Previously we used `static_assert` which is only available in C23. By contrast, C11 only provides `_Static_assert`. Fixes #22777 - - - - - 2648c09c by Andrei Borzenkov at 2023-01-27T05:02:07-05:00 Replace errors from badOrigBinding with new one (#22839) Problem: in 02279a9c the type-level [] syntax was changed from a built-in name to an alias for the GHC.Types.List constructor. badOrigBinding assumes that if a name is not built-in then it must have come from TH quotation, but this is not necessarily the case with []. The outdated assumption in badOrigBinding leads to incorrect error messages. This code: data [] Fails with "Cannot redefine a Name retrieved by a Template Haskell quote: []" Unfortunately, there is not enough information in RdrName to directly determine if the name was constructed via TH or by the parser, so this patch changes the error message instead. It unifies TcRnIllegalBindingOfBuiltIn and TcRnNameByTemplateHaskellQuote into a new error TcRnBindingOfExistingName and changes its wording to avoid guessing the origin of the name. - - - - - 545bf8cf by Matthew Pickering at 2023-01-27T14:58:53+00:00 Revert "base: NoImplicitPrelude in Data.Void and Data.Kind" Fixes CI errors of the form. ``` ===> Command failed with error code: 1 ghc: panic! (the 'impossible' happened) GHC version 9.7.20230127: lookupGlobal Failed to load interface for ‘GHC.Num.BigNat’ There are files missing in the ‘ghc-bignum’ package, try running 'ghc-pkg check'. Use -v (or `:set -v` in ghci) to see a list of the files searched for. Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Tc/Utils/Env.hs:154:32 in ghc:GHC.Tc.Utils.Env CallStack (from HasCallStack): panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` This reverts commit d0d7ba0fb053ebe7f919a5932066fbc776301ccd. The module now lacks a dependency on GHC.Num.BigNat which it implicitly depends on. It is causing all CI jobs to fail so we revert without haste whilst the patch can be fixed. Fixes #22848 - - - - - 638277ba by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Detect family instance orphans correctly We were treating a type-family instance as a non-orphan if there was a type constructor on its /right-hand side/ that was local. Boo! Utterly wrong. With this patch, we correctly check the /left-hand side/ instead! Fixes #22717 - - - - - 46a53bb2 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Report family instance orphans correctly This fixes the fact that we were not reporting orphan family instances at all. The fix here is easy, but touches a bit of code. I refactored the code to be much more similar to the way that class instances are done: - Add a fi_orphan field to FamInst, like the is_orphan field in ClsInst - Make newFamInst initialise this field, just like newClsInst - And make newFamInst report a warning for an orphan, just like newClsInst - I moved newFamInst from GHC.Tc.Instance.Family to GHC.Tc.Utils.Instantiate, just like newClsInst. - I added mkLocalFamInst to FamInstEnv, just like mkLocalClsInst in InstEnv - TcRnOrphanInstance and SuggestFixOrphanInstance are now parametrised over class instances vs type/data family instances. Fixes #19773 - - - - - faa300fb by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in STG This patch removes some orphan instances in the STG namespace by introducing the GHC.Stg.Lift.Types module, which allows various type family instances to be moved to GHC.Stg.Syntax, avoiding orphan instances. - - - - - 0f25a13b by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in the parser This moves Anno instances for PatBuilder from GHC.Parser.PostProcess to GHC.Parser.Types to avoid orphans. - - - - - 15750d33 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Accept an orphan declaration (sadly) This accepts the orphan type family instance type instance DsForeignHook = ... in GHC.HsToCore.Types. See Note [The Decoupling Abstract Data Hack] in GHC.Driver.Hooks - - - - - c9967d13 by Zubin Duggal at 2023-01-27T23:55:31-05:00 bindist configure: Fail if find not found (#22691) - - - - - ad8cfed4 by John Ericson at 2023-01-27T23:56:06-05:00 Put hadrian bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. - - - - - d0ddc01b by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Introduce threaded2_sanity way Incredibly, we previously did not have a single way which would test the threaded RTS with multiple capabilities and the sanity-checker enabled. - - - - - 38ad8351 by Ben Gamari at 2023-01-27T23:56:42-05:00 rts: Relax Messages assertion `doneWithMsgThrowTo` was previously too strict in asserting that the `Message` is locked. Specifically, it failed to consider that the `Message` may not be locked if we are deleting all threads during RTS shutdown. - - - - - a9fe81af by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Fix race in UnliftedTVar2 Previously UnliftedTVar2 would fail when run with multiple capabilities (and possibly even with one capability) as it would assume that `killThread#` would immediately kill the "increment" thread. Also, refactor the the executable to now succeed with no output and fails with an exit code. - - - - - 8519af60 by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Make listThreads more robust Previously it was sensitive to the labels of threads which it did not create (e.g. the IO manager event loop threads). Fix this. - - - - - 55a81995 by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix non-atomic mutation of enabled_capabilities - - - - - b5c75f1d by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix C++ compilation issues Make the RTS compilable with a C++ compiler by inserting necessary casts. - - - - - c261b62f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix typo "tracingAddCapabilities" was mis-named - - - - - 77fdbd3f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Drop long-dead fallback definitions for INFINITY & NAN These are no longer necessary since we now compile as C99. - - - - - 56c1bd98 by Ben Gamari at 2023-01-28T02:57:59-05:00 Revert "CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043)" This reverts commit 99aca26b652603bc62953157a48e419f737d352d. - - - - - b3a3534b by nineonine at 2023-01-28T02:57:59-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043. - - - - - 082b7d43 by Oleg Grenrus at 2023-01-28T02:58:38-05:00 Add Foldable1 Solo instance - - - - - 50b1e2e8 by Andrei Borzenkov at 2023-01-28T02:59:18-05:00 Convert diagnostics in GHC.Rename.Bind to proper TcRnMessage (#20115) I removed all occurrences of TcRnUnknownMessage in GHC.Rename.Bind module. Instead, these TcRnMessage messages were introduced: TcRnMultipleFixityDecls TcRnIllegalPatternSynonymDecl TcRnIllegalClassBiding TcRnOrphanCompletePragma TcRnEmptyCase TcRnNonStdGuards TcRnDuplicateSigDecl TcRnMisplacedSigDecl TcRnUnexpectedDefaultSig TcRnBindInBootFile TcRnDuplicateMinimalSig - - - - - 3330b819 by Matthew Pickering at 2023-01-28T02:59:54-05:00 hadrian: Fix library-dirs, dynamic-library-dirs and static-library-dirs in inplace .conf files Previously we were just throwing away the contents of the library-dirs fields but really we have to do the same thing as for include-dirs, relativise the paths into the current working directory and maintain any extra libraries the user has specified. Now the relevant section of the rts.conf file looks like: ``` library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib library-dirs-static: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib dynamic-library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib ``` Fixes #22209 - - - - - c9ad8852 by Andrew Lelechenko at 2023-01-28T03:00:33-05:00 Document differences between Data.{Monoid,Semigroup}.{First,Last} - - - - - 7e11c6dc by Cheng Shao at 2023-01-28T03:01:09-05:00 compiler: fix subword literal narrowing logic in the wasm NCG This patch fixes the W8/W16 literal narrowing logic in the wasm NCG, which used to lower it to something like i32.const -1, without properly zeroing-out the unused higher bits. Fixes #22608. - - - - - 6ea2aa02 by Cheng Shao at 2023-01-28T03:01:46-05:00 compiler: fix lowering of CmmBlock in the wasm NCG The CmmBlock datacon was not handled in lower_CmmLit, since I thought it would have been eliminated after proc-point splitting. Turns out it still occurs in very rare occasions, and this patch is needed to fix T9329 for wasm. - - - - - 2b62739d by Andrew Lelechenko at 2023-01-28T17:16:11-05:00 Assorted changes to avoid Data.List.{head,tail} - - - - - 78c07219 by Cheng Shao at 2023-01-28T17:16:48-05:00 compiler: properly handle ForeignHints in the wasm NCG Properly handle ForeignHints of ccall arguments/return value, insert sign extends and truncations when handling signed subwords. Fixes #22852. - - - - - 8bed166b by Ben Gamari at 2023-01-30T05:06:26-05:00 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. - - - - - da468391 by Cheng Shao at 2023-01-30T05:07:03-05:00 compiler: fix data section alignment in the wasm NCG Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size. - - - - - 08ba8720 by Andreas Klebinger at 2023-01-30T21:18:45-05:00 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- - - - - - 20598ef6 by Ryan Scott at 2023-01-30T21:19:20-05:00 Handle `type data` properly in tyThingParent_maybe Unlike most other data constructors, data constructors declared with `type data` are represented in `TyThing`s as `ATyCon` rather than `ADataCon`. The `ATyCon` case in `tyThingParent_maybe` previously did not consider the possibility of the underlying `TyCon` being a promoted data constructor, which led to the oddities observed in #22817. This patch adds a dedicated special case in `tyThingParent_maybe`'s `ATyCon` case for `type data` data constructors to fix these oddities. Fixes #22817. - - - - - 2f145052 by Ryan Scott at 2023-01-30T21:19:56-05:00 Fix two bugs in TypeData TH reification This patch fixes two issues in the way that `type data` declarations were reified with Template Haskell: * `type data` data constructors are now properly reified using `DataConI`. This is accomplished with a special case in `reifyTyCon`. Fixes #22818. * `type data` type constructors are now reified in `reifyTyCon` using `TypeDataD` instead of `DataD`. Fixes #22819. - - - - - d0f34f25 by Simon Peyton Jones at 2023-01-30T21:20:35-05:00 Take account of loop breakers in specLookupRule The key change is that in GHC.Core.Opt.Specialise.specLookupRule we were using realIdUnfolding, which ignores the loop-breaker flag. When given a loop breaker, rule matching therefore looped infinitely -- #22802. In fixing this I refactored a bit. * Define GHC.Core.InScopeEnv as a data type, and use it. (Previously it was a pair: hard to grep for.) * Put several functions returning an IdUnfoldingFun into GHC.Types.Id, namely idUnfolding alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun and use them. (The are all loop-breaker aware.) - - - - - de963cb6 by Matthew Pickering at 2023-01-30T21:21:11-05:00 ci: Remove FreeBSD job from release pipelines We no longer attempt to build or distribute this release - - - - - f26d27ec by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Add check to make sure that release jobs are downloaded by fetch-gitlab This check makes sure that if a job is a prefixed by "release-" then the script downloads it and understands how to map the job name to the platform. - - - - - 7619c0b4 by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Fix the name of the ubuntu-* jobs These were not uploaded for alpha1 Fixes #22844 - - - - - 68eb8877 by Matthew Pickering at 2023-01-30T21:21:11-05:00 gen_ci: Only consider release jobs for job metadata In particular we do not have a release job for FreeBSD so the generation of the platform mapping was failing. - - - - - b69461a0 by Jason Shipman at 2023-01-30T21:21:50-05:00 User's guide: Clarify overlapping instance candidate elimination This commit updates the user's guide section on overlapping instance candidate elimination to use "or" verbiage instead of "either/or" in regards to the current pair of candidates' being overlappable or overlapping. "Either IX is overlappable, or IY is overlapping" can cause confusion as it suggests "Either IX is overlappable, or IY is overlapping, but not both". This was initially discussed on this Discourse topic: https://discourse.haskell.org/t/clarification-on-overlapping-instance-candidate-elimination/5677 - - - - - 7cbdaad0 by Matthew Pickering at 2023-01-31T07:53:53-05:00 Fixes for cabal-reinstall CI job * Allow filepath to be reinstalled * Bump some version bounds to allow newer versions of libraries * Rework testing logic to avoid "install --lib" and package env files Fixes #22344 - - - - - fd8f32bf by Cheng Shao at 2023-01-31T07:54:29-05:00 rts: prevent potential divide-by-zero when tickInterval=0 This patch fixes a few places in RtsFlags.c that may result in divide-by-zero error when tickInterval=0, which is the default on wasm. Fixes #22603. - - - - - 085a6db6 by Joachim Breitner at 2023-01-31T07:55:05-05:00 Update note at beginning of GHC.Builtin.NAmes some things have been renamed since it was written, it seems. - - - - - 7716cbe6 by Cheng Shao at 2023-01-31T07:55:41-05:00 testsuite: use tgamma for cg007 gamma is a glibc-only deprecated function, use tgamma instead. It's required for fixing cg007 when testing the wasm unregisterised codegen. - - - - - 19c1fbcd by doyougnu at 2023-01-31T13:08:03-05:00 InfoTableProv: ShortText --> ShortByteString - - - - - 765fab98 by doyougnu at 2023-01-31T13:08:03-05:00 FastString: add fastStringToShorText - - - - - a83c810d by Simon Peyton Jones at 2023-01-31T13:08:38-05:00 Improve exprOkForSpeculation for classops This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord - - - - - f83374f8 by Krzysztof Gogolewski at 2023-01-31T13:09:14-05:00 Support "unusable UNPACK pragma" warning with -O0 Fixes #11270 - - - - - a2d814dc by Ben Gamari at 2023-01-31T13:09:50-05:00 configure: Always create the VERSION file Teach the `configure` script to create the `VERSION` file. This will serve as the stable interface to allow the user to determine the version number of a working tree. Fixes #22322. - - - - - 5618fc21 by sheaf at 2023-01-31T15:51:06-05:00 Cmm: track the type of global registers This patch tracks the type of Cmm global registers. This is needed in order to lint uses of polymorphic registers, such as SIMD vector registers that can be used both for floating-point and integer values. This changes allows us to refactor VanillaReg to not store VGcPtr, as that information is instead stored in the type of the usage of the register. Fixes #22297 - - - - - 78b99430 by sheaf at 2023-01-31T15:51:06-05:00 Revert "Cmm Lint: relax SIMD register assignment check" This reverts commit 3be48877, which weakened a Cmm Lint check involving SIMD vectors. Now that we keep track of the type a global register is used at, we can restore the original stronger check. - - - - - be417a47 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. - - - - - 30989d13 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. - - - - - 7566fd9d by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. - - - - - 2cb500a5 by Ben Gamari at 2023-01-31T15:51:45-05:00 testsuite: Add regression test for #22798 - - - - - 03d693b2 by Ben Gamari at 2023-01-31T15:52:32-05:00 Revert "Hadrian: fix doc generation" This is too large of a hammer. This reverts commit 5640cb1d84d3cce4ce0a9e90d29b2b20d2b38c2f. - - - - - f838815c by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Sphinx docs require templated cabal files The package-version discovery logic in `doc/users_guide/package_versions.py` uses packages' cabal files to determine package versions. Teach Sphinx about these dependencies in cases where the cabal files are generated by templates. - - - - - 2e48c19a by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Refactor templating logic This refactors Hadrian's autoconf-style templating logic to be explicit about which interpolation variables should be substituted in which files. This clears the way to fix #22714 without incurring rule cycles. - - - - - 93f0e3c4 by Ben Gamari at 2023-01-31T15:52:33-05:00 hadrian: Substitute LIBRARY_*_VERSION variables This teaches Hadrian to substitute the `LIBRARY_*_VERSION` variables in `libraries/prologue.txt`, fixing #22714. Fixes #22714. - - - - - 22089f69 by Ben Gamari at 2023-01-31T20:46:27-05:00 Bump transformers submodule to 0.6.0.6 Fixes #22862. - - - - - f0eefa3c by Cheng Shao at 2023-01-31T20:47:03-05:00 compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCG Currently, the wasm NCG has an implicit assumption: all CmmSwitch scrutinees are 32-bit integers. This is not always true; #22864 is one counter-example with a 64-bit scrutinee. This patch fixes the logic by explicitly converting the scrutinee to a word that can be used as a br_table operand. Fixes #22871. Also includes a regression test. - - - - - 9f95db54 by Simon Peyton Jones at 2023-02-01T08:55:08+00:00 Improve treatment of type applications in patterns This patch fixes a subtle bug in the typechecking of type applications in patterns, e.g. f (MkT @Int @a x y) = ... See Note [Type applications in patterns] in GHC.Tc.Gen.Pat. This fixes #19847, #22383, #19577, #21501 - - - - - 955a99ea by Simon Peyton Jones at 2023-02-01T12:31:23-05:00 Treat existentials correctly in dubiousDataConInstArgTys Consider (#22849) data T a where MkT :: forall k (t::k->*) (ix::k). t ix -> T @k a Then dubiousDataConInstArgTys MkT [Type, Foo] should return [Foo (ix::Type)] NOT [Foo (ix::k)] A bit of an obscure case, but it's an outright bug, and the fix is easy. - - - - - 0cc16aaf by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump supported LLVM range from 10 through 15 to 11 through 16 LLVM 15 turns on the new pass manager by default, which we have yet to migrate to so for new we pass the `-enable-new-pm-0` flag in our llvm-passes flag. LLVM 11 was the first version to support the `-enable-new-pm` flag so we bump the lowest supported version to 11. Our CI jobs are using LLVM 12 so they should continue to work despite this bump to the lower bound. Fixes #21936 - - - - - f94f1450 by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump DOCKER_REV to use alpine image without LLVM installed alpine_3_12 only supports LLVM 10, which is now outside the supported version range. - - - - - 083e26ed by Matthew Pickering at 2023-02-01T17:43:21-05:00 Remove tracing OPTIONS_GHC These were accidentally left over from !9542 - - - - - 354aa47d by Teo Camarasu at 2023-02-01T17:44:00-05:00 doc: fix gcdetails_block_fragmentation_bytes since annotation - - - - - 61ce5bf6 by Jaro Reinders at 2023-02-02T00:15:30-05:00 compiler: Implement higher order patterns in the rule matcher This implements proposal 555 and closes ticket #22465. See the proposal and ticket for motivation. The core changes of this patch are in the GHC.Core.Rules.match function and they are explained in the Note [Matching higher order patterns]. - - - - - 394b91ce by doyougnu at 2023-02-02T00:16:10-05:00 CI: JavaScript backend runs testsuite This MR runs the testsuite for the JS backend. Note that this is a temporary solution until !9515 is merged. Key point: The CI runs hadrian on the built cross compiler _but not_ on the bindist. Other Highlights: - stm submodule gets a bump to mark tests as broken - several tests are marked as broken or are fixed by adding more - conditions to their test runner instance. List of working commit messages: CI: test cross target _and_ emulator CI: JS: Try run testsuite with hadrian JS.CI: cleanup and simplify hadrian invocation use single bracket, print info JS CI: remove call to test_compiler from hadrian don't build haddock JS: mark more tests as broken Tracked in https://gitlab.haskell.org/ghc/ghc/-/issues/22576 JS testsuite: don't skip sum_mod test Its expected to fail, yet we skipped it which automatically makes it succeed leading to an unexpected success, JS testsuite: don't mark T12035j as skip leads to an unexpected pass JS testsuite: remove broken on T14075 leads to unexpected pass JS testsuite: mark more tests as broken JS testsuite: mark T11760 in base as broken JS testsuite: mark ManyUnbSums broken submodules: bump process and hpc for JS tests Both submodules has needed tests skipped or marked broken for th JS backend. This commit now adds these changes to GHC. See: HPC: https://gitlab.haskell.org/hpc/hpc/-/merge_requests/21 Process: https://github.com/haskell/process/pull/268 remove js_broken on now passing tests separate wasm and js backend ci test: T11760: add threaded, non-moving only_ways test: T10296a add req_c T13894: skip for JS backend tests: jspace, T22333: mark as js_broken(22573) test: T22513i mark as req_th stm submodule: mark stm055, T16707 broken for JS tests: js_broken(22374) on unpack_sums_6, T12010 dont run diff on JS CI, cleanup fixup: More CI cleanup fix: align text to master fix: align exceptions submodule to master CI: Bump DOCKER_REV Bump to ci-images commit that has a deb11 build with node. Required for !9552 testsuite: mark T22669 as js_skip See #22669 This test tests that .o-boot files aren't created when run in using the interpreter backend. Thus this is not relevant for the JS backend. testsuite: mark T22671 as broken on JS See #22835 base.testsuite: mark Chan002 fragile for JS see #22836 revert: submodule process bump bump stm submodule New hash includes skips for the JS backend. testsuite: mark RnPatternSynonymFail broken on JS Requires TH: - see !9779 - and #22261 compiler: GHC.hs ifdef import Utils.Panic.Plain - - - - - 1ffe770c by Cheng Shao at 2023-02-02T09:40:38+00:00 docs: 9.6 release notes for wasm backend - - - - - 0ada4547 by Matthew Pickering at 2023-02-02T11:39:44-05:00 Disable unfolding sharing for interface files with core definitions Ticket #22807 pointed out that the RHS sharing was not compatible with -fignore-interface-pragmas because the flag would remove unfoldings from identifiers before the `extra-decls` field was populated. For the 9.6 timescale the only solution is to disable this sharing, which will make interface files bigger but this is acceptable for the first release of `-fwrite-if-simplified-core`. For 9.8 it would be good to fix this by implementing #20056 due to the large number of other bugs that would fix. I also improved the error message in tc_iface_binding to avoid the "no match in record selector" error but it should never happen now as the entire sharing logic is disabled. Also added the currently broken test for #22807 which could be fixed by !6080 Fixes #22807 - - - - - 7e2d3eb5 by lrzlin at 2023-02-03T05:23:27-05:00 Enable tables next to code for LoongArch64 - - - - - 2931712a by Wander Hillen at 2023-02-03T05:24:06-05:00 Move pthread and timerfd ticker implementations to separate files - - - - - 41c4baf8 by Ben Gamari at 2023-02-03T05:24:44-05:00 base: Fix Note references in GHC.IO.Handle.Types - - - - - 31358198 by Andrew Lelechenko at 2023-02-03T05:25:22-05:00 Bump submodule containers to 0.6.7 Metric Decrease: ManyConstructors T10421 T12425 T12707 T13035 T13379 T15164 T1969 T783 T9198 T9961 WWRec - - - - - 8feb9301 by Ben Gamari at 2023-02-03T05:25:59-05:00 gitlab-ci: Eliminate redundant ghc --info output Previously ci.sh would emit the output of `ghc --info` every time it ran when using the nix toolchain. This produced a significant amount of noise. See #22861. - - - - - de1d1512 by Ryan Scott at 2023-02-03T14:07:30-05:00 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` - - - - - 48e39195 by Tamar Christina at 2023-02-03T14:07:30-05:00 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. - - - - - b2bb3e62 by Ben Gamari at 2023-02-03T14:07:30-05:00 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - bf3f88a1 by Andreas Klebinger at 2023-02-03T14:08:07-05:00 Fix CallerCC potentially shadowing other cost centres. Add a CallerCC cost centre flavour for cost centres added by the CallerCC pass. This avoids potential accidental shadowing between CCs added by user annotations and ones added by CallerCC. - - - - - faea4bcd by j at 2023-02-03T14:08:47-05:00 Disable several ignore-warning flags in genapply. - - - - - 25537dfd by Ben Gamari at 2023-02-04T04:12:57-05:00 Revert "Use fix-sized bit-fiddling primops for fixed size boxed types" This reverts commit 4512ad2d6a8e65ea43c86c816411cb13b822f674. This was never applied to master/9.6 originally. (cherry picked from commit a44bdc2720015c03d57f470b759ece7fab29a57a) - - - - - 7612dc71 by Krzysztof Gogolewski at 2023-02-04T04:13:34-05:00 Minor refactor * Introduce refactorDupsOn f = refactorDups (comparing f) * Make mkBigTupleCase and coreCaseTuple monadic. Every call to those functions was preceded by calling newUniqueSupply. * Use mkUserLocalOrCoVar, which is equivalent to combining mkLocalIdOrCoVar with mkInternalName. - - - - - 5a54ac0b by Andrew Lelechenko at 2023-02-04T18:48:32-05:00 Fix colors in emacs terminal - - - - - 3c0f0c6d by Andrew Lelechenko at 2023-02-04T18:49:11-05:00 base changelog: move entries which were not backported to ghc-9.6 to base-4.19 section - - - - - b18fbf52 by Josh Meredith at 2023-02-06T07:47:57+00:00 Update JavaScript fileStat to match Emscripten layout - - - - - 6636b670 by Sylvain Henry at 2023-02-06T09:43:21-05:00 JS: replace "js" architecture with "javascript" Despite Cabal supporting any architecture name, `cabal --check` only supports a few built-in ones. Sadly `cabal --check` is used by Hackage hence using any non built-in name in a package (e.g. `arch(js)`) is rejected and the package is prevented from being uploaded on Hackage. Luckily built-in support for the `javascript` architecture was added for GHCJS a while ago. In order to allow newer `base` to be uploaded on Hackage we make the switch from `js` to `javascript` architecture. Fixes #22740. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 77a8234c by Luite Stegeman at 2023-02-06T09:43:59-05:00 Fix marking async exceptions in the JS backend Async exceptions are posted as a pair of the exception and the thread object. This fixes the marking pass to correctly follow the two elements of the pair. Potentially fixes #22836 - - - - - 3e09cf82 by Jan Hrček at 2023-02-06T09:44:38-05:00 Remove extraneous word in Roles user guide - - - - - b17fb3d9 by sheaf at 2023-02-07T10:51:33-05:00 Don't allow . in overloaded labels This patch removes . from the list of allowed characters in a non-quoted overloaded label, as it was realised this steals syntax, e.g. (#.). Users who want this functionality will have to add quotes around the label, e.g. `#"17.28"`. Fixes #22821 - - - - - 5dce04ee by romes at 2023-02-07T10:52:10-05:00 Update kinds in comments in GHC.Core.TyCon Use `Type` instead of star kind (*) Fix comment with incorrect kind * to have kind `Constraint` - - - - - 92916194 by Ben Gamari at 2023-02-07T10:52:48-05:00 Revert "Use fix-sized equality primops for fixed size boxed types" This reverts commit 024020c38126f3ce326ff56906d53525bc71690c. This was never applied to master/9.6 originally. See #20405 for why using these primops is a bad idea. (cherry picked from commit b1d109ad542e4c37ae5af6ace71baf2cb509d865) - - - - - c1670c6b by Sylvain Henry at 2023-02-07T21:25:18-05:00 JS: avoid head/tail and unpackFS - - - - - a9912de7 by Krzysztof Gogolewski at 2023-02-07T21:25:53-05:00 testsuite: Fix Python warnings (#22856) - - - - - 9ee761bf by sheaf at 2023-02-08T14:40:40-05:00 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 - - - - - 7eac2468 by Matthew Pickering at 2023-02-08T14:41:17-05:00 Revert "Don't keep exit join points so much" This reverts commit caced75765472a1a94453f2e5a439dba0d04a265. It seems the patch "Don't keep exit join points so much" is causing wide-spread regressions in the bytestring library benchmarks. If I revert it then the 9.6 numbers are better on average than 9.4. See https://gitlab.haskell.org/ghc/ghc/-/issues/22893#note_479525 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T12150 T13386 T13719 T21839c T3294 parsing001 ------------------------- - - - - - 633f2799 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: remove config.use_threads This patch simplifies the testsuite driver by removing the use_threads config field. It's just a degenerate case of threads=1. - - - - - ca6673e3 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: use concurrent.futures.ThreadPoolExecutor in the driver The testsuite driver used to create one thread per test case, and explicitly use semaphore and locks for rate limiting and synchronization. This is a bad practice in any language, and occasionally may result in livelock conditions (e.g. #22889). This patch uses concurrent.futures.ThreadPoolExecutor for scheduling test case runs, which is simpler and more robust. - - - - - f22cce70 by Alan Zimmerman at 2023-02-08T18:42:51-05:00 EPA: Comment between module and where should be in header comments Do not apply the heuristic to associate a comment with a prior declaration for the first declaration in the file. Closes #22919 - - - - - d69ecac2 by Josh Meredith at 2023-02-09T03:24:05-05:00 JS generated refs: update testsuite conditions - - - - - 2ea1a6bc by sheaf at 2023-02-09T03:24:44-05:00 Bump transformers to 0.6.1.0 This allows us to avoid orphans for Foldable1 instances, fixing #22898. Updates transformers submodule. - - - - - d9d0c28d by konsumlamm at 2023-02-09T14:07:48-05:00 Update `Data.List.singleton` doc comment - - - - - fe9cd6ef by Ben Gamari at 2023-02-09T14:08:23-05:00 gitlab-template: Emphasize `user facing` label My sense is that the current mention of the ~"user facing" label is overlooked by many MR authors. Let's move this point up in the list to make it more likely that it is seen. Also rephrase some of the points. - - - - - e45eb828 by Simon Peyton Jones at 2023-02-10T06:51:28-05:00 Refactor the simplifier a bit to fix #22761 The core change in this commit, which fixes #22761, is that * In a Core rule, ru_rhs is always occ-analysed. This means adding a couple of calls to occurAnalyseExpr when building a Rule, in * GHC.Core.Rules.mkRule * GHC.Core.Opt.Simplify.Iteration.simplRules But diagosing the bug made me stare carefully at the code of the Simplifier, and I ended up doing some only-loosely-related refactoring. * I think that RULES could be lost because not every code path did addBndrRules * The code around lambdas was very convoluted It's mainly moving deck chairs around, but I like it more now. - - - - - 11e0cacb by Rebecca Turner at 2023-02-10T06:52:09-05:00 Detect the `mold` linker Enables support for the `mold` linker by rui314. - - - - - 59556235 by parsonsmatt at 2023-02-10T09:53:11-05:00 Add Lift instance for Fixed - - - - - c44e5f30 by Sylvain Henry at 2023-02-10T09:53:51-05:00 Testsuite: decrease length001 timeout for JS (#22921) - - - - - 133516af by Zubin Duggal at 2023-02-10T09:54:27-05:00 compiler: Use NamedFieldPuns for `ModIface_` and `ModIfaceBackend` `NFData` instances This is a minor refactor that makes it easy to add and remove fields from `ModIface_` and `ModIfaceBackend`. Also change the formatting to make it clear exactly which fields are fully forced with `rnf` - - - - - 1e9eac1c by Matthew Pickering at 2023-02-13T11:36:41+01:00 Refresh profiling docs I went through the whole of the profiling docs and tried to amend them to reflect current best practices and tooling. In particular I removed some old references to tools such as hp2any and replaced them with references to eventlog2html. - - - - - da208b9a by Matthew Pickering at 2023-02-13T11:36:41+01:00 docs: Add section about profiling and foreign calls Previously there was no documentation for how foreign calls interacted with the profiler. This can be quite confusing for users so getting it into the user guide is the first step to a potentially better solution. See the ticket for more insightful discussion. Fixes #21764 - - - - - 081640f1 by Andrew Lelechenko at 2023-02-13T12:51:52-05:00 Document that -fproc-alignment was introduced only in GHC 8.6 - - - - - 16adc349 by Sven Tennie at 2023-02-14T11:26:31-05:00 Add clangd flag to include generated header files This enables clangd to correctly check C files that import Rts.h. (The added include directory contains ghcautoconf.h et. al.) - - - - - c399ccd9 by amesgen at 2023-02-14T11:27:14-05:00 Mention new `Foreign.Marshal.Pool` implementation in User's Guide - - - - - b9282cf7 by Ben Gamari at 2023-02-14T11:27:50-05:00 upload_ghc_libs: More control over which packages to operate on Here we add a `--skip` flag to `upload_ghc_libs`, making it easier to limit which packages to upload. This is often necessary when one package is not uploadable (e.g. see #22740). - - - - - aa3a262d by PHO at 2023-02-14T11:28:29-05:00 Assume platforms support rpaths if they use either ELF or Mach-O Not only Linux, Darwin, and FreeBSD support rpaths. Determine the usability of rpaths based on the object format, not on OS. - - - - - 47716024 by PHO at 2023-02-14T11:29:09-05:00 RTS linker: Improve compatibility with NetBSD 1. Hint address to NetBSD mmap(2) has a different semantics from that of Linux. When a hint address is provided, mmap(2) searches for a free region at or below the hint but *never* above it. This means we can't reliably search for free regions incrementally on the userland, especially when ASLR is enabled. Let the kernel do it for us if we don't care where the mapped address is going to be. 2. NetBSD not only hates to map pages as rwx, but also disallows to switch pages from rw- to r-x unless the intention is declared when pages are initially requested. This means we need a new MemoryAccess mode for pages that are going to be changed to r-x. - - - - - 11de324a by Li-yao Xia at 2023-02-14T11:29:49-05:00 base: Move changelog entry to its place - - - - - 75930424 by Ben Gamari at 2023-02-14T11:30:27-05:00 nativeGen/AArch64: Emit Atomic{Read,Write} inline Previously the AtomicRead and AtomicWrite operations were emitted as out-of-line calls. However, these tend to be very important for performance, especially the RELAXED case (which only exists for ThreadSanitizer checking). Fixes #22115. - - - - - d6411d6c by Andreas Klebinger at 2023-02-14T11:31:04-05:00 Fix some correctness issues around tag inference when targeting the bytecode generator. * Let binders are now always assumed untagged for bytecode. * Imported referenced are now always assumed to be untagged for bytecode. Fixes #22840 - - - - - 9fb4ca89 by sheaf at 2023-02-14T11:31:49-05:00 Introduce warning for loopy superclass solve Commit aed1974e completely re-engineered the treatment of loopy superclass dictionaries in instance declarations. Unfortunately, it has the potential to break (albeit in a rather minor way) user code. To alleviate migration concerns, this commit re-introduces the old behaviour. Any reliance on this old behaviour triggers a warning, controlled by `-Wloopy-superclass-solve`. The warning text explains that GHC might produce bottoming evidence, and provides a migration strategy. This allows us to provide a graceful migration period, alerting users when they are relying on this unsound behaviour. Fixes #22912 #22891 #20666 #22894 #22905 - - - - - 1928c7f3 by Cheng Shao at 2023-02-14T11:32:26-05:00 rts: make it possible to change mblock size on 32-bit targets The MBLOCK_SHIFT macro must be the single source of truth for defining the mblock size, and changing it should only affect performance, not correctness. This patch makes it truly possible to reconfigure mblock size, at least on 32-bit targets, by fixing places which implicitly relied on the previous MBLOCK_SHIFT constant. Fixes #22901. - - - - - 78aa3b39 by Simon Hengel at 2023-02-14T11:33:06-05:00 Update outdated references to notes - - - - - e8baecd2 by meooow25 at 2023-02-14T11:33:49-05:00 Documentation: Improve Foldable1 documentation * Explain foldrMap1, foldlMap1, foldlMap1', and foldrMap1' in greater detail, the text is mostly adapted from documentation of Foldable. * Describe foldr1, foldl1, foldl1' and foldr1' in terms of the above functions instead of redoing the full explanation. * Small updates to documentation of fold1, foldMap1 and toNonEmpty, again adapting from Foldable. * Update the foldMap1 example to lists instead of Sum since this is recommended for lazy right-associative folds. Fixes #22847 - - - - - 85a1a575 by romes at 2023-02-14T11:34:25-05:00 fix: Mark ghci Prelude import as implicit Fixes #22829 In GHCi, we were creating an import declaration for Prelude but we were not setting it as an implicit declaration. Therefore, ghci's import of Prelude triggered -Wmissing-import-lists. Adds regression test T22829 to testsuite - - - - - 3b019a7a by Cheng Shao at 2023-02-14T11:35:03-05:00 compiler: fix generateCgIPEStub for no-tables-next-to-code builds generateCgIPEStub already correctly implements the CmmTick finding logic for when tables-next-to-code is on/off, but it used the wrong predicate to decide when to switch between the two. Previously it switches based on whether the codegen is unregisterised, but there do exist registerised builds that disable tables-next-to-code! This patch corrects that problem. Fixes #22896. - - - - - 08c0822c by doyougnu at 2023-02-15T00:16:39-05:00 docs: release notes, user guide: add js backend Follow up from #21078 - - - - - 79d8fd65 by Bryan Richter at 2023-02-15T00:17:15-05:00 Allow failure in nightly-x86_64-linux-deb10-no_tntc-validate See #22343 - - - - - 9ca51f9e by Cheng Shao at 2023-02-15T00:17:53-05:00 rts: add the rts_clearMemory function This patch adds the rts_clearMemory function that does its best to zero out unused RTS memory for a wasm backend use case. See the comment above rts_clearMemory() prototype declaration for more detailed explanation. Closes #22920. - - - - - 26df73fb by Oleg Grenrus at 2023-02-15T22:20:57-05:00 Add -single-threaded flag to force single threaded rts This is the small part of implementing https://github.com/ghc-proposals/ghc-proposals/pull/240 - - - - - 631c6c72 by Cheng Shao at 2023-02-16T06:43:09-05:00 docs: add a section for the wasm backend Fixes #22658 - - - - - 1878e0bd by Bryan Richter at 2023-02-16T06:43:47-05:00 tests: Mark T12903 fragile everywhere See #21184 - - - - - b9420eac by Bryan Richter at 2023-02-16T06:43:47-05:00 Mark all T5435 variants as fragile See #22970. - - - - - df3d94bd by Sylvain Henry at 2023-02-16T06:44:33-05:00 Testsuite: mark T13167 as fragile for JS (#22921) - - - - - 324e925b by Sylvain Henry at 2023-02-16T06:45:15-05:00 JS: disable debugging info for heap objects - - - - - 518af814 by Josh Meredith at 2023-02-16T10:16:32-05:00 Factor JS Rts generation for h$c{_,0,1,2} into h$c{n} and improve name caching - - - - - 34cd308e by Ben Gamari at 2023-02-16T10:17:08-05:00 base: Note move of GHC.Stack.CCS.whereFrom to GHC.InfoProv in changelog Fixes #22883. - - - - - 12965aba by Simon Peyton Jones at 2023-02-16T10:17:46-05:00 Narrow the dont-decompose-newtype test Following #22924 this patch narrows the test that stops us decomposing newtypes. The key change is the use of noGivenNewtypeReprEqs in GHC.Tc.Solver.Canonical.canTyConApp. We went to and fro on the solution, as you can see in #22924. The result is carefully documented in Note [Decomoposing newtype equalities] On the way I had revert most of commit 3e827c3f74ef76d90d79ab6c4e71aa954a1a6b90 Author: Richard Eisenberg <rae at cs.brynmawr.edu> Date: Mon Dec 5 10:14:02 2022 -0500 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. It turns out that (a) 3e827c3f makes GHC behave worse on some recursive newtypes (see one of the tests on this commit) (b) the finer-grained test (namely noGivenNewtypeReprEqs) renders 3e827c3f unnecessary - - - - - 5b038888 by Andrew Lelechenko at 2023-02-16T10:18:24-05:00 Documentation: add an example of SPEC usage - - - - - 681e0e8c by sheaf at 2023-02-16T14:09:56-05:00 No default finalizer exception handler Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680 - - - - - b3ac17ad by Matthew Pickering at 2023-02-16T14:10:31-05:00 unicode: Don't inline bitmap in generalCategory generalCategory contains a huge literal string but is marked INLINE, this will duplicate the string into any use site of generalCategory. In particular generalCategory is used in functions like isSpace and the literal gets inlined into this function which makes it massive. https://github.com/haskell/core-libraries-committee/issues/130 Fixes #22949 ------------------------- Metric Decrease: T4029 T18304 ------------------------- - - - - - 8988eeef by sheaf at 2023-02-16T20:32:27-05:00 Expand synonyms in RoughMap We were failing to expand type synonyms in the function GHC.Core.RoughMap.typeToRoughMatchLookupTc, even though the RoughMap infrastructure crucially relies on type synonym expansion to work. This patch adds the missing type-synonym expansion. Fixes #22985 - - - - - 3dd50e2f by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Add test artifact Add the released testsuite tarball to the generated ghcup metadata. - - - - - c6a967d9 by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Use Ubuntu and Rocky bindists Prefer to use the Ubuntu 20.04 and 18.04 binary distributions on Ubuntu and Linux Mint. Prefer to use the Rocky 8 binary distribution on unknown distributions. - - - - - be0b7209 by Matthew Pickering at 2023-02-17T09:37:16+00:00 Add INLINABLE pragmas to `generic*` functions in Data.OldList These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129 - - - - - a203ad85 by Sylvain Henry at 2023-02-17T15:59:16-05:00 Merge libiserv with ghci `libiserv` serves no purpose. As it depends on `ghci` and doesn't have more dependencies than the `ghci` package, its code could live in the `ghci` package too. This commit also moves most of the code from the `iserv` program into the `ghci` package as well so that it can be reused. This is especially useful for the implementation of TH for the JS backend (#22261, !9779). - - - - - 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Andrew Lelechenko at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Andrew Lelechenko at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Andrew Lelechenko at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Andrew Lelechenko at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Andrew Lelechenko at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Andrew Lelechenko at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Andrew Lelechenko at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Andrew Lelechenko at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Andrew Lelechenko at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Andrew Lelechenko at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Andrew Lelechenko at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Andrew Lelechenko at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 57277662 by sheaf at 2023-04-29T20:23:06+02:00 Add the Unsatisfiable class This commit implements GHC proposal #433, adding the Unsatisfiable class to the GHC.TypeError module. This provides an alternative to TypeError for which error reporting is more predictable: we report it when we are reporting unsolved Wanted constraints. Fixes #14983 #16249 #16906 #18310 #20835 - - - - - 00a8a5ff by Torsten Schmits at 2023-04-30T03:45:09-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 931c8d82 by Ben Orchard at 2023-05-03T20:16:18-04:00 Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - f3460845 by Andrew Lelechenko at 2023-05-03T20:16:57-04:00 Document instances of Double - - - - - 1e9caa1a by Sylvain Henry at 2023-05-03T20:17:37-04:00 Bump Cabal submodule (#22356) - - - - - 4eafb52a by sheaf at 2023-05-03T20:18:16-04:00 Don't forget to check the parent in an export list Commit 3f374399 introduced a bug which caused us to forget to include the parent of an export item of the form T(..) (that is, IEThingAll) when checking for duplicate exports. Fixes #23318 - - - - - 8fde4ac8 by amesgen at 2023-05-03T20:18:57-04:00 Fix unlit path in cross bindists - - - - - 8cc9a534 by Matthew Pickering at 2023-05-04T14:58:14-04:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 3fdb18f8 by romes at 2023-05-04T14:58:14-04:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 6689c9c6 by romes at 2023-05-04T14:58:14-04:00 Validate compatibility of ghcs when loading plugins Ensure, when loading plugins, that the ghc the plugin depends on is the ghc loading the plugin -- otherwise fail to load the plugin. Progress towards #20742. - - - - - db4be339 by romes at 2023-05-04T14:58:14-04:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 944a9b94 by Matthew Pickering at 2023-05-04T14:58:14-04:00 Use hash-unit-ids in release jobs Includes fix upload_ghc_libs glob - - - - - 116d7312 by Josh Meredith at 2023-05-04T14:58:51-04:00 JS: fix bounds checking (Issue 23123) * For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. * Range-based operations must also check both the start and end of the range for bounds * All indicies are valid for ranges of size zero, since they are essentially no-ops * For cases of ByteArray accesses (e.g. read as Int), the end index is (i * sizeof(type) + sizeof(type) - 1), while the previous implementation uses (i + sizeof(type) - 1). In the Int32 example, this is (i * 4 + 3) * IndexByteArrayOp_Word8As* primitives use byte array indicies (unlike the previous point), but now check both start and end indicies * Byte array copies now check if the arrays are the same by identity and then if the ranges overlap. - - - - - 2d5c1dde by Sylvain Henry at 2023-05-04T14:58:51-04:00 Fix remaining issues with bound checking (#23123) While fixing these I've also changed the way we store addresses into ByteArray#. Addr# are composed of two parts: a JavaScript array and an offset (32-bit number). Suppose we want to store an Addr# in a ByteArray# foo at offset i. Before this patch, we were storing both fields as a tuple in the "arr" array field: foo.arr[i] = [addr_arr, addr_offset]; Now we only store the array part in the "arr" field and the offset directly in the array: foo.dv.setInt32(i, addr_offset): foo.arr[i] = addr_arr; It avoids wasting space for the tuple. - - - - - 98c5ee45 by Luite Stegeman at 2023-05-04T14:59:31-04:00 JavaScript: Correct arguments to h$appendToHsStringA fixes #23278 - - - - - ca611447 by Josh Meredith at 2023-05-04T15:00:07-04:00 base/encoding: add an allocations performance test (#22946) - - - - - e3ddf58d by Krzysztof Gogolewski at 2023-05-04T15:00:44-04:00 linear types: Don't add external names to the usage env This has no observable effect, but avoids storing useless data. - - - - - b3226616 by Andrei Borzenkov at 2023-05-04T15:01:25-04:00 Improved documentation for the Data.OldList.nub function There was recomentation to use map head . group . sort instead of nub function, but containers library has more suitable and efficient analogue - - - - - e8b72ff6 by Ryan Scott at 2023-05-04T15:02:02-04:00 Fix type variable substitution in gen_Newtype_fam_insts Previously, `gen_Newtype_fam_insts` was substituting the type variable binders of a type family instance using `substTyVars`, which failed to take type variable dependencies into account. There is similar code in `GHC.Tc.TyCl.Class.tcATDefault` that _does_ perform this substitution properly, so this patch: 1. Factors out this code into a top-level `substATBndrs` function, and 2. Uses `substATBndrs` in `gen_Newtype_fam_insts`. Fixes #23329. - - - - - 275836d2 by Torsten Schmits at 2023-05-05T08:43:02+00:00 Add structured error messages for GHC.Rename.Utils Tracking ticket: #20115 MR: !10350 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 983ce558 by Oleg Grenrus at 2023-05-05T13:11:29-04:00 Use TemplateHaskellQuotes in TH.Syntax to construct Names - - - - - a5174a59 by Matthew Pickering at 2023-05-05T18:42:31-04:00 driver: Use hooks from plugin_hsc_env This fixes a bug in oneshot mode where hooks modified in a plugin wouldn't be used in oneshot mode because we neglected to use the right hsc_env. This was observed by @csabahruska. - - - - - 18a7d03d by Aaron Allen at 2023-05-05T18:42:31-04:00 Rework plugin initialisation points In general this patch pushes plugin initialisation points to earlier in the pipeline. As plugins can modify the `HscEnv`, it's imperative that the plugins are initialised as soon as possible and used thereafter. For example, there are some new tests which modify hsc_logger and other hooks which failed to fire before (and now do) One consequence of this change is that the error for specifying the usage of a HPT plugin from the command line has changed, because it's now attempted to be loaded at initialisation rather than causing a cyclic module import. Closes #21279 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 6e776ed3 by Matthew Pickering at 2023-05-05T18:42:31-04:00 docs: Add Note [Timing of plugin initialization] - - - - - e1df8511 by Matthew Pickering at 2023-05-05T18:43:07-04:00 Incrementally update ghcup metadata in ghc/ghcup-metadata This job paves the way for distributing nightly builds * A new repo https://gitlab.haskell.org/ghc/ghcup-metadata stores the metadata on the "updates" branch. * Each night this metadata is downloaded and the nightly builds are appended to the end of the metadata. * The update job only runs on the scheduled nightly pipeline, not just when NIGHTLY=1. Things which are not done yet * Modify the retention policy for nightly jobs * Think about building release flavour compilers to distribute nightly. Fixes #23334 - - - - - 8f303d27 by Rodrigo Mesquita at 2023-05-05T22:04:31-04:00 docs: Remove mentions of ArrayArray# from unlifted FFI section Fixes #23277 - - - - - 994bda56 by Torsten Schmits at 2023-05-05T22:05:12-04:00 Add structured error messages for GHC.Rename.Module Tracking ticket: #20115 MR: !10361 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. Only addresses the single warning missing from the previous MR. - - - - - 3e3a6be4 by Ben Gamari at 2023-05-08T12:15:19+00:00 rts: Fix data-race in hs_init_ghc As noticed by @Terrorjack, `hs_init_ghc` previously used non-atomic increment/decrement on the RTS's initialization count. This may go wrong in a multithreaded program which initializes the runtime multiple times. Closes #22756. - - - - - 78c8dc50 by Torsten Schmits at 2023-05-08T21:41:51-04:00 Add structured error messages for GHC.IfaceToCore Tracking ticket: #20114 MR: !10390 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 0e2df4c9 by Bryan Richter at 2023-05-09T12:03:35+03:00 Fix up rules for ghcup-metadata-nightly-push - - - - - b970e64f by Ben Gamari at 2023-05-09T08:41:33-04:00 testsuite: Add test for atomicSwapIORef - - - - - 81cfefd2 by Ben Gamari at 2023-05-09T08:41:53-04:00 compiler: Implement atomicSwapIORef with xchg As requested by @treeowl in CLC#139. - - - - - 6b29154d by Ben Gamari at 2023-05-09T08:41:53-04:00 Make atomicSwapMutVar# an inline primop - - - - - 64064cfe by doyougnu at 2023-05-09T18:40:01-04:00 JS: add GHC.JS.Optimizer, remove RTS.Printer, add Linker.Opt This MR changes some simple optimizations and is a first step in re-architecting the JS backend pipeline to add the optimizer. In particular it: - removes simple peep hole optimizations from `GHC.StgToJS.Printer` and removes that module - adds module `GHC.JS.Optimizer` - defines the same peep hole opts that were removed only now they are `Syntax -> Syntax` transformations rather than `Syntax -> JS code` optimizations - hooks the optimizer into code gen - adds FuncStat and ForStat constructors to the backend. Working Ticket: - #22736 Related MRs: - MR !10142 - MR !10000 ------------------------- Metric Decrease: CoOpt_Read ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T12707 T13253 T13253-spj T15164 T17516 T18140 T18282 T18698a T18698b T18923 T1969 T19695 T20049 T3064 T5321FD T5321Fun T783 T9198 T9233 T9630 ------------------------- - - - - - 6738c01d by Krzysztof Gogolewski at 2023-05-09T18:40:38-04:00 Add a regression test for #21050 - - - - - b2cdb7da by Ben Gamari at 2023-05-09T18:41:14-04:00 nonmoving: Account for mutator allocations in bytes_allocated Previously we failed to account direct mutator allocations into the nonmoving heap against the mutator's allocation limit and `cap->total_allocated`. This only manifests during CAF evaluation (since we allocate the CAF's blackhole directly into the nonmoving heap). Fixes #23312. - - - - - 0657b482 by Sven Tennie at 2023-05-09T22:22:42-04:00 Adjust AArch64 stackFrameHeaderSize The prologue of each stack frame are the saved LR and FP registers, 8 byte each. I.e. the size of the stack frame header is 2 * 8 byte. - - - - - 7788c09c by konsumlamm at 2023-05-09T22:23:23-04:00 Make `(&)` representation polymorphic in the return type - - - - - b3195922 by Ben Gamari at 2023-05-10T05:06:45-04:00 ghc-prim: Generalize keepAlive#/touch# in state token type Closes #23163. - - - - - 1e6861dd by Cheng Shao at 2023-05-10T05:07:25-04:00 Bump hsc2hs submodule Fixes #22981. - - - - - 0a513952 by Ben Gamari at 2023-05-11T04:10:17-04:00 base: Export GHC.Conc.Sync.fromThreadId Closes #22706. - - - - - 29be39ba by Matthew Pickering at 2023-05-11T04:10:54-04:00 Build vanilla alpine bindists We currently attempt to build and distribute fully static alpine bindists (ones which could be used on any linux platform) but most people who use the alpine bindists want to use alpine to build their own static applications (for which a fully static bindist is not necessary). We should build and distribute these bindists for these users whilst the fully-static bindist is still unusable. Fixes #23349 - - - - - 40c7daed by Simon Peyton Jones at 2023-05-11T04:11:30-04:00 Look both ways when looking for quantified equalities When looking up (t1 ~# t2) in the quantified constraints, check both orientations. Forgetting this led to #23333. - - - - - c17bb82f by Rodrigo Mesquita at 2023-05-11T04:12:07-04:00 Move "target has RTS linker" out of settings We move the "target has RTS linker" information out of configure into a predicate in GHC, and remove this option from the settings file where it is unnecessary -- it's information statically known from the platform. Note that previously we would consider `powerpc`s and `s390x`s other than `powerpc-ibm-aix*` and `s390x-ibm-linux` to have an RTS linker, but the RTS linker supports neither platform. Closes #23361 - - - - - bd0b056e by Krzysztof Gogolewski at 2023-05-11T04:12:44-04:00 Add a test for #17284 Since !10123 we now reject this program. - - - - - 630b1fea by Andrew Lelechenko at 2023-05-11T04:13:24-04:00 Document unlawfulness of instance Num Fixed Fixes #22712 - - - - - 87eebf98 by sheaf at 2023-05-11T11:55:22-04:00 Add fused multiply-add instructions This patch adds eight new primops that fuse a multiplication and an addition or subtraction: - `{fmadd,fmsub,fnmadd,fnmsub}{Float,Double}#` fmadd x y z is x * y + z, computed with a single rounding step. This patch implements code generation for these primops in the following backends: - X86, AArch64 and PowerPC NCG, - LLVM - C WASM uses the C implementation. The primops are unsupported in the JavaScript backend. The following constant folding rules are also provided: - compute a * b + c when a, b, c are all literals, - x * y + 0 ==> x * y, - ±1 * y + z ==> z ± y and x * ±1 + z ==> z ± x. NB: the constant folding rules incorrectly handle signed zero. This is a known limitation with GHC's floating-point constant folding rules (#21227), which we hope to resolve in the future. - - - - - ad16a066 by Krzysztof Gogolewski at 2023-05-11T11:55:59-04:00 Add a test for #21278 - - - - - 05cea68c by Matthew Pickering at 2023-05-11T11:56:36-04:00 rts: Refine memory retention behaviour to account for pinned/compacted objects When using the copying collector there is still a lot of data which isn't copied (such as pinned, compacted, large objects etc). The logic to decide how much memory to retain didn't take into account that these wouldn't be copied. Therefore we pessimistically retained 2* the amount of memory for these blocks even though they wouldn't be copied by the collector. The solution is to split up the heap into two parts, the parts which will be copied and the parts which won't be copied. Then the appropiate factor is applied to each part individually (2 * for copying and 1.2 * for not copying). The T23221 test demonstrates this improvement with a program which first allocates many unpinned ByteArray# followed by many pinned ByteArray# and observes the difference in the ultimate memory baseline between the two. There are some charts on #23221. Fixes #23221 - - - - - 1bb24432 by Cheng Shao at 2023-05-11T11:57:15-04:00 hadrian: fix no_dynamic_libs flavour transformer This patch fixes the no_dynamic_libs flavour transformer and make fully_static reuse it. Previously building with no_dynamic_libs fails since ghc program is still dynamic and transitively brings in dyn ways of rts which are produced by no rules. - - - - - 0ed493a3 by Josh Meredith at 2023-05-11T23:08:27-04:00 JS: refactor jsSaturate to return a saturated JStat (#23328) - - - - - a856d98e by Pierre Le Marre at 2023-05-11T23:09:08-04:00 Doc: Fix out-of-sync using-optimisation page - Make explicit that default flag values correspond to their -O0 value. - Fix -fignore-interface-pragmas, -fstg-cse, -fdo-eta-reduction, -fcross-module-specialise, -fsolve-constant-dicts, -fworker-wrapper. - - - - - c176ad18 by sheaf at 2023-05-12T06:10:57-04:00 Don't panic in mkNewTyConRhs This function could come across invalid newtype constructors, as we only perform validity checking of newtypes once we are outside the knot-tied typechecking loop. This patch changes this function to fake up a stub type in the case of an invalid newtype, instead of panicking. This patch also changes "checkNewDataCon" so that it reports as many errors as possible at once. Fixes #23308 - - - - - ab63daac by Krzysztof Gogolewski at 2023-05-12T06:11:38-04:00 Allow Core optimizations when interpreting bytecode Tracking ticket: #23056 MR: !10399 This adds the flag `-funoptimized-core-for-interpreter`, permitting use of the `-O` flag to enable optimizations when compiling with the interpreter backend, like in ghci. - - - - - c6cf9433 by Ben Gamari at 2023-05-12T06:12:14-04:00 hadrian: Fix mention of non-existent removeFiles function Previously Hadrian's bindist Makefile referred to a `removeFiles` function that was previously defined by the `make` build system. Since the `make` build system is no longer around, this function is now undefined. Naturally, make being make, this appears to be silently ignored instead of producing an error. Fix this by rewriting it to `rm -f`. Closes #23373. - - - - - eb60ec18 by Andrew Lelechenko at 2023-05-12T06:12:54-04:00 Mention new implementation of GHC.IORef.atomicSwapIORef in the changelog - - - - - aa84cff4 by Teo Camarasu at 2023-05-12T19:27:23-04:00 rts: Ensure non-moving gc is not running when pausing - - - - - 5ad776ab by Teo Camarasu at 2023-05-12T19:27:23-04:00 rts: Teach listAllBlocks about nonmoving heap List all blocks on the non-moving heap. Resolves #22627 - - - - - d683b2e5 by Krzysztof Gogolewski at 2023-05-12T19:28:00-04:00 Fix coercion optimisation for SelCo (#23362) setNominalRole_maybe is supposed to output a nominal coercion. In the SelCo case, it was not updating the stored role to Nominal, causing #23362. - - - - - 59aa4676 by Alexis King at 2023-05-12T19:28:47-04:00 hadrian: Fix linker script flag for MergeObjects builder This fixes what appears to have been a typo in !9530. The `-t` flag just enables tracing on all versions of `ld` I’ve looked at, while `-T` is used to specify a linker script. It seems that this worked anyway for some reason on some `ld` implementations (perhaps because they automatically detect linker scripts), but the missing `-T` argument causes `gold` to complain. - - - - - 4bf9fa0f by Adam Gundry at 2023-05-12T23:49:49-04:00 Less coercion optimization for non-newtype axioms See Note [Push transitivity inside newtype axioms only] for an explanation of the change here. This change substantially improves the performance of coercion optimization for programs involving transitive type family reductions. ------------------------- Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12545 T13386 T15703 T5030 T8095 ------------------------- - - - - - dc0c9574 by Adam Gundry at 2023-05-12T23:49:49-04:00 Move checkAxInstCo to GHC.Core.Lint A consequence of the previous change is that checkAxInstCo is no longer called during coercion optimization, so it can be moved back where it belongs. Also includes some edits to Note [Conflict checking with AxiomInstCo] as suggested by @simonpj. - - - - - 8b9b7dbc by Simon Peyton Jones at 2023-05-12T23:50:25-04:00 Use the eager unifier in the constraint solver This patch continues the refactoring of the constraint solver described in #23070. The Big Deal in this patch is to call the regular, eager unifier from the constraint solver, when we want to create new equalities. This replaces the existing, unifyWanted which amounted to yet-another-unifier, so it reduces duplication of a rather subtle piece of technology. See * Note [The eager unifier] in GHC.Tc.Utils.Unify * GHC.Tc.Solver.Monad.wrapUnifierTcS I did lots of other refactoring along the way * I simplified the treatment of right hand sides that contain CoercionHoles. Now, a constraint that contains a hetero-kind CoercionHole is non-canonical, and cannot be used for rewriting or unification alike. This required me to add the ch_hertero_kind flag to CoercionHole, with consequent knock-on effects. See wrinkle (2) of `Note [Equalities with incompatible kinds]` in GHC.Tc.Solver.Equality. * I refactored the StopOrContinue type to add StartAgain, so that after a fundep improvement (for example) we can simply start the pipeline again. * I got rid of the unpleasant (and inefficient) rewriterSetFromType/Co functions. With Richard I concluded that they are never needed. * I discovered Wrinkle (W1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint, and therefore now prioritise non-rewritten equalities. Quite a few error messages change, I think always for the better. Compiler runtime stays about the same, with one outlier: a 17% improvement in T17836 Metric Decrease: T17836 T18223 - - - - - 5cad28e7 by Bartłomiej Cieślar at 2023-05-12T23:51:06-04:00 Cleanup of dynflags override in export renaming The deprecation warnings are normally emitted whenever the name's GRE is being looked up, which calls the GHC.Rename.Env.addUsedGRE function. We do not want those warnings to be emitted when renaming export lists, so they are artificially turned off by removing all warning categories from DynFlags at the beginning of GHC.Tc.Gen.Export.rnExports. This commit removes that dependency by unifying the function used for GRE lookup in lookup_ie to lookupGreAvailRn and disabling the call to addUsedGRE in said function (the warnings are also disabled in a call to lookupSubBndrOcc_helper in lookupChildrenExport), as per #17957. This commit also changes the setting for whether to warn about deprecated names in addUsedGREs to be an explicit enum instead of a boolean. - - - - - d85ed900 by Alexis King at 2023-05-13T08:45:18-04:00 Use a uniform return convention in bytecode for unary results fixes #22958 - - - - - 8a0d45f7 by Andrew Lelechenko at 2023-05-13T08:45:58-04:00 Add more instances for Compose: Enum, Bounded, Num, Real, Integral See https://github.com/haskell/core-libraries-committee/issues/160 for discussion - - - - - 902f0730 by Simon Peyton Jones at 2023-05-13T14:58:34-04:00 Make GHC.Types.Id.Make.shouldUnpackTy a bit more clever As #23307, GHC.Types.Id.Make.shouldUnpackTy was leaving money on the table, failing to unpack arguments that are perfectly unpackable. The fix is pretty easy; see Note [Recursive unboxing] - - - - - a5451438 by sheaf at 2023-05-13T14:59:13-04:00 Fix bad multiplicity role in tyConAppFunCo_maybe The function tyConAppFunCo_maybe produces a multiplicity coercion for the multiplicity argument of the function arrow, except that it could be at the wrong role if asked to produce a representational coercion. We fix this by using the 'funRole' function, which computes the right roles for arguments to the function arrow TyCon. Fixes #23386 - - - - - 5b9e9300 by sheaf at 2023-05-15T11:26:59-04:00 Turn "ambiguous import" error into a panic This error should never occur, as a lookup of a type or data constructor should never be ambiguous. This is because a single module cannot export multiple Names with the same OccName, as per item (1) of Note [Exporting duplicate declarations] in GHC.Tc.Gen.Export. This code path was intended to handle duplicate record fields, but the rest of the code had since been refactored to handle those in a different way. We also remove the AmbiguousImport constructor of IELookupError, as it is no longer used. Fixes #23302 - - - - - e305e60c by M Farkas-Dyck at 2023-05-15T11:27:41-04:00 Unbreak some tests with latest GNU grep, which now warns about stray '\'. Confusingly, the testsuite mangled the error to say "stray /". We also migrate some tests from grep to grep -E, as it seems the author actually wanted an "POSIX extended" (a.k.a. sane) regex. Background: POSIX specifies 2 "regex" syntaxen: "basic" and "extended". Of these, only "extended" syntax is actually a regular expression. Furthermore, "basic" syntax is inconsistent in its use of the '\' character — sometimes it escapes a regex metacharacter, but sometimes it unescapes it, i.e. it makes an otherwise normal character become a metacharacter. This baffles me and it seems also the authors of these tests. Also, the regex(7) man page (at least on Linux) says "basic" syntax is obsolete. Nearly all modern tools and libraries are consistent in this use of the '\' character (of which many use "extended" syntax by default). - - - - - 5ae81842 by sheaf at 2023-05-15T14:49:17-04:00 Improve "ambiguous occurrence" error messages This error was sometimes a bit confusing, especially when data families were involved. This commit improves the general presentation of the "ambiguous occurrence" error, and adds a bit of extra context in the case of data families. Fixes #23301 - - - - - 2f571afe by Sylvain Henry at 2023-05-15T14:50:07-04:00 Fix GHCJS OS platform (fix #23346) - - - - - 86aae570 by Oleg Grenrus at 2023-05-15T14:50:43-04:00 Split DynFlags structure into own module This will allow to make command line parsing to depend on diagnostic system (which depends on dynflags) - - - - - fbe3fe00 by Josh Meredith at 2023-05-15T18:01:43-04:00 Replace the implementation of CodeBuffers with unboxed types - - - - - 21f3aae7 by Josh Meredith at 2023-05-15T18:01:43-04:00 Use unboxed codebuffers in base Metric Decrease: encodingAllocations - - - - - 18ea2295 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Weak pointer cleanups Various stylistic cleanups. No functional changes. - - - - - c343112f by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Don't force debug output to stderr Previously `+RTS -Dw -l` would emit debug output to the eventlog while `+RTS -l -Dw` would emit it to stderr. This was because the parser for `-D` would unconditionally override the debug output target. Now we instead only do so if no it is currently `TRACE_NONE`. - - - - - a5f5f067 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Forcibly flush eventlog on barf Previously we would attempt to flush via `endEventLogging` which can easily deadlock, e.g., if `barf` fails during GC. Using `flushEventLog` directly may result in slightly less consistent eventlog output (since we don't take all capabilities before flushing) but avoids deadlocking. - - - - - 73b1e87c by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Assert that pointers aren't cleared by -DZ This turns many segmentation faults into much easier-to-debug assertion failures by ensuring that LOOKS_LIKE_*_PTR checks recognize bit-patterns produced by `+RTS -DZ` clearing as invalid pointers. This is a bit ad-hoc but this is the debug runtime. - - - - - 37fb61d8 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Introduce printGlobalThreads - - - - - 451d65a6 by Ben Gamari at 2023-05-15T18:02:20-04:00 rts: Don't sanity-check StgTSO.global_link See Note [Avoid dangling global_link pointers]. Fixes #19146. - - - - - d69cbd78 by sheaf at 2023-05-15T18:03:00-04:00 Split up tyThingToIfaceDecl from GHC.Iface.Make This commit moves tyThingToIfaceDecl and coAxiomToIfaceDecl from GHC.Iface.Make into GHC.Iface.Decl. This avoids GHC.Types.TyThing.Ppr, which needs tyThingToIfaceDecl, transitively depending on e.g. GHC.Iface.Load and GHC.Tc.Utils.Monad. - - - - - 4d29ecdf by sheaf at 2023-05-15T18:03:00-04:00 Migrate errors to diagnostics in GHC.Tc.Module This commit migrates the errors in GHC.Tc.Module to use the new diagnostic infrastructure. It required a significant overhaul of the compatibility checks between an hs-boot or signature module and its implementation; we now use a Writer monad to accumulate errors; see the BootMismatch datatype in GHC.Tc.Errors.Types, with its panoply of subtypes. For the sake of readability, several local functions inside the 'checkBootTyCon' function were split off into top-level functions. We split off GHC.Types.HscSource into a "boot or sig" vs "normal hs file" datatype, as this mirrors the logic in several other places where we want to treat hs-boot and hsig files in a similar fashion. This commit also refactors the Backpack checks for type synonyms implementing abstract data, to correctly reject implementations that contain qualified or quantified types (this fixes #23342 and #23344). - - - - - d986c98e by Rodrigo Mesquita at 2023-05-16T00:14:04-04:00 configure: Drop unused AC_PROG_CPP In configure, we were calling `AC_PROG_CPP` but never making use of the $CPP variable it sets or reads. The issue is $CPP will show up in the --help output of configure, falsely advertising a configuration option that does nothing. The reason we don't use the $CPP variable is because HS_CPP_CMD is expected to be a single command (without flags), but AC_PROG_CPP, when CPP is unset, will set said variable to something like `/usr/bin/gcc -E`. Instead, we configure HS_CPP_CMD through $CC. - - - - - a8f0435f by Cheng Shao at 2023-05-16T00:14:42-04:00 rts: fix --disable-large-address-space This patch moves ACQUIRE_ALLOC_BLOCK_SPIN_LOCK/RELEASE_ALLOC_BLOCK_SPIN_LOCK from Storage.h to HeapAlloc.h. When --disable-large-address-space is passed to configure, the code in HeapAlloc.h makes use of these two macros. Fixes #23385. - - - - - bdb93cd2 by Oleg Grenrus at 2023-05-16T07:59:21+03:00 Add -Wmissing-role-annotations Implements #22702 - - - - - 41ecfc34 by Ben Gamari at 2023-05-16T07:28:15-04:00 base: Export {get,set}ExceptionFinalizer from System.Mem.Weak As proposed in CLC Proposal #126 [1]. [1]: https://github.com/haskell/core-libraries-committee/issues/126 - - - - - 67330303 by Ben Gamari at 2023-05-16T07:28:16-04:00 base: Introduce printToHandleFinalizerExceptionHandler - - - - - 5e3f9bb5 by Josh Meredith at 2023-05-16T13:59:22-04:00 JS: Implement h$clock_gettime in the JavaScript RTS (#23360) - - - - - 90e69d5d by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation for SourceText SourceText is serialized along with INLINE pragmas into interface files. Many of these SourceTexts are identical, for example "{-# INLINE#". When deserialized, each such SourceText was previously expanded out into a [Char], which is highly wasteful of memory, and each such instance of the text would allocate an independent list with its contents as deserializing breaks any sharing that might have existed. Instead, we use a `FastString` to represent these, so that each instance unique text will be interned and stored in a memory efficient manner. - - - - - b70bc690 by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation/FastStrings for `SourceNote`s `SourceNote`s should not be stored as [Char] as this is highly wasteful and in certain scenarios can be highly duplicated. Metric Decrease: hard_hole_fits - - - - - 6231a126 by Zubin Duggal at 2023-05-16T14:00:00-04:00 compiler: Use compact representation for UsageFile (#22744) Use FastString to store filepaths in interface files, as this data is highly redundant so we want to share all instances of filepaths in the compiler session. - - - - - 47a58150 by Zubin Duggal at 2023-05-16T14:00:00-04:00 testsuite: add test for T22744 This test checks for #22744 by compiling 100 modules which each have a dependency on 1000 distinct external files. Previously, when loading these interfaces from disk, each individual instance of a filepath in the interface will would be allocated as an individual object on the heap, meaning we have heap objects for 100*1000 files, when there are only 1000 distinct files we care about. This test checks this by first compiling the module normally, then measuring the peak memory usage in a no-op recompile, as the recompilation checking will force the allocation of all these filepaths. - - - - - 0451bdc9 by Ben Gamari at 2023-05-16T21:31:40-04:00 users guide: Add glossary Currently this merely explains the meaning of "technology preview" in the context of released features. - - - - - 0ba52e4e by Ben Gamari at 2023-05-16T21:31:40-04:00 Update glossary.rst - - - - - 3d23060c by Ben Gamari at 2023-05-16T21:31:40-04:00 Use glossary directive - - - - - 2972fd66 by Sylvain Henry at 2023-05-16T21:32:20-04:00 JS: fix getpid (fix #23399) - - - - - 5fe1d3e6 by Matthew Pickering at 2023-05-17T21:42:00-04:00 Use setSrcSpan rather than setLclEnv in solveForAll In subsequent MRs (#23409) we want to remove the TcLclEnv argument from a CtLoc. This MR prepares us for that by removing the one place where the entire TcLclEnv is used, by using it more precisely to just set the contexts source location. Fixes #23390 - - - - - 385edb65 by Torsten Schmits at 2023-05-17T21:42:40-04:00 Update the users guide paragraph on -O in GHCi In relation to #23056 - - - - - 87626ef0 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Add test for #13660 - - - - - 9eef53b1 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Move implementation of GHC.Foreign to GHC.Internal - - - - - 174ea2fa by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Introduce {new,with}CStringLen0 These are useful helpers for implementing the internal-NUL code unit check needed to fix #13660. - - - - - a46ced16 by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Clean up documentation - - - - - b98d99cc by Ben Gamari at 2023-05-18T15:18:53-04:00 base: Ensure that FilePaths don't contain NULs POSIX filepaths may not contain the NUL octet but previously we did not reject such paths. This could be exploited by untrusted input to cause discrepancies between various `FilePath` queries and the opened filename. For instance, `readFile "hello.so\x00.txt"` would open the file `"hello.so"` yet `takeFileExtension` would return `".txt"`. The same argument applies to Windows FilePaths Fixes #13660. - - - - - 7ae45459 by Simon Peyton Jones at 2023-05-18T15:19:29-04:00 Allow the demand analyser to unpack tuple and equality dictionaries Addresses #23398. The demand analyser usually does not unpack class dictionaries: see Note [Do not unbox class dictionaries] in GHC.Core.Opt.DmdAnal. This patch makes an exception for tuple dictionaries and equality dictionaries, for reasons explained in wrinkles (DNB1) and (DNB2) of the above Note. Compile times fall by 0.1% for some reason (max 0.7% on T18698b). - - - - - b53a9086 by Greg Steuck at 2023-05-18T15:20:08-04:00 Use a simpler and more portable construct in ld.ldd check printf '%q\n' is a bash extension which led to incorrectly failing an ld.lld test on OpenBSD which uses pdksh as /bin/sh - - - - - dd5710af by Torsten Schmits at 2023-05-18T15:20:50-04:00 Update the warning about interpreter optimizations to reflect that they're not incompatible anymore, but guarded by a flag - - - - - 4f6dd999 by Matthew Pickering at 2023-05-18T15:21:26-04:00 Remove stray dump flags in GHC.Rename.Names - - - - - 4bca0486 by Oleg Grenrus at 2023-05-19T11:51:33+03:00 Make Warn = Located DriverMessage This change makes command line argument parsing use diagnostic framework for producing warnings. - - - - - 525ed554 by Simon Peyton Jones at 2023-05-19T10:09:15-04:00 Type inference for data family newtype instances This patch addresses #23408, a tricky case with data family newtype instances. Consider type family TF a where TF Char = Bool data family DF a newtype instance DF Bool = MkDF Int and [W] Int ~R# DF (TF a), with a Given (a ~# Char). We must fully rewrite the Wanted so the tpye family can fire; that wasn't happening. - - - - - c6fb6690 by Peter Trommler at 2023-05-20T03:16:08-04:00 testsuite: fix predicate on rdynamic test Test rdynamic requires dynamic linking support, which is orthogonal to RTS linker support. Change the predicate accordingly. Fixes #23316 - - - - - 735d504e by Matthew Pickering at 2023-05-20T03:16:44-04:00 docs: Use ghc-ticket directive where appropiate in users guide Using the directive automatically formats and links the ticket appropiately. - - - - - b56d7379 by Sylvain Henry at 2023-05-22T14:21:22-04:00 NCG: remove useless .align directive (#20758) - - - - - 15b93d2f by Simon Peyton Jones at 2023-05-22T14:21:58-04:00 Add test for #23156 This program had exponential typechecking time in GHC 9.4 and 9.6 - - - - - 2b53f206 by Greg Steuck at 2023-05-22T20:23:11-04:00 Revert "Change hostSupportsRPaths to report False on OpenBSD" This reverts commit 1e0d8fdb55a38ece34fa6cf214e1d2d46f5f5bf2. - - - - - 882e43b7 by Greg Steuck at 2023-05-22T20:23:11-04:00 Disable T17414 on OpenBSD Like on other systems it's not guaranteed that there's sufficient space in /tmp to write 2G out. - - - - - 9d531f9a by Greg Steuck at 2023-05-22T20:23:11-04:00 Bring back getExecutablePath to getBaseDir on OpenBSD Fix #18173 - - - - - 9db0eadd by Krzysztof Gogolewski at 2023-05-22T20:23:47-04:00 Add an error origin for impedance matching (#23427) - - - - - 33cf4659 by Ben Gamari at 2023-05-23T03:46:20-04:00 testsuite: Add tests for #23146 Both lifted and unlifted variants. - - - - - 76727617 by Ben Gamari at 2023-05-23T03:46:21-04:00 codeGen: Fix some Haddocks - - - - - 33a8c348 by Ben Gamari at 2023-05-23T03:46:21-04:00 codeGen: Give proper LFInfo to datacon wrappers As noted in `Note [Conveying CAF-info and LFInfo between modules]`, when importing a binding from another module we must ensure that it gets the appropriate `LambdaFormInfo` if it is in WHNF to ensure that references to it are tagged correctly. However, the implementation responsible for doing this, `GHC.StgToCmm.Closure.mkLFImported`, only dealt with datacon workers and not wrappers. This lead to the crash of this program in #23146: module B where type NP :: [UnliftedType] -> UnliftedType data NP xs where UNil :: NP '[] module A where import B fieldsSam :: NP xs -> NP xs -> Bool fieldsSam UNil UNil = True x = fieldsSam UNil UNil Due to its GADT nature, `UNil` produces a trivial wrapper $WUNil :: NP '[] $WUNil = UNil @'[] @~(<co:1>) which is referenced in the RHS of `A.x`. Due to the above-mentioned bug in `mkLFImported`, the references to `$WUNil` passed to `fieldsSam` were not tagged. This is problematic as `fieldsSam` expected its arguments to be tagged as they are unlifted. The fix is straightforward: extend the logic in `mkLFImported` to cover (nullary) datacon wrappers as well as workers. This is safe because we know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). Thanks to @MangoIV for the great ticket and @alt-romes for his minimization and help debugging. Fixes #23146. - - - - - 2fc18e9e by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 0598f7f0 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 12294b22 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Update Note [Core letrec invariant] Authored by @simonpj - - - - - e93ab972 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Rename mkLFImported to importedIdLFInfo The `mkLFImported` sounded too much like a constructor of sorts, when really it got the `LFInfo` of an imported Id from its `lf_info` field when this existed, and otherwise returned a conservative estimate of that imported Id's LFInfo. This in contrast to functions such as `mkLFReEntrant` which really are about constructing an `LFInfo`. - - - - - e54d9259 by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Enforce invariant on typePrimRepArgs in the types As part of the documentation effort in !10165 I came across this invariant on 'typePrimRepArgs' which is easily expressed at the type-level through a NonEmpty list. It allowed us to remove one panic. - - - - - b8fe6a0c by Rodrigo Mesquita at 2023-05-23T03:46:21-04:00 Merge outdated Note [Data con representation] into Note [Data constructor representation] Introduce new Note [Constructor applications in STG] to better support the merge, and reference it from the relevant bits in the STG syntax. - - - - - e1590ddc by Simon Peyton Jones at 2023-05-23T03:46:57-04:00 Add the SolverStage monad This refactoring makes a substantial improvement in the structure of the type-checker's constraint solver: #23070. Specifically: * Introduced the SolverStage monad. See GHC.Tc.Solver.Monad Note [The SolverStage monad] * Make each solver pipeline (equalities, dictionaries, irreds etc) deal with updating the inert set, as a separate SolverStage. There is sometimes special stuff to do, and it means that each full pipeline can have type SolverStage Void, indicating that they never return anything. * Made GHC.Tc.Solver.Equality.zonkEqTypes into a SolverStage. Much nicer. * Combined the remnants of GHC.Tc.Solver.Canonical and GHC.Tc.Solver.Interact into a new module GHC.Tc.Solver.Solve. (Interact and Canonical are removed.) * Gave the same treatment to dictionary and irred constraints as I have already done for equality constraints: * New types (akin to EqCt): IrredCt and DictCt * Ct is now just a simple sum type data Ct = CDictCan DictCt | CIrredCan IrredCt | CEqCan EqCt | CQuantCan QCInst | CNonCanonical CtEvidence * inert_dicts can now have the better type DictMap DictCt, instead of DictMap Ct; and similarly inert_irreds. * Significantly simplified the treatment of implicit parameters. Previously we had a number of special cases * interactGivenIP, an entire function * special case in maybeKickOut * special case in findDict, when looking up dictionaries But actually it's simpler than that. When adding a new Given, implicit parameter constraint to the InertSet, we just need to kick out any existing inert constraints that mention that implicit parameter. The main work is done in GHC.Tc.Solver.InertSet.delIPDict, along with its auxiliary GHC.Core.Predicate.mentionsIP. See Note [Shadowing of implicit parameters] in GHC.Tc.Solver.Dict. * Add a new fast-path in GHC.Tc.Errors.Hole.tcCheckHoleFit. See Note [Fast path for tcCheckHoleFit]. This is a big win in some cases: test hard_hole_fits gets nearly 40% faster (at compile time). * Add a new fast-path for solving /boxed/ equality constraints (t1 ~ t2). See Note [Solving equality classes] in GHC.Tc.Solver.Dict. This makes a big difference too: test T17836 compiles 40% faster. * Implement the PermissivePlan of #23413, which concerns what happens with insoluble Givens. Our previous treatment was wildly inconsistent as that ticket pointed out. A part of this, I simplified GHC.Tc.Validity.checkAmbiguity: now we simply don't run the ambiguity check at all if -XAllowAmbiguousTypes is on. Smaller points: * In `GHC.Tc.Errors.misMatchOrCND` instead of having a special case for insoluble /occurs/ checks, broaden in to all insouluble constraints. Just generally better. See Note [Insoluble mis-match] in that module. As noted above, compile time perf gets better. Here are the changes over 0.5% on Fedora. (The figures are slightly larger on Windows for some reason.) Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -0.9% MultiLayerModulesTH_OneShot(normal) +0.5% T11822(normal) -0.6% T12227(normal) -1.8% GOOD T12545(normal) -0.5% T13035(normal) -0.6% T15703(normal) -1.4% GOOD T16875(normal) -0.5% T17836(normal) -40.7% GOOD T17836b(normal) -12.3% GOOD T17977b(normal) -0.5% T5837(normal) -1.1% T8095(normal) -2.7% GOOD T9020(optasm) -1.1% hard_hole_fits(normal) -37.0% GOOD geo. mean -1.3% minimum -40.7% maximum +0.5% Metric Decrease: T12227 T15703 T17836 T17836b T8095 hard_hole_fits LargeRecord T9198 T13035 - - - - - 6abf3648 by Simon Peyton Jones at 2023-05-23T03:46:57-04:00 Avoid an assertion failure in abstractFloats The function GHC.Core.Opt.Simplify.Utils.abstractFloats was carelessly calling lookupIdSubst_maybe on a CoVar; but a precondition of the latter is being given an Id. In fact it's harmless to call it on a CoVar, but still, the precondition on lookupIdSubst_maybe makes sense, so I added a test for CoVars. This avoids a crash in a DEBUG compiler, but otherwise has no effect. Fixes #23426. - - - - - 838aaf4b by hainq at 2023-05-24T12:41:19-04:00 Migrate errors in GHC.Tc.Validity This patch migrates the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It adds the constructors: - TcRnSimplifiableConstraint - TcRnArityMismatch - TcRnIllegalInstanceDecl, with sub-datatypes for HasField errors and fundep coverage condition errors. - - - - - 8539764b by Krzysztof Gogolewski at 2023-05-24T12:41:56-04:00 linear lint: Add missing processing of DEFAULT In this correct program f :: a %1 -> a f x = case x of x { _DEFAULT -> x } after checking the alternative we weren't popping the case binder 'x' from the usage environment, which meant that the lambda-bound 'x' was counted twice: in the scrutinee and (incorrectly) in the alternative. In fact, we weren't checking the usage of 'x' at all. Now the code for handling _DEFAULT is similar to the one handling data constructors. Fixes #23025. - - - - - ae683454 by Matthew Pickering at 2023-05-24T12:42:32-04:00 Remove outdated "Don't check hs-boot type family instances too early" note This note was introduced in 25b70a29f623 which delayed performing some consistency checks for type families. However, the change was reverted later in 6998772043a7f0b0360116eb5ffcbaa5630b21fb but the note was not removed. I found it confusing when reading to code to try and work out what special behaviour there was for hs-boot files (when in-fact there isn't any). - - - - - 44af57de by Matthew Pickering at 2023-05-24T12:43:08-04:00 rts: Define ticky macro stubs These macros have long been undefined which has meant we were missing reporting these allocations in ticky profiles. The most critical missing definition was TICK_ALLOC_HEAP_NOCTR which was missing all the RTS calls to allocate, this leads to a the overall ALLOC_RTS_tot number to be severaly underreported. Of particular interest though is the ALLOC_STACK_ctr and ALLOC_STACK_tot counters which are useful to tracking stack allocations. Fixes #23421 - - - - - b2dabe3a by Matthew Pickering at 2023-05-24T12:43:08-04:00 rts: ticky: Rename TICK_ALLOC_HEAP_NOCTR to TICK_ALLOC_RTS This macro increments the ALLOC_HEAP_tot and ALLOC_HEAP_ctr so it makes more sense to name it after that rather than the suffix NOCTR, whose meaning has been lost to the mists of time. - - - - - eac4420a by Ben Gamari at 2023-05-24T12:43:45-04:00 users guide: A few small mark-up fixes - - - - - a320ca76 by Rodrigo Mesquita at 2023-05-24T12:44:20-04:00 configure: Fix support check for response files. In failing to escape the '-o' in '-o\nconftest\nconftest.o\n' argument to printf, the writing of the arguments response file always failed. The fix is to pass the arguments after `--` so that they are treated positional arguments rather than flags to printf. Closes #23435 - - - - - f21ce0e4 by mangoiv at 2023-05-24T12:45:00-04:00 [feat] add .direnv to the .gitignore file - - - - - 36d5944d by Andrew Lelechenko at 2023-05-24T20:58:34-04:00 Add Data.List.unsnoc See https://github.com/haskell/core-libraries-committee/issues/165 for discussion - - - - - c0f2f9e3 by Bartłomiej Cieślar at 2023-05-24T20:59:14-04:00 Fix crash in backpack signature merging with -ddump-rn-trace In some cases, backpack signature merging could crash in addUsedGRE when -ddump-rn-trace was enabled, as pretty-printing the GREInfo would cause unavailable interfaces to be loaded. This commit fixes that issue by not pretty-printing the GREInfo in addUsedGRE when -ddump-rn-trace is enabled. Fixes #23424 Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - 5a07d94a by Krzysztof Gogolewski at 2023-05-25T03:30:20-04:00 Add a regression test for #13981 The panic was fixed by 6998772043a7f0b. Fixes #13981. - - - - - 182df90e by Krzysztof Gogolewski at 2023-05-25T03:30:57-04:00 Add a test for #23355 It was fixed by !10061, so I'm adding it in the same group. - - - - - 1b31b039 by uhbif19 at 2023-05-25T12:08:28+02:00 Migrate errors in GHC.Rename.Splice GHC.Rename.Pat This commit migrates the errors in GHC.Rename.Splice and GHC.Rename.Pat to use the new diagnostic infrastructure. - - - - - 56abe494 by sheaf at 2023-05-25T12:09:55+02:00 Common up Template Haskell errors in TcRnMessage This commit commons up the various Template Haskell errors into a single constructor, TcRnTHError, of TcRnMessage. - - - - - a487ba9e by Krzysztof Gogolewski at 2023-05-25T14:35:56-04:00 Enable ghci tests for unboxed tuples The tests were originally skipped because ghci used not to support unboxed tuples/sums. - - - - - dc3422d4 by Matthew Pickering at 2023-05-25T18:57:19-04:00 rts: Build ticky GHC with single-threaded RTS The threaded RTS allows you to use ticky profiling but only for the counters in the generated code. The counters used in the C portion of the RTS are disabled. Updating the counters is also racy using the threaded RTS which can lead to misleading or incorrect ticky results. Therefore we change the hadrian flavour to build using the single-threaded RTS (mainly in order to get accurate C code counter increments) Fixes #23430 - - - - - fbc8e04e by sheaf at 2023-05-25T18:58:00-04:00 Propagate long-distance info in generated code When desugaring generated pattern matches, we skip pattern match checks. However, this ended up also discarding long-distance information, which might be needed for user-written sub-expressions. Example: ```haskell okay (GADT di) cd = let sr_field :: () sr_field = case getFooBar di of { Foo -> () } in case cd of { SomeRec _ -> SomeRec sr_field } ``` With sr_field a generated FunBind, we still want to propagate the outer long-distance information from the GADT pattern match into the checks for the user-written RHS of sr_field. Fixes #23445 - - - - - f8ced241 by Matthew Pickering at 2023-05-26T15:26:21-04:00 Introduce GHCiMessage to wrap GhcMessage By introducing a wrapped message type we can control how certain messages are printed in GHCi (to add extra information for example) - - - - - 58e554c1 by Matthew Pickering at 2023-05-26T15:26:22-04:00 Generalise UnknownDiagnostic to allow embedded diagnostics to access parent diagnostic options. * Split default diagnostic options from Diagnostic class into HasDefaultDiagnosticOpts class. * Generalise UnknownDiagnostic to allow embedded diagnostics to access options. The principle idea here is that when wrapping an error message (such as GHCMessage to make GHCiMessage) then we need to also be able to lift the configuration when overriding how messages are printed (see load' for an example). - - - - - b112546a by Matthew Pickering at 2023-05-26T15:26:22-04:00 Allow API users to wrap error messages created during 'load' This allows API users to configure how messages are rendered when they are emitted from the load function. For an example see how 'loadWithCache' is used in GHCi. - - - - - 2e4cf0ee by Matthew Pickering at 2023-05-26T15:26:22-04:00 Abstract cantFindError and turn Opt_BuildingCabal into a print-time option * cantFindError is abstracted so that the parts which mention specific things about ghc/ghci are parameters. The intention being that GHC/GHCi can specify the right values to put here but otherwise display the same error message. * The BuildingCabalPackage argument from GenericMissing is removed and turned into a print-time option. The reason for the error is not dependent on whether `-fbuilding-cabal-package` is passed, so we don't want to store that in the error message. - - - - - 34b44f7d by Matthew Pickering at 2023-05-26T15:26:22-04:00 error messages: Don't display ghci specific hints for missing packages Tickets like #22884 suggest that it is confusing that GHC used on the command line can suggest options which only work in GHCi. This ticket uses the error message infrastructure to override certain error messages which displayed GHCi specific information so that this information is only showed when using GHCi. The main annoyance is that we mostly want to display errors in the same way as before, but with some additional information. This means that the error rendering code has to be exported from the Iface/Errors/Ppr.hs module. I am unsure about whether the approach taken here is the best or most maintainable solution. Fixes #22884 - - - - - 05a1b626 by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Don't override existing metadata if version already exists. If a nightly pipeline runs twice for some reason for the same version then we really don't want to override an existing entry with new bindists. This could cause ABI compatability issues for users or break ghcup's caching logic. - - - - - fcbcb3cc by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Use proper API url for bindist download Previously we were using links from the web interface, but it's more robust and future-proof to use the documented links to the artifacts. https://docs.gitlab.com/ee/api/job_artifacts.html - - - - - 5b59c8fe by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Set Nightly and LatestNightly tags The latest nightly release needs the LatestNightly tag, and all other nightly releases need the Nightly tag. Therefore when the metadata is updated we need to replace all LatestNightly with Nightly.` - - - - - 914e1468 by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Download nightly metadata for correct date The metadata now lives in https://gitlab.haskell.org/ghc/ghcup-metadata with one metadata file per year. When we update the metadata we download and update the right file for the current year. - - - - - 16cf7d2e by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Download metadata and update for correct year something about pipeline date - - - - - 14792c4b by Matthew Pickering at 2023-05-26T15:26:58-04:00 ghcup-metadata: Don't skip CI On a push we now have a CI job which updates gitlab pages with the metadata files. - - - - - 1121bdd8 by Matthew Pickering at 2023-05-26T15:26:59-04:00 ghcup-metadata: Add --date flag to specify the release date The ghcup-metadata now has a viReleaseDay field which needs to be populated with the day of the release. - - - - - bc478bee by Matthew Pickering at 2023-05-26T15:26:59-04:00 ghcup-metadata: Add dlOutput field ghcup now requires us to add this field which specifies where it should download the bindist to. See https://gitlab.haskell.org/ghc/ghcup-metadata/-/issues/1 for some more discussion. - - - - - 2bdbd9da by Josh Meredith at 2023-05-26T15:27:35-04:00 JS: Convert rendering to use HLine instead of SDoc (#22455) - - - - - abd9e37c by Norman Ramsey at 2023-05-26T15:28:12-04:00 testsuite: add WasmControlFlow test This patch adds the WasmControlFlow test to test the wasm backend's relooper component. - - - - - 07f858eb by Sylvain Henry at 2023-05-26T15:28:53-04:00 Factorize getLinkDeps Prepare reuse of getLinkDeps for TH implementation in the JS backend (cf #22261 and review of !9779). - - - - - fad9d092 by Oleg Grenrus at 2023-05-27T13:38:08-04:00 Change GHC.Driver.Session import to .DynFlags Also move targetPlatform selector Plenty of GHC needs just DynFlags. Even more can be made to use .DynFlags if more selectors is migrated. This is a low hanging fruit. - - - - - 69fdbece by Alan Zimmerman at 2023-05-27T13:38:45-04:00 EPA: Better fix for #22919 The original fix for #22919 simply removed the ability to match up prior comments with the first declaration in the file. Restore it, but add a check that the comment is on a single line, by ensuring that it comes immediately prior to the next thing (comment or start of declaration), and that the token preceding it is not on the same line. closes #22919 - - - - - 0350b186 by Josh Meredith at 2023-05-29T12:46:27+00:00 Remove JavaScriptFFI from --supported-extensions for non-JS targets (#11214) - - - - - b4816919 by Matthew Pickering at 2023-05-30T17:07:43-04:00 testsuite: Pass -kb16k -kc128k for performance tests Setting a larger stack chunk size gives a greater protection from stack thrashing (where the repeated overflow/underflow allocates a lot of stack chunks which sigificantly impact allocations). This stabilises some tests against differences cause by more things being pushed onto the stack. The performance tests are generally testing work done by the compiler, using allocation as a proxy, so removing/stabilising the allocations due to the stack gives us more stable tests which are also more sensitive to actual changes in compiler performance. The tests which increase are ones where we compile a lot of modules, and for each module we spawn a thread to compile the module in. Therefore increasing these numbers has a multiplying effect on these tests because there are many more stacks which we can increase in size. The most significant improvements though are cases such as T8095 which reduce significantly in allocations (30%). This isn't a performance improvement really but just helps stabilise the test against this threshold set by the defaults. Fixes #23439 ------------------------- Metric Decrease: InstanceMatching T14683 T8095 T9872b_defer T9872d T9961 hie002 T19695 T3064 Metric Increase: MultiLayerModules T13701 T14697 ------------------------- - - - - - 6629f1c5 by Ben Gamari at 2023-05-30T17:08:20-04:00 Move via-C flags into GHC These were previously hardcoded in configure (with no option for overriding them) and simply passed onto ghc through the settings file. Since configure already guarantees gcc supports those flags, we simply move them into GHC. - - - - - 981e5e11 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00 Allow CPR on unrestricted constructors Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will allow CPR to handle `Ur`, in particular. - - - - - bf9344d2 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00 Push coercions across multiplicity boundaries Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will avoid preventing inlinings and reductions and make linear programs more efficient. - - - - - d56dd695 by sheaf at 2023-05-31T11:37:12-04:00 Data.Bag: add INLINEABLE to polymorphic functions This commit allows polymorphic methods in GHC.Data.Bag to be specialised, avoiding having to pass explicit dictionaries when they are instantiated with e.g. a known monad. - - - - - 5366cd35 by sheaf at 2023-05-31T11:37:12-04:00 Split off TcBinderStack into its own module This commit splits off TcBinderStack into its own module, to avoid module cycles: we might want to refer to it without also pulling in the TcM monad. - - - - - 09d4d307 by sheaf at 2023-05-31T11:37:12-04:00 Split off TcRef into its own module This helps avoid pull in the full TcM monad when we just want access to mutable references in the typechecker. This facilitates later patches which introduce a slimmed down TcM monad for zonking. - - - - - 88cc19b3 by sheaf at 2023-05-31T11:37:12-04:00 Introduce Codensity monad The Codensity monad is useful to write state-passing computations in continuation-passing style, e.g. to implement a State monad as continuation-passing style over a Reader monad. - - - - - f62d8195 by sheaf at 2023-05-31T11:37:12-04:00 Restructure the zonker This commit splits up the zonker into a few separate components, described in Note [The structure of the zonker] in `GHC.Tc.Zonk.Type`. 1. `GHC.Tc.Zonk.Monad` introduces a pared-down `TcM` monad, `ZonkM`, which has enough information for zonking types. This allows us to refactor `ErrCtxt` to use `ZonkM` instead of `TcM`, which guarantees we don't throw an error while reporting an error. 2. `GHC.Tc.Zonk.Env` is the new home of `ZonkEnv`, and also defines two zonking monad transformers, `ZonkT` and `ZonkBndrT`. `ZonkT` is a reader monad transformer over `ZonkEnv`. `ZonkBndrT m` is the codensity monad over `ZonkT m`. `ZonkBndrT` is used for computations that accumulate binders in the `ZonkEnv`. 3. `GHC.Tc.Zonk.TcType` contains the code for zonking types, for use in the typechecker. It uses the `ZonkM` monad. 4. `GHC.Tc.Zonk.Type` contains the code for final zonking to `Type`, which has been refactored to use `ZonkTcM = ZonkT TcM` and `ZonkBndrTcM = ZonkBndrT TcM`. Allocations slightly decrease on the whole due to using continuation-passing style instead of manual state passing of ZonkEnv in the final zonking to Type. ------------------------- Metric Decrease: T4029 T8095 T14766 T15304 hard_hole_fits RecordUpdPerf Metric Increase: T10421 ------------------------- - - - - - 70526f5b by mimi.vx at 2023-05-31T11:37:53-04:00 Update rdt-theme to latest upstream version Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/23444 - - - - - f3556d6c by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Restructure IPE buffer layout Reference ticket #21766 This commit restructures IPE buffer list entries to not contain references to their corresponding info tables. IPE buffer list nodes now point to two lists of equal length, one holding the list of info table pointers and one holding the corresponding entries for each info table. This will allow the entry data to be compressed without losing the references to the info tables. - - - - - 5d1f2411 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add IPE compression to configure Reference ticket #21766 Adds an `--enable-ipe-data-compreesion` flag to the configure script which will check for libzstd and set the appropriate flags to allow for IPE data compression in the compiler - - - - - b7a640ac by Finley McIlwaine at 2023-06-01T04:53:12-04:00 IPE data compression Reference ticket #21766 When IPE data compression is enabled, compress the emitted IPE buffer entries and decompress them in the RTS. - - - - - 5aef5658 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix libzstd detection in configure and RTS Ensure that `HAVE_LIBZSTD` gets defined to either 0 or 1 in all cases and properly check that before IPE data decompression in the RTS. See ticket #21766. - - - - - 69563c97 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add note describing IPE data compression See ticket #21766 - - - - - 7872e2b6 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix byte order of IPE data, fix IPE tests Make sure byte order of written IPE buffer entries matches target. Make sure the IPE-related tests properly access the fields of IPE buffer entry nodes with the new IPE layout. This commit also introduces checks to avoid importing modules if IPE compression is not enabled. See ticket #21766. - - - - - 0e85099b by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Fix IPE data decompression buffer allocation Capacity of buffers allocated for decompressed IPE data was incorrect due to a misuse of the `ZSTD_findFrameCompressedSize` function. Fix by always storing decompressed size of IPE data in IPE buffer list nodes and using `ZSTD_findFrameCompressedSize` to determine the size of the compressed data. See ticket #21766 - - - - - a0048866 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add optional dependencies to ./configure output Changes the configure script to indicate whether libnuma, libzstd, or libdw are being used as dependencies due to their optional features being enabled. - - - - - 09d93bd0 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Add IPE-enabled builds to CI - Adds an IPE job to the CI pipeline which is triggered by the ~IPE label - Introduces CI logic to enable IPE data compression - Enables uncompressed IPE data on debug CI job - Regenerates jobs.yaml MR https://gitlab.haskell.org/ghc/ci-images/-/merge_requests/112 on the images repository is meant to ensure that the proper images have libzstd-dev installed. - - - - - 3ded9a1c by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Update user's guide and release notes, small fixes Add mention of IPE data compression to user's guide and the release notes for 9.8.1. Also note the impact compression has on binary size in both places. Change IpeBufferListNode compression check so only the value `1` indicates compression. See ticket #21766 - - - - - 41b41577 by Finley McIlwaine at 2023-06-01T04:53:12-04:00 Remove IPE enabled builds from CI We don't need to explicitly specify the +ipe transformer to test IPE data since there are tests which manually enable IPE information. This commit does leave zstd IPE data compression enabled on the debian CI jobs. - - - - - 982bef3a by Krzysztof Gogolewski at 2023-06-01T04:53:49-04:00 Fix build with 9.2 GHC.Tc.Zonk.Type uses an equality constraint. ghc.nix currently provides 9.2. - - - - - 1c96bc3d by Krzysztof Gogolewski at 2023-06-01T10:56:11-04:00 Output Lint errors to stderr instead of stdout This is a continuation of 7b095b99, which fixed warnings but not errors. Refs #13342 - - - - - 8e81f140 by sheaf at 2023-06-01T10:56:51-04:00 Refactor lookupExactOrOrig & friends This refactors the panoply of renamer lookup functions relating to lookupExactOrOrig to more graciously handle Exact and Orig names. In particular, we avoid the situation in which we would add Exact/Orig GREs to the tcg_used_gres field, which could cause a panic in bestImport like in #23240. Fixes #23428 - - - - - 5d415bfd by Krzysztof Gogolewski at 2023-06-01T10:57:31-04:00 Use the one-shot trick for UM and RewriteM functors As described in Note [The one-shot state monad trick], we shouldn't use derived Functor instances for monads using one-shot. This was done for most of them, but UM and RewriteM were missed. - - - - - 2c38551e by Krzysztof Gogolewski at 2023-06-01T10:58:08-04:00 Fix testsuite skipping Lint setTestOpts() is used to modify the test options for an entire .T file, rather than a single test. If there was a test using collect_compiler_stats, all of the tests in the same file had lint disabled. Fixes #21247 - - - - - 00a1e50b by Krzysztof Gogolewski at 2023-06-01T10:58:44-04:00 Add testcases for already fixed #16432 They were fixed by 40c7daed0. Fixes #16432 - - - - - f6e060cc by Krzysztof Gogolewski at 2023-06-02T09:07:25-04:00 cleanup: Remove unused field from SelfBoot It is no longer needed since Note [Extra dependencies from .hs-boot files] was deleted in 6998772043. I've also added tildes to Note headers, otherwise they're not detected by the linter. - - - - - 82eacab6 by sheaf at 2023-06-02T09:08:01-04:00 Delete GHC.Tc.Utils.Zonk This module was split up into GHC.Tc.Zonk.Type and GHC.Tc.Zonk.TcType in commit f62d8195, but I forgot to delete the original module - - - - - 4a4eb761 by Ben Gamari at 2023-06-02T23:53:21-04:00 base: Add build-order import of GHC.Types in GHC.IO.Handle.Types For reasons similar to those described in Note [Depend on GHC.Num.Integer]. Fixes #23411. - - - - - f53ac0ae by Sylvain Henry at 2023-06-02T23:54:01-04:00 JS: fix and enhance non-minimized code generation (#22455) Flag -ddisable-js-minimizer was producing invalid code. Fix that and also a few other things to generate nicer JS code for debugging. The added test checks that we don't regress when using the flag. - - - - - f7744e8e by Andrey Mokhov at 2023-06-03T16:49:44-04:00 [hadrian] Fix multiline synopsis rendering - - - - - b2c745db by Andrew Lelechenko at 2023-06-03T16:50:23-04:00 Elaborate on performance properties of Data.List.++ - - - - - 7cd8a61e by Matthew Pickering at 2023-06-05T11:46:23+01:00 Big TcLclEnv and CtLoc refactoring The overall goal of this refactoring is to reduce the dependency footprint of the parser and syntax tree. Good reasons include: - Better module graph parallelisability - Make it easier to migrate error messages without introducing module loops - Philosophically, there's not reason for the AST to depend on half the compiler. One of the key edges which added this dependency was > GHC.Hs.Expr -> GHC.Tc.Types (TcLclEnv) As this in turn depending on TcM which depends on HscEnv and so on. Therefore the goal of this patch is to move `TcLclEnv` out of `GHC.Tc.Types` so that `GHC.Hs.Expr` can import TcLclEnv without incurring a huge dependency chain. The changes in this patch are: * Move TcLclEnv from GHC.Tc.Types to GHC.Tc.Types.LclEnv * Create new smaller modules for the types used in TcLclEnv New Modules: - GHC.Tc.Types.ErrCtxt - GHC.Tc.Types.BasicTypes - GHC.Tc.Types.TH - GHC.Tc.Types.LclEnv - GHC.Tc.Types.CtLocEnv - GHC.Tc.Errors.Types.PromotionErr Removed Boot File: - {-# SOURCE #-} GHC.Tc.Types * Introduce TcLclCtxt, the part of the TcLclEnv which doesn't participate in restoreLclEnv. * Replace TcLclEnv in CtLoc with specific CtLocEnv which is defined in GHC.Tc.Types.CtLocEnv. Use CtLocEnv in Implic and CtLoc to record the location of the implication and constraint. By splitting up TcLclEnv from GHC.Tc.Types we allow GHC.Hs.Expr to no longer depend on the TcM monad and all that entails. Fixes #23389 #23409 - - - - - 3d8d39d1 by Matthew Pickering at 2023-06-05T11:46:23+01:00 Remove dependency of GHC.Tc.Utils.TcType on GHC.Driver.Session This removes the usage of DynFlags from Tc.Utils.TcType so that it no longer depends on GHC.Driver.Session. In general we don't want anything which is a dependency of Language.Haskell.Syntax to depend on GHC.Driver.Session and removing this edge gets us closer to that goal. - - - - - 18db5ada by Matthew Pickering at 2023-06-05T11:46:23+01:00 Move isIrrefutableHsPat to GHC.Rename.Utils and rename to isIrrefutableHsPatRn This removes edge from GHC.Hs.Pat to GHC.Driver.Session, which makes Language.Haskell.Syntax end up depending on GHC.Driver.Session. - - - - - 12919dd5 by Matthew Pickering at 2023-06-05T11:46:23+01:00 Remove dependency of GHC.Tc.Types.Constraint on GHC.Driver.Session - - - - - eb852371 by Matthew Pickering at 2023-06-05T11:46:24+01:00 hole fit plugins: Split definition into own module The hole fit plugins are defined in terms of TcM, a type we want to avoid depending on from `GHC.Tc.Errors.Types`. By moving it into its own module we can remove this dependency. It also simplifies the necessary boot file. - - - - - 9e5246d7 by Matthew Pickering at 2023-06-05T11:46:24+01:00 Move GHC.Core.Opt.CallerCC Types into separate module This allows `GHC.Driver.DynFlags` to depend on these types without depending on CoreM and hence the entire simplifier pipeline. We can also remove a hs-boot file with this change. - - - - - 52d6a7d7 by Matthew Pickering at 2023-06-05T11:46:24+01:00 Remove unecessary SOURCE import - - - - - 698d160c by Matthew Pickering at 2023-06-05T11:46:24+01:00 testsuite: Accept new output for CountDepsAst and CountDepsParser tests These are in a separate commit as the improvement to these tests is the cumulative effect of the previous set of patches rather than just the responsibility of the last one in the patchset. - - - - - 58ccf02e by sheaf at 2023-06-05T16:00:47-04:00 TTG: only allow VarBind at GhcTc The VarBind constructor of HsBind is only used at the GhcTc stage. This commit makes that explicit by setting the extension field of VarBind to be DataConCantHappen at all other stages. This allows us to delete a dead code path in GHC.HsToCore.Quote.rep_bind, and remove some panics. - - - - - 54b83253 by Matthew Craven at 2023-06-06T12:59:25-04:00 Generate Addr# access ops programmatically The existing utils/genprimopcode/gen_bytearray_ops.py was relocated and extended for this purpose. Additionally, hadrian now knows about this script and uses it when generating primops.txt - - - - - ecadbc7e by Matthew Pickering at 2023-06-06T13:00:01-04:00 ghcup-metadata: Only add Nightly tag when replacing LatestNightly Previously we were always adding the Nightly tag, but this led to all the previous builds getting an increasing number of nightly tags over time. Now we just add it once, when we remove the LatestNightly tag. - - - - - 4aea0a72 by Vladislav Zavialov at 2023-06-07T12:06:46+02:00 Invisible binders in type declarations (#22560) This patch implements @k-binders introduced in GHC Proposal #425 and guarded behind the TypeAbstractions extension: type D :: forall k j. k -> j -> Type data D @k @j a b = ... ^^ ^^ To represent the new syntax, we modify LHsQTyVars as follows: - hsq_explicit :: [LHsTyVarBndr () pass] + hsq_explicit :: [LHsTyVarBndr (HsBndrVis pass) pass] HsBndrVis is a new data type that records the distinction between type variable binders written with and without the @ sign: data HsBndrVis pass = HsBndrRequired | HsBndrInvisible (LHsToken "@" pass) The rest of the patch updates GHC, template-haskell, and haddock to handle the new syntax. Parser: The PsErrUnexpectedTypeAppInDecl error message is removed. The syntax it used to reject is now permitted. Renamer: The @ sign does not affect the scope of a binder, so the changes to the renamer are minimal. See rnLHsTyVarBndrVisFlag. Type checker: There are three code paths that were updated to deal with the newly introduced invisible type variable binders: 1. checking SAKS: see kcCheckDeclHeader_sig, matchUpSigWithDecl 2. checking CUSK: see kcCheckDeclHeader_cusk 3. inference: see kcInferDeclHeader, rejectInvisibleBinders Helper functions bindExplicitTKBndrs_Q_Skol and bindExplicitTKBndrs_Q_Tv are generalized to work with HsBndrVis. Updates the haddock submodule. Metric Increase: MultiLayerModulesTH_OneShot Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - b7600997 by Josh Meredith at 2023-06-07T13:10:21-04:00 JS: clean up FFI 'fat arrow' calls in base:System.Posix.Internals (#23481) - - - - - e5d3940d by Sebastian Graf at 2023-06-07T18:01:28-04:00 Update CODEOWNERS - - - - - 960ef111 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Remove IPE enabled builds from CI" This reverts commit 41b41577c8a28c236fa37e8f73aa1c6dc368d951. - - - - - bad1c8cc by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Update user's guide and release notes, small fixes" This reverts commit 3ded9a1cd22f9083f31bc2f37ee1b37f9d25dab7. - - - - - 12726d90 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add IPE-enabled builds to CI" This reverts commit 09d93bd0305b0f73422ce7edb67168c71d32c15f. - - - - - dbdd989d by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add optional dependencies to ./configure output" This reverts commit a00488665cd890a26a5564a64ba23ff12c9bec58. - - - - - 240483af by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix IPE data decompression buffer allocation" This reverts commit 0e85099b9316ee24565084d5586bb7290669b43a. - - - - - 9b8c7dd8 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix byte order of IPE data, fix IPE tests" This reverts commit 7872e2b6f08ea40d19a251c4822a384d0b397327. - - - - - 3364379b by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add note describing IPE data compression" This reverts commit 69563c97396b8fde91678fae7d2feafb7ab9a8b0. - - - - - fda30670 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Fix libzstd detection in configure and RTS" This reverts commit 5aef5658ad5fb96bac7719710e0ea008bf7b62e0. - - - - - 1cbcda9a by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "IPE data compression" This reverts commit b7a640acf7adc2880e5600d69bcf2918fee85553. - - - - - fb5e99aa by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Add IPE compression to configure" This reverts commit 5d1f2411f4becea8650d12d168e989241edee186. - - - - - 2cdcb3a5 by Matthew Pickering at 2023-06-07T18:02:04-04:00 Revert "Restructure IPE buffer layout" This reverts commit f3556d6cefd3d923b36bfcda0c8185abb1d11a91. - - - - - 2b0c9f5e by Simon Peyton Jones at 2023-06-08T07:52:34+00:00 Don't report redundant Givens from quantified constraints This fixes #23323 See (RC4) in Note [Tracking redundant constraints] - - - - - 567b32e1 by David Binder at 2023-06-08T18:41:29-04:00 Update the outdated instructions in HACKING.md on how to compile GHC - - - - - 2b1a4abe by Ryan Scott at 2023-06-09T07:56:58-04:00 Restore mingwex dependency on Windows This partially reverts some of the changes in !9475 to make `base` and `ghc-prim` depend on the `mingwex` library on Windows. It also restores the RTS's stubs for `mingwex`-specific symbols such as `_lock_file`. This is done because the C runtime provides `libmingwex` nowadays, and moreoever, not linking against `mingwex` requires downstream users to link against it explicitly in difficult-to-predict circumstances. Better to always link against `mingwex` and prevent users from having to do the guesswork themselves. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10360#note_495873 for the discussion that led to this. - - - - - 28954758 by Ryan Scott at 2023-06-09T07:56:58-04:00 RtsSymbols.c: Remove mingwex symbol stubs As of !9475, the RTS now links against `ucrt` instead of `msvcrt` on Windows, which means that the RTS no longer needs to declare stubs for the `__mingw_*` family of symbols. Let's remove these stubs to avoid confusion. Fixes #23309. - - - - - 3ab0155b by Ryan Scott at 2023-06-09T07:57:35-04:00 Consistently use validity checks for TH conversion of data constructors We were checking that TH-spliced data declarations do not look like this: ```hs data D :: Type = MkD Int ``` But we were only doing so for `data` declarations' data constructors, not for `newtype`s, `data instance`s, or `newtype instance`s. This patch factors out the necessary validity checks into its own `cvtDataDefnCons` function and uses it in all of the places where it needs to be. Fixes #22559. - - - - - a24b83dd by Matthew Pickering at 2023-06-09T15:19:00-04:00 Fix behaviour of -keep-tmp-files when used in OPTIONS_GHC pragma This fixes the behaviour of -keep-tmp-files when used in an OPTIONS_GHC pragma for files with module level scope. Instead of simple not deleting the files, we also need to remove them from the TmpFs so they are not deleted later on when all the other files are deleted. There are additional complications because you also need to remove the directory where these files live from the TmpFs so we don't try to delete those later either. I added two tests. 1. Tests simply that -keep-tmp-files works at all with a single module and --make mode. 2. The other tests that temporary files are deleted for other modules which don't enable -keep-tmp-files. Fixes #23339 - - - - - dcf32882 by Matthew Pickering at 2023-06-09T15:19:00-04:00 withDeferredDiagnostics: When debugIsOn, write landmine into IORef to catch use-after-free. Ticket #23305 reports an error where we were attempting to use the logger which was created by withDeferredDiagnostics after its scope had ended. This problem would have been caught by this patch and a validate build: ``` +*** Exception: Use after free +CallStack (from HasCallStack): + error, called at compiler/GHC/Driver/Make.hs:<line>:<column> in <package-id>:GHC.Driver.Make ``` This general issue is tracked by #20981 - - - - - 432c736c by Matthew Pickering at 2023-06-09T15:19:00-04:00 Don't return complete HscEnv from upsweep By returning a complete HscEnv from upsweep the logger (as introduced by withDeferredDiagnostics) was escaping the scope of withDeferredDiagnostics and hence we were losing error messages. This is reminiscent of #20981, which also talks about writing errors into messages after their scope has ended. See #23305 for details. - - - - - 26013cdc by Alexander McKenna at 2023-06-09T15:19:41-04:00 Dump `SpecConstr` specialisations separately Introduce a `-ddump-spec-constr` flag which debugs specialisations from `SpecConstr`. These are no longer shown when you use `-ddump-spec`. - - - - - 4639100b by Matthew Pickering at 2023-06-09T18:50:43-04:00 Add role annotations to SNat, SSymbol and SChar Ticket #23454 explained it was possible to implement unsafeCoerce because SNat was lacking a role annotation. As these are supposed to be singleton types but backed by an efficient representation the correct annotation is nominal to ensure these kinds of coerces are forbidden. These annotations were missed from https://github.com/haskell/core-libraries-committee/issues/85 which was implemented in 532de36870ed9e880d5f146a478453701e9db25d. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/170 Fixes #23454 - - - - - 9c0dcff7 by Matthew Pickering at 2023-06-09T18:51:19-04:00 Remove non-existant bytearray-ops.txt.pp file from ghc.cabal.in This broke the sdist generation. Fixes #23489 - - - - - 273ff0c7 by David Binder at 2023-06-09T18:52:00-04:00 Regression test T13438 is no longer marked as "expect_broken" in the testsuite driver. - - - - - b84a2900 by Andrei Borzenkov at 2023-06-10T08:27:28-04:00 Fix -Wterm-variable-capture scope (#23434) -Wterm-variable-capture wasn't accordant with type variable scoping in associated types, in type classes. For example, this code produced the warning: k = 12 class C k a where type AT a :: k -> Type I solved this issue by reusing machinery of newTyVarNameRn function that is accordand with associated types: it does lookup for each free type variable when we are in the type class context. And in this patch I use result of this work to make sure that -Wterm-variable-capture warns only on implicitly quantified type variables. - - - - - 9d1a8d87 by Jorge Mendes at 2023-06-10T08:28:10-04:00 Remove redundant case statement in rts/js/mem.js. - - - - - a1f350e2 by Oleg Grenrus at 2023-06-13T09:42:16-04:00 Change WarningWithFlag to plural WarningWithFlags Resolves #22825 Now each diagnostic can name multiple different warning flags for its reason. There is currently one use case: missing signatures. Currently we need to check which warning flags are enabled when generating the diagnostic, which is against the declarative nature of the diagnostic framework. This patch allows a warning diagnostic to have multiple warning flags, which makes setup more declarative. The WarningWithFlag pattern synonym is added for backwards compatibility The 'msgEnvReason' field is added to MsgEnvelope to store the `ResolvedDiagnosticReason`, which accounts for the enabled flags, and then that is used for pretty printing the diagnostic. - - - - - ec01f0ec by Matthew Pickering at 2023-06-13T09:42:59-04:00 Add a test Way for running ghci with Core optimizations Tracking ticket: #23059 This runs compile_and_run tests with optimised code with bytecode interpreter Changed submodules: hpc, process Co-authored-by: Torsten Schmits <git at tryp.io> - - - - - c6741e72 by Rodrigo Mesquita at 2023-06-13T09:43:38-04:00 Configure -Qunused-arguments instead of hardcoding it When GHC invokes clang, it currently passes -Qunused-arguments to discard warnings resulting from GHC using multiple options that aren't used. In this commit, we configure -Qunused-arguments into the Cc options instead of checking if the compiler is clang at runtime and hardcoding the flag into GHC. This is part of the effort to centralise toolchain information in toolchain target files at configure time with the end goal of a runtime retargetable GHC. This also means we don't need to call getCompilerInfo ever, which improves performance considerably (see !10589). Metric Decrease: PmSeriesG T10421 T11303b T12150 T12227 T12234 T12425 T13035 T13253-spj T13386 T15703 T16875 T17836b T17977 T17977b T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T3064 T5030 T5321FD T5321Fun T5837 T6048 T9020 T9198 T9872d T9961 - - - - - 0128db87 by Victor Cacciari Miraldo at 2023-06-13T09:44:18-04:00 Improve docs for Data.Fixed; adds 'realToFrac' as an option for conversion between different precisions. - - - - - 95b69cfb by Ryan Scott at 2023-06-13T09:44:55-04:00 Add regression test for #23143 !10541, the fix for #23323, also fixes #23143. Let's add a regression test to ensure that it stays fixed. Fixes #23143. - - - - - ed2dbdca by Emily Martins at 2023-06-13T09:45:37-04:00 delete GHCi.UI.Tags module and remove remaining references Co-authored-by: Tilde Rose <t1lde at protonmail.com> - - - - - c90d96e4 by Victor Cacciari Miraldo at 2023-06-13T09:46:26-04:00 Add regression test for 17328 - - - - - de58080c by Victor Cacciari Miraldo at 2023-06-13T09:46:26-04:00 Skip checking whether constructors are in scope when deriving newtype instances. Fixes #17328 - - - - - 5e3c2b05 by Philip Hazelden at 2023-06-13T09:47:07-04:00 Don't suggest `DeriveAnyClass` when instance can't be derived. Fixes #19692. Prototypical cases: class C1 a where x1 :: a -> Int data G1 = G1 deriving C1 class C2 a where x2 :: a -> Int x2 _ = 0 data G2 = G2 deriving C2 Both of these used to give this suggestion, but for C1 the suggestion would have failed (generated code with undefined methods, which compiles but warns). Now C2 still gives the suggestion but C1 doesn't. - - - - - 80a0b099 by David Binder at 2023-06-13T09:47:49-04:00 Add testcase for error GHC-00711 to testsuite - - - - - e4b33a1d by Oleg Grenrus at 2023-06-14T07:01:21-04:00 Add -Wmissing-poly-kind-signatures Implements #22826 This is a restricted version of -Wmissing-kind-signatures shown only for polykinded types. - - - - - f8395b94 by doyougnu at 2023-06-14T07:02:01-04:00 ci: special case in req_host_target_ghc for JS - - - - - b852a5b6 by Gergő Érdi at 2023-06-14T07:02:42-04:00 When forcing a `ModIface`, force the `MINIMAL` pragmas in class definitions Fixes #23486 - - - - - c29b45ee by Krzysztof Gogolewski at 2023-06-14T07:03:19-04:00 Add a testcase for #20076 Remove 'recursive' in the error message, since the error can arise without recursion. - - - - - b80ef202 by Krzysztof Gogolewski at 2023-06-14T07:03:56-04:00 Use tcInferFRR to prevent bad generalisation Fixes #23176 - - - - - bd8ef37d by Matthew Pickering at 2023-06-14T07:04:31-04:00 ci: Add dependenices on necessary aarch64 jobs for head.hackage ci These need to be added since we started testing aarch64 on head.hackage CI. The jobs will sometimes fail because they will start before the relevant aarch64 job has finished. Fixes #23511 - - - - - a0c27cee by Vladislav Zavialov at 2023-06-14T07:05:08-04:00 Add standalone kind signatures for Code and TExp CodeQ and TExpQ already had standalone kind signatures even before this change: type TExpQ :: TYPE r -> Kind.Type type CodeQ :: TYPE r -> Kind.Type Now Code and TExp have signatures too: type TExp :: TYPE r -> Kind.Type type Code :: (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type This is a stylistic change. - - - - - e70c1245 by Tom Ellis at 2023-06-14T07:05:48-04:00 Warn that GHC.TypeLits.Internal should not be used - - - - - 100650e3 by Tom Ellis at 2023-06-14T07:05:48-04:00 Warn that GHC.TypeNats.Internal should not be used - - - - - 078250ef by Jacco Krijnen at 2023-06-14T17:17:53-04:00 Add more flags for dumping core passes (#23491) - - - - - 1b7604af by Jacco Krijnen at 2023-06-14T17:17:53-04:00 Add tests for dumping flags (#23491) - - - - - 42000000 by Sebastian Graf at 2023-06-14T17:18:29-04:00 Provide a demand signature for atomicModifyMutVar.# (#23047) Fixes #23047 - - - - - 8f27023b by Ben Gamari at 2023-06-15T03:10:24-04:00 compiler: Cross-reference Note [StgToJS design] In particular, the numeric representations are quite useful context in a few places. - - - - - a71b60e9 by Andrei Borzenkov at 2023-06-15T03:11:00-04:00 Implement the -Wimplicit-rhs-quantification warning (#23510) GHC Proposal #425 "Invisible binders in type declarations" forbids implicit quantification of type variables that occur free on the right-hand side of a type synonym but are not mentioned on the left-hand side. The users are expected to rewrite this using invisible binders: type T1 :: forall a . Maybe a type T1 = 'Nothing :: Maybe a -- old type T1 @a = 'Nothing :: Maybe a -- new Since the @k-binders are a new feature, we need to wait for three releases before we require the use of the new syntax. In the meantime, we ought to provide users with a new warning, -Wimplicit-rhs-quantification, that would detect when such implicit quantification takes place, and include it in -Wcompat. - - - - - 0078dd00 by Sven Tennie at 2023-06-15T03:11:36-04:00 Minor refactorings to mkSpillInstr and mkLoadInstr Better error messages. And, use the existing `off` constant to reduce duplication. - - - - - 1792b57a by doyougnu at 2023-06-15T03:12:17-04:00 JS: merge util modules Merge Core and StgUtil modules for StgToJS pass. Closes: #23473 - - - - - 469ff08b by Vladislav Zavialov at 2023-06-15T03:12:57-04:00 Check visibility of nested foralls in can_eq_nc (#18863) Prior to this change, `can_eq_nc` checked the visibility of the outermost layer of foralls: forall a. forall b. forall c. phi1 forall x. forall y. forall z. phi2 ^^ up to here Then it delegated the rest of the work to `can_eq_nc_forall`, which split off all foralls: forall a. forall b. forall c. phi1 forall x. forall y. forall z. phi2 ^^ up to here This meant that some visibility flags were completely ignored. We fix this oversight by moving the check to `can_eq_nc_forall`. - - - - - 59c9065b by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: use regular mask for blocking IO Blocking IO used uninterruptibleMask which should make any thread blocked on IO unreachable by async exceptions (such as those from timeout). This changes it to a regular mask. It's important to note that the nodejs runtime does not actually interrupt the blocking IO when the Haskell thread receives an async exception, and that file positions may be updated and buffers may be written after the Haskell thread has already resumed. Any file descriptor affected by an async exception interruption should therefore be used with caution. - - - - - 907c06c3 by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: nodejs: do not set 'readable' handler on stdin at startup The Haskell runtime used to install a 'readable' handler on stdin at startup in nodejs. This would cause the nodejs system to start buffering the stream, causing data loss if the stdin file descriptor is passed to another process. This change delays installation of the 'readable' handler until the first read of stdin by Haskell code. - - - - - a54b40a9 by Luite Stegeman at 2023-06-15T03:13:37-04:00 JS: reserve one more virtual (negative) file descriptor This is needed for upcoming support of the process package - - - - - 78cd1132 by Andrei Borzenkov at 2023-06-15T11:16:11+04:00 Report scoped kind variables at the type-checking phase (#16635) This patch modifies the renamer to respect ScopedTypeVariables in kind signatures. This means that kind variables bound by the outermost `forall` now scope over the type: type F = '[Right @a @() () :: forall a. Either a ()] -- ^^^^^^^^^^^^^^^ ^^^ -- in scope here bound here However, any use of such variables is a type error, because we don't have type-level lambdas to bind them in Core. This is described in the new Note [Type variable scoping errors during type check] in GHC.Tc.Types. - - - - - 4a41ba75 by Sylvain Henry at 2023-06-15T18:09:15-04:00 JS: testsuite: use correct ticket number Replace #22356 with #22349 for these tests because #22356 has been fixed but now these tests fail because of #22349. - - - - - 15f150c8 by Sylvain Henry at 2023-06-15T18:09:16-04:00 JS: testsuite: update ticket numbers - - - - - 08d8e9ef by Sylvain Henry at 2023-06-15T18:09:16-04:00 JS: more triage - - - - - e8752e12 by Krzysztof Gogolewski at 2023-06-15T18:09:52-04:00 Fix test T18522-deb-ppr Fixes #23509 - - - - - 62c56416 by Ben Price at 2023-06-16T05:52:39-04:00 Lint: more details on "Occurrence is GlobalId, but binding is LocalId" This is helpful when debugging a pass which accidentally shadowed a binder. - - - - - d4c10238 by Ryan Hendrickson at 2023-06-16T05:53:22-04:00 Clean a stray bit of text in user guide - - - - - 93647b5c by Vladislav Zavialov at 2023-06-16T05:54:02-04:00 testsuite: Add forall visibility test cases The added tests ensure that the type checker does not confuse visible and invisible foralls. VisFlag1: kind-checking type applications and inferred type variable instantiations VisFlag1_ql: kind-checking Quick Look instantiations VisFlag2: kind-checking type family instances VisFlag3: checking kind annotations on type parameters of associated type families VisFlag4: checking kind annotations on type parameters in type declarations with SAKS VisFlag5: checking the result kind annotation of data family instances - - - - - a5f0c00e by Sylvain Henry at 2023-06-16T12:25:40-04:00 JS: factorize SaneDouble into its own module Follow-up of b159e0e9 whose ticket is #22736 - - - - - 0baf9e7c by Krzysztof Gogolewski at 2023-06-16T12:26:17-04:00 Add tests for #21973 - - - - - 640ea90e by Diego Diverio at 2023-06-16T23:07:55-04:00 Update documentation for `<**>` - - - - - 2469a813 by Diego Diverio at 2023-06-16T23:07:55-04:00 Update text - - - - - 1f515bbb by Diego Diverio at 2023-06-16T23:07:55-04:00 Update examples - - - - - 7af99a0d by Diego Diverio at 2023-06-16T23:07:55-04:00 Update documentation to actually display code correctly - - - - - 800aad7e by Andrei Borzenkov at 2023-06-16T23:08:32-04:00 Type/data instances: require that variables on the RHS are mentioned on the LHS (#23512) GHC Proposal #425 "Invisible binders in type declarations" restricts the scope of type and data family instances as follows: In type family and data family instances, require that every variable mentioned on the RHS must also occur on the LHS. For example, here are three equivalent type instance definitions accepted before this patch: type family F1 a :: k type instance F1 Int = Any :: j -> j type family F2 a :: k type instance F2 @(j -> j) Int = Any :: j -> j type family F3 a :: k type instance forall j. F3 Int = Any :: j -> j - In F1, j is implicitly quantified and it occurs only on the RHS; - In F2, j is implicitly quantified and it occurs both on the LHS and the RHS; - In F3, j is explicitly quantified. Now F1 is rejected with an out-of-scope error, while F2 and F3 continue to be accepted. - - - - - 9132d529 by Sylvain Henry at 2023-06-18T02:50:34-04:00 JS: testsuite: use correct ticket numbers - - - - - c3a1274c by Sylvain Henry at 2023-06-18T02:50:34-04:00 JS: don't dump eventlog to stderr by default Fix T16707 Bump stm submodule - - - - - 89bb8ad8 by Ryan Hendrickson at 2023-06-18T02:51:14-04:00 Fix TH name lookup for symbolic tycons (#23525) - - - - - cb9e1ce4 by Finley McIlwaine at 2023-06-18T21:16:45-06:00 IPE data compression IPE data resulting from the `-finfo-table-map` flag may now be compressed by configuring the GHC build with the `--enable-ipe-data-compression` flag. This results in about a 20% reduction in the size of IPE-enabled build results. The compression library, zstd, may optionally be statically linked by configuring with the `--enabled-static-libzstd` flag (on non-darwin platforms) libzstd version 1.4.0 or greater is required. - - - - - 0cbc3ae0 by Gergő Érdi at 2023-06-19T09:11:38-04:00 Add `IfaceWarnings` to represent the `ModIface`-storable parts of a `Warnings GhcRn`. Fixes #23516 - - - - - 3e80c2b4 by Arnaud Spiwack at 2023-06-20T03:19:41-04:00 Avoid desugaring non-recursive lets into recursive lets This prepares for having linear let expressions in the frontend. When desugaring lets, SPECIALISE statements create more copies of a let binding. Because of the rewrite rules attached to the bindings, there are dependencies between the generated binds. Before this commit, we simply wrapped all these in a mutually recursive let block, and left it to the simplified to sort it out. With this commit: we are careful to generate the bindings in dependency order, so that we can wrap them in consecutive lets (if the source is non-recursive). - - - - - 9fad49e0 by Ben Gamari at 2023-06-20T03:20:19-04:00 rts: Do not call exit() from SIGINT handler Previously `shutdown_handler` would call `stg_exit` if the scheduler was Oalready found to be in `SCHED_INTERRUPTING` state (or higher). However, `stg_exit` is not signal-safe as it calls `exit` (which calls `atexit` handlers). The only safe thing to do in this situation is to call `_exit`, which terminates with minimal cleanup. Fixes #23417. - - - - - 7485f848 by Andrew Lelechenko at 2023-06-20T03:20:57-04:00 Bump Cabal submodule This requires changing the recomp007 test because now cabal passes `this-unit-id` to executable components, and that unit-id contains a hash which includes the ABI of the dependencies. Therefore changing the dependencies means that -this-unit-id changes and recompilation is triggered. The spririt of the test is to test GHC's recompilation logic assuming that `-this-unit-id` is constant, so we explicitly pass `-ipid` to `./configure` rather than letting `Cabal` work it out. - - - - - 1464a2a8 by mangoiv at 2023-06-20T03:21:34-04:00 [feat] add a hint to `HasField` error message - add a hint that indicates that the record that the record dot is used on might just be missing a field - as the intention of the programmer is not entirely clear, it is only shown if the type is known - This addresses in part issue #22382 - - - - - b65e78dd by Ben Gamari at 2023-06-20T16:56:43-04:00 rts/ipe: Fix unused lock warning - - - - - 6086effd by Ben Gamari at 2023-06-20T16:56:44-04:00 rts/ProfilerReportJson: Fix memory leak - - - - - 1e48c434 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Various warnings fixes - - - - - 471486b9 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix printf format mismatch - - - - - 80603fb3 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect #include <sys/poll.h> According to Alpine's warnings and poll(2), <poll.h> should be preferred. - - - - - ff18e6fd by Ben Gamari at 2023-06-20T16:56:44-04:00 nonmoving: Fix unused definition warrnings - - - - - 6e7fe8ee by Ben Gamari at 2023-06-20T16:56:44-04:00 Disable futimens on Darwin. See #22938 - - - - - b7706508 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect CPP guard - - - - - 94f00e9b by Ben Gamari at 2023-06-20T16:56:44-04:00 hadrian: Ensure that -Werror is passed when compiling the RTS. Previously the `+werror` transformer would only pass `-Werror` to GHC, which does not ensure that the same is passed to the C compiler when building the RTS. Arguably this is itself a bug but for now we will just work around this by passing `-optc-Werror` to GHC. I tried to enable `-Werror` in all C compilations but the boot libraries are something of a portability nightmare. - - - - - 5fb54bf8 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Disable `#pragma GCC`s on clang compilers Otherwise the build fails due to warnings. See #23530. - - - - - cf87f380 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix capitalization of prototype - - - - - 17f250d7 by Ben Gamari at 2023-06-20T16:56:44-04:00 rts: Fix incorrect format specifier - - - - - 0ff1c501 by Josh Meredith at 2023-06-20T16:57:20-04:00 JS: remove js_broken(22576) in favour of the pre-existing wordsize(32) condition (#22576) - - - - - 3d1d42b7 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Memory usage fixes for Haddock - Do not include `mi_globals` in the `NoBackend` backend. It was only included for Haddock, but Haddock does not actually need it. This causes a 200MB reduction in max residency when generating haddocks on the Agda codebase (roughly 1GB to 800MB). - Make haddock_{parser,renamer}_perf tests more accurate by forcing docs to be written to interface files using `-fwrite-interface` Bumps haddock submodule. Metric Decrease: haddock.base - - - - - 8185b1c2 by Finley McIlwaine at 2023-06-21T12:04:58-04:00 Fix associated data family doc structure items Associated data families were being given their own export DocStructureItems, which resulted in them being documented separately from their classes in haddocks. This commit fixes it. - - - - - 4d356ea3 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: implement TH support - Add ghc-interp.js bootstrap script for the JS interpreter - Interactively link and execute iserv code from the ghci package - Incrementally load and run JS code for splices into the running iserv Co-authored-by: Luite Stegeman <stegeman at gmail.com> - - - - - 3249cf12 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Don't use getKey - - - - - f84ff161 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Stg: return imported FVs This is used to determine what to link when using the interpreter. For now it's only used by the JS interpreter but it could easily be used by the native interpreter too (instead of extracting names from compiled BCOs). - - - - - fab2ad23 by Sylvain Henry at 2023-06-21T12:04:59-04:00 Fix some recompilation avoidance tests - - - - - a897dc13 by Sylvain Henry at 2023-06-21T12:04:59-04:00 TH_import_loop is now broken as expected - - - - - dbb4ad51 by Sylvain Henry at 2023-06-21T12:04:59-04:00 JS: always recompile when TH is enabled (cf #23013) - - - - - 711b1d24 by Bartłomiej Cieślar at 2023-06-21T12:59:27-04:00 Add support for deprecating exported items (proposal #134) This is an implementation of the deprecated exports proposal #134. The proposal introduces an ability to introduce warnings to exports. This allows for deprecating a name only when it is exported from a specific module, rather than always depreacting its usage. In this example: module A ({-# DEPRECATED "do not use" #-} x) where x = undefined --- module B where import A(x) `x` will emit a warning when it is explicitly imported. Like the declaration warnings, export warnings are first accumulated within the `Warnings` struct, then passed into the ModIface, from which they are then looked up and warned about in the importing module in the `lookup_ie` helpers of the `filterImports` function (for the explicitly imported names) and in the `addUsedGRE(s)` functions where they warn about regular usages of the imported name. In terms of the AST information, the custom warning is stored in the extension field of the variants of the `IE` type (see Trees that Grow for more information). The commit includes a bump to the haddock submodule added in MR #28 Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - c1865854 by Ben Gamari at 2023-06-21T12:59:30-04:00 configure: Bump version to 9.8 Bumps Haddock submodule - - - - - 4e1de71c by Ben Gamari at 2023-06-21T21:07:48-04:00 configure: Bump version to 9.9 Bumps haddock submodule. - - - - - 5b6612bc by Ben Gamari at 2023-06-23T03:56:49-04:00 rts: Work around missing prototypes errors Darwin's toolchain inexpliciably claims that `write_barrier` and friends have declarations without prototypes, despite the fact that (a) they are definitions, and (b) the prototypes appear only a few lines above. Work around this by making the definitions proper prototypes. - - - - - 43b66a13 by Matthew Pickering at 2023-06-23T03:57:26-04:00 ghcup-metadata: Fix date modifier (M = minutes, m = month) Fixes #23552 - - - - - 564164ef by Luite Stegeman at 2023-06-24T10:27:29+09:00 Support large stack frames/offsets in GHCi bytecode interpreter Bytecode instructions like PUSH_L (push a local variable) contain an operand that refers to the stack slot. Before this patch, the operand type was SmallOp (Word16), limiting the maximum stack offset to 65535 words. This could cause compiler panics in some cases (See #22888). This patch changes the operand type for stack offsets from SmallOp to Op, removing the stack offset limit. Fixes #22888 - - - - - 8d6574bc by Sylvain Henry at 2023-06-26T13:15:06-04:00 JS: support levity-polymorphic datatypes (#22360,#22291) - thread knowledge about levity into PrimRep instead of panicking - JS: remove assumption that unlifted heap objects are rts objects (TVar#, etc.) Doing this also fixes #22291 (test added). There is a small performance hit (~1% more allocations). Metric Increase: T18698a T18698b - - - - - 5578bbad by Matthew Pickering at 2023-06-26T13:15:43-04:00 MR Review Template: Mention "Blocked on Review" label In order to improve our MR review processes we now have the label "Blocked on Review" which allows people to signal that a MR is waiting on a review to happen. See: https://mail.haskell.org/pipermail/ghc-devs/2023-June/021255.html - - - - - 4427e9cf by Matthew Pickering at 2023-06-26T13:15:43-04:00 Move MR template to Default.md This makes it more obvious what you have to modify to affect the default template rather than looking in the project settings. - - - - - 522bd584 by Arnaud Spiwack at 2023-06-26T13:16:33-04:00 Revert "Avoid desugaring non-recursive lets into recursive lets" This (temporary) reverts commit 3e80c2b40213bebe302b1bd239af48b33f1b30ef. Fixes #23550 - - - - - c59fbb0b by Torsten Schmits at 2023-06-26T19:34:20+02:00 Propagate breakpoint information when inlining across modules Tracking ticket: #23394 MR: !10448 * Add constructor `IfaceBreakpoint` to `IfaceTickish` * Store breakpoint data in interface files * Store `BreakArray` for the breakpoint's module, not the current module, in BCOs * Store module name in BCOs instead of `Unique`, since the `Unique` from an `Iface` doesn't match the modules in GHCi's state * Allocate module name in `ModBreaks`, like `BreakArray` * Lookup breakpoint by module name in GHCi * Skip creating breakpoint instructions when no `ModBreaks` are available, rather than injecting `ModBreaks` in the linker when breakpoints are enabled, and panicking when `ModBreaks` is missing - - - - - 6f904808 by Greg Steuck at 2023-06-27T16:53:07-04:00 Remove undefined FP_PROG_LD_BUILD_ID from configure.ac's - - - - - e89aa072 by Andrei Borzenkov at 2023-06-27T16:53:44-04:00 Remove arity inference in type declarations (#23514) Arity inference in type declarations was introduced as a workaround for the lack of @k-binders. They were added in 4aea0a72040, so I simplified all of this by simply removing arity inference altogether. This is part of GHC Proposal #425 "Invisible binders in type declarations". - - - - - 459dee1b by Torsten Schmits at 2023-06-27T16:54:20-04:00 Relax defaulting of RuntimeRep/Levity when printing Fixes #16468 MR: !10702 Only default RuntimeRep to LiftedRep when variables are bound by the toplevel forall - - - - - 151f8f18 by Torsten Schmits at 2023-06-27T16:54:57-04:00 Remove duplicate link label in linear types docs - - - - - ecdc4353 by Rodrigo Mesquita at 2023-06-28T12:24:57-04:00 Stop configuring unused Ld command in `settings` GHC has no direct dependence on the linker. Rather, we depend upon the C compiler for linking and an object-merging program (which is typically `ld`) for production of GHCi objects and merging of C stubs into final object files. Despite this, for historical reasons we still recorded information about the linker into `settings`. Remove these entries from `settings`, `hadrian/cfg/system.config`, as well as the `configure` logic responsible for this information. Closes #23566. - - - - - bf9ec3e4 by Bryan Richter at 2023-06-28T12:25:33-04:00 Remove extraneous debug output - - - - - 7eb68dd6 by Bryan Richter at 2023-06-28T12:25:33-04:00 Work with unset vars in -e mode - - - - - 49c27936 by Bryan Richter at 2023-06-28T12:25:33-04:00 Pass positional arguments in their positions By quoting $cmd, the default "bash -i" is a single argument to run, and no file named "bash -i" actually exists to be run. - - - - - 887dc4fc by Bryan Richter at 2023-06-28T12:25:33-04:00 Handle unset value in -e context - - - - - 5ffc7d7b by Rodrigo Mesquita at 2023-06-28T21:07:36-04:00 Configure CPP into settings There is a distinction to be made between the Haskell Preprocessor and the C preprocessor. The former is used to preprocess Haskell files, while the latter is used in C preprocessing such as Cmm files. In practice, they are both the same program (usually the C compiler) but invoked with different flags. Previously we would, at configure time, configure the haskell preprocessor and save the configuration in the settings file, but, instead of doing the same for CPP, we had hardcoded in GHC that the CPP program was either `cc -E` or `cpp`. This commit fixes that asymmetry by also configuring CPP at configure time, and tries to make more explicit the difference between HsCpp and Cpp (see Note [Preprocessing invocations]). Note that we don't use the standard CPP and CPPFLAGS to configure Cpp, but instead use the non-standard --with-cpp and --with-cpp-flags. The reason is that autoconf sets CPP to "$CC -E", whereas we expect the CPP command to be configured as a standalone executable rather than a command. These are symmetrical with --with-hs-cpp and --with-hs-cpp-flags. Cleanup: Hadrian no longer needs to pass the CPP configuration for CPP to be C99 compatible through -optP, since we now configure that into settings. Closes #23422 - - - - - 5efa9ca5 by Ben Gamari at 2023-06-28T21:08:13-04:00 hadrian: Always canonicalize topDirectory Hadrian's `topDirectory` is intended to provide an absolute path to the root of the GHC tree. However, if the tree is reached via a symlink this One question here is whether the `canonicalizePath` call is expensive enough to warrant caching. In a quick microbenchmark I observed that `canonicalizePath "."` takes around 10us per call; this seems sufficiently low not to worry. Alternatively, another approach here would have been to rather move the canonicalization into `m4/fp_find_root.m4`. This would have avoided repeated canonicalization but sadly path canonicalization is a hard problem in POSIX shell. Addresses #22451. - - - - - b3e1436f by aadaa_fgtaa at 2023-06-28T21:08:53-04:00 Optimise ELF linker (#23464) - cache last elements of `relTable`, `relaTable` and `symbolTables` in `ocInit_ELF` - cache shndx table in ObjectCode - run `checkProddableBlock` only with debug rts - - - - - 30525b00 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Introduce MO_{ACQUIRE,RELEASE}_FENCE - - - - - b787e259 by Ben Gamari at 2023-06-28T21:09:30-04:00 compiler: Drop MO_WriteBarrier rts: Drop write_barrier - - - - - 7550b4a5 by Ben Gamari at 2023-06-28T21:09:30-04:00 rts: Drop load_store_barrier() This is no longer used. - - - - - d5f2875e by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop last instances of prim_{write,read}_barrier - - - - - 965ac2ba by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Eliminate remaining uses of load_load_barrier - - - - - 0fc5cb97 by Sven Tennie at 2023-06-28T21:09:31-04:00 compiler: Drop MO_ReadBarrier - - - - - 7a7d326c by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Drop load_load_barrier This is no longer used. - - - - - 9f63da66 by Sven Tennie at 2023-06-28T21:09:31-04:00 Delete write_barrier function - - - - - bb0ed354 by Ben Gamari at 2023-06-28T21:09:31-04:00 rts: Make collectFreshWeakPtrs definition a prototype x86-64/Darwin's toolchain inexplicably warns that collectFreshWeakPtrs needs to be a prototype. - - - - - ef81a1eb by Sven Tennie at 2023-06-28T21:10:08-04:00 Fix number of free double regs D1..D4 are defined for aarch64 and thus not free. - - - - - c335fb7c by Ryan Scott at 2023-06-28T21:10:44-04:00 Fix typechecking of promoted empty lists The `'[]` case in `tc_infer_hs_type` is smart enough to handle arity-0 uses of `'[]` (see the newly added `T23543` test case for an example), but the `'[]` case in `tc_hs_type` was not. We fix this by changing the `tc_hs_type` case to invoke `tc_infer_hs_type`, as prescribed in `Note [Future-proofing the type checker]`. There are some benign changes to test cases' expected output due to the new code path using `forall a. [a]` as the kind of `'[]` rather than `[k]`. Fixes #23543. - - - - - fcf310e7 by Rodrigo Mesquita at 2023-06-28T21:11:21-04:00 Configure MergeObjs supports response files rather than Ld The previous configuration script to test whether Ld supported response files was * Incorrect (see #23542) * Used, in practice, to check if the *merge objects tool* supported response files. This commit modifies the macro to run the merge objects tool (rather than Ld), using a response file, and checking the result with $NM Fixes #23542 - - - - - 78b2f3cc by Sylvain Henry at 2023-06-28T21:12:02-04:00 JS: fix JS stack printing (#23565) - - - - - 9f01d14b by Matthew Pickering at 2023-06-29T04:13:41-04:00 Add -fpolymorphic-specialisation flag (off by default at all optimisation levels) Polymorphic specialisation has led to a number of hard to diagnose incorrect runtime result bugs (see #23469, #23109, #21229, #23445) so this commit introduces a flag `-fpolymorhphic-specialisation` which allows users to turn on this experimental optimisation if they are willing to buy into things going very wrong. Ticket #23469 - - - - - b1e611d5 by Ben Gamari at 2023-06-29T04:14:17-04:00 Rip out runtime linker/compiler checks We used to choose flags to pass to the toolchain at runtime based on the platform running GHC, and in this commit we drop all of those runtime linker checks Ultimately, this represents a change in policy: We no longer adapt at runtime to the toolchain being used, but rather make final decisions about the toolchain used at /configure time/ (we have deleted Note [Run-time linker info] altogether!). This works towards the goal of having all toolchain configuration logic living in the same place, which facilities the work towards a runtime-retargetable GHC (see #19877). As of this commit, the runtime linker/compiler logic was moved to autoconf, but soon it, and the rest of the existing toolchain configuration logic, will live in the standalone ghc-toolchain program (see !9263) In particular, what used to be done at runtime is now as follows: * The flags -Wl,--no-as-needed for needed shared libs are configured into settings * The flag -fstack-check is configured into settings * The check for broken tables-next-to-code was outdated * We use the configured c compiler by default as the assembler program * We drop `asmOpts` because we already configure -Qunused-arguments flag into settings (see !10589) Fixes #23562 Co-author: Rodrigo Mesquita (@alt-romes) - - - - - 8b35e8ca by Ben Gamari at 2023-06-29T18:46:12-04:00 Define FFI_GO_CLOSURES The libffi shipped with Apple's XCode toolchain does not contain a definition of the FFI_GO_CLOSURES macro, despite containing references to said macro. Work around this by defining the macro, following the model of a similar workaround in OpenJDK [1]. [1] https://github.com/openjdk/jdk17u-dev/pull/741/files - - - - - d7ef1704 by Ben Gamari at 2023-06-29T18:46:12-04:00 base: Fix incorrect CPP guard This was guarded on `darwin_HOST_OS` instead of `defined(darwin_HOST_OS)`. - - - - - 7c7d1f66 by Ben Gamari at 2023-06-29T18:46:48-04:00 rts/Trace: Ensure that debugTrace arguments are used As debugTrace is a macro we must take care to ensure that the fact is clear to the compiler lest we see warnings. - - - - - cb92051e by Ben Gamari at 2023-06-29T18:46:48-04:00 rts: Various warnings fixes - - - - - dec81dd1 by Ben Gamari at 2023-06-29T18:46:48-04:00 hadrian: Ignore warnings in unix and semaphore-compat - - - - - d7f6448a by Matthew Pickering at 2023-06-30T12:38:43-04:00 hadrian: Fix dependencies of docs:* rule For the docs:* rule we need to actually build the package rather than just the haddocks for the dependent packages. Therefore we depend on the .conf files of the packages we are trying to build documentation for as well as the .haddock files. Fixes #23472 - - - - - cec90389 by sheaf at 2023-06-30T12:39:27-04:00 Add tests for #22106 Fixes #22106 - - - - - 083794b1 by Torsten Schmits at 2023-07-03T03:27:27-04:00 Add -fbreak-points to control breakpoint insertion Rather than statically enabling breakpoints only for the interpreter, this adds a new flag. Tracking ticket: #23057 MR: !10466 - - - - - fd8c5769 by Ben Gamari at 2023-07-03T03:28:04-04:00 rts: Ensure that pinned allocations respect block size Previously, it was possible for pinned, aligned allocation requests to allocate beyond the end of the pinned accumulator block. Specifically, we failed to account for the padding needed to achieve the requested alignment in the "large object" check. With large alignment requests, this can result in the allocator using the capability's pinned object accumulator block to service a request which is larger than `PINNED_EMPTY_SIZE`. To fix this we reorganize `allocatePinned` to consistently account for the alignment padding in all large object checks. This is a bit subtle as we must handle the case of a small allocation request filling the accumulator block, as well as large requests. Fixes #23400. - - - - - 98185d52 by Ben Gamari at 2023-07-03T03:28:05-04:00 testsuite: Add test for #23400 - - - - - 4aac0540 by Ben Gamari at 2023-07-03T03:28:42-04:00 ghc-heap: Support for BLOCKING_QUEUE closures - - - - - 03f941f4 by Ben Bellick at 2023-07-03T03:29:29-04:00 Add some structured diagnostics in Tc/Validity.hs This addresses the work of ticket #20118 Created the following constructors for TcRnMessage - TcRnInaccessibleCoAxBranch - TcRnPatersonCondFailure - - - - - 6074cc3c by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Add failing test case for #23492 - - - - - 356a2692 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Use generated src span for catch-all case of record selector functions This fixes #23492. The problem was that we used the real source span of the field declaration for the generated catch-all case in the selector function, in particular in the generated call to `recSelError`, which meant it was included in the HIE output. Using `generatedSrcSpan` instead means that it is not included. - - - - - 3efe7f39 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Introduce genLHsApp and genLHsLit helpers in GHC.Rename.Utils - - - - - dd782343 by Moisés Ackerman at 2023-07-03T03:30:13-04:00 Construct catch-all default case using helpers GHC.Rename.Utils concrete helpers instead of wrapGenSpan + HS AST constructors - - - - - 0e09c38e by Ryan Hendrickson at 2023-07-03T03:30:56-04:00 Add regression test for #23549 - - - - - 32741743 by Alexis King at 2023-07-03T03:31:36-04:00 perf tests: Increase default stack size for MultiLayerModules An unhelpfully small stack size appears to have been the real culprit behind the metric fluctuations in #19293. Debugging metric decreases triggered by !10729 helped to finally identify the problem. Metric Decrease: MultiLayerModules MultiLayerModulesTH_Make T13701 T14697 - - - - - 82ac6bf1 by Bryan Richter at 2023-07-03T03:32:15-04:00 Add missing void prototypes to rts functions See #23561. - - - - - 6078b429 by Ben Gamari at 2023-07-03T03:32:51-04:00 gitlab-ci: Refactor compilation of gen_ci Flakify and document it, making it far less sensitive to the build environment. - - - - - aa2db0ae by Ben Gamari at 2023-07-03T03:33:29-04:00 testsuite: Update documentation - - - - - 924a2362 by Gregory Gerasev at 2023-07-03T03:34:10-04:00 Better error for data deriving of type synonym/family. Closes #23522 - - - - - 4457da2a by Dave Barton at 2023-07-03T03:34:51-04:00 Fix some broken links and typos - - - - - de5830d0 by Ben Gamari at 2023-07-04T22:03:59-04:00 configure: Rip out Solaris dyld check Solaris 11 was released over a decade ago and, moreover, I doubt we have any Solaris users - - - - - 59c5fe1d by doyougnu at 2023-07-04T22:04:56-04:00 CI: add JS release and debug builds, regen CI jobs - - - - - 679bbc97 by Vladislav Zavialov at 2023-07-04T22:05:32-04:00 testsuite: Do not require CUSKs Numerous tests make use of CUSKs (complete user-supplied kinds), a legacy feature scheduled for deprecation. In order to proceed with the said deprecation, the tests have been updated to use SAKS instead (standalone kind signatures). This also allows us to remove the Haskell2010 language pragmas that were added in 115cd3c85a8 to work around the lack of CUSKs in GHC2021. - - - - - 945d3599 by Ben Gamari at 2023-07-04T22:06:08-04:00 gitlab: Drop backport-for-8.8 MR template Its usefulness has long passed. - - - - - 66c721d3 by Alan Zimmerman at 2023-07-04T22:06:44-04:00 EPA: Simplify GHC/Parser.y comb2 Use the HasLoc instance from Ast.hs to allow comb2 to work with anything with a SrcSpan This gets rid of the custom comb2A, comb2Al, comb2N functions, and removes various reLoc calls. - - - - - 2be99b7e by Matthew Pickering at 2023-07-04T22:07:21-04:00 Fix deprecation warning when deprecated identifier is from another module A stray 'Just' was being printed in the deprecation message. Fixes #23573 - - - - - 46c9bcd6 by Ben Gamari at 2023-07-04T22:07:58-04:00 rts: Don't rely on initializers for sigaction_t As noted in #23577, CentOS's ancient toolchain throws spurious missing-field-initializer warnings. - - - - - ec55035f by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Don't treat -Winline warnings as fatal Such warnings are highly dependent upon the toolchain, platform, and build configuration. It's simply too fragile to rely on these. - - - - - 3a09b789 by Ben Gamari at 2023-07-04T22:07:58-04:00 hadrian: Only pass -Wno-nonportable-include-path on Darwin This flag, which was introduced due to #17798, is only understood by Clang and consequently throws warnings on platforms using gcc. Sadly, there is no good way to treat such warnings as non-fatal with `-Werror` so for now we simply make this flag specific to platforms known to use Clang and case-insensitive filesystems (Darwin and Windows). See #23577. - - - - - 4af7eac2 by Mario Blažević at 2023-07-04T22:08:38-04:00 Fixed ticket #23571, TH.Ppr.pprLit hanging on large numeric literals - - - - - 2304c697 by Ben Gamari at 2023-07-04T22:09:15-04:00 compiler: Make OccSet opaque - - - - - cf735db8 by Andrei Borzenkov at 2023-07-04T22:09:51-04:00 Add Note about why we need forall in Code to be on the right - - - - - fb140f82 by Hécate Moonlight at 2023-07-04T22:10:34-04:00 Relax the constraint about the foreign function's calling convention of FinalizerPtr to capi as well as ccall. - - - - - 9ce44336 by meooow25 at 2023-07-05T11:42:37-04:00 Improve the situation with the stimes cycle Currently the Semigroup stimes cycle is resolved in GHC.Base by importing stimes implementations from a hs-boot file. Resolve the cycle using hs-boot files for required classes (Num, Integral) instead. Now stimes can be defined directly in GHC.Base, making inlining and specialization possible. This leads to some new boot files for `GHC.Num` and `GHC.Real`, the methods for those are only used to implement `stimes` so it doesn't appear that these boot files will introduce any new performance traps. Metric Decrease: T13386 T8095 Metric Increase: T13253 T13386 T18698a T18698b T19695 T8095 - - - - - 9edcb1fb by Jaro Reinders at 2023-07-05T11:43:24-04:00 Refactor Unique to be represented by Word64 In #22010 we established that Int was not always sufficient to store all the uniques we generate during compilation on 32-bit platforms. This commit addresses that problem by using Word64 instead of Int for uniques. The core of the change is in GHC.Core.Types.Unique and GHC.Core.Types.Unique.Supply. However, the representation of uniques is used in many other places, so those needed changes too. Additionally, the RTS has been extended with an atomic_inc64 operation. One major change from this commit is the introduction of the Word64Set and Word64Map data types. These are adapted versions of IntSet and IntMap from the containers package. These are planned to be upstreamed in the future. As a natural consequence of these changes, the compiler will be a bit slower and take more space on 32-bit platforms. Our CI tests indicate around a 5% residency increase. Metric Increase: CoOpt_Read CoOpt_Singletons LargeRecord ManyAlternatives ManyConstructors MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot RecordUpdPerf T10421 T10547 T12150 T12227 T12234 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T13386 T13719 T14683 T14697 T14766 T15164 T15703 T16577 T16875 T17516 T18140 T18223 T18282 T18304 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T3294 T4801 T5030 T5321FD T5321Fun T5631 T5642 T5837 T6048 T783 T8095 T9020 T9198 T9233 T9630 T9675 T9872a T9872b T9872b_defer T9872c T9872d T9961 TcPlugin_RewritePerf UniqLoop WWRec hard_hole_fits - - - - - 6b9db7d4 by Brandon Chinn at 2023-07-05T11:44:03-04:00 Fix docs for __GLASGOW_HASKELL_FULL_VERSION__ macro - - - - - 40f4ef7c by Torsten Schmits at 2023-07-05T18:06:19-04:00 Substitute free variables captured by breakpoints in SpecConstr Fixes #23267 - - - - - 2b55cb5f by sheaf at 2023-07-05T18:07:07-04:00 Reinstate untouchable variable error messages This extra bit of information was accidentally being discarded after a refactoring of the way we reported problems when unifying a type variable with another type. This patch rectifies that. - - - - - 53ed21c5 by Rodrigo Mesquita at 2023-07-05T18:07:47-04:00 configure: Drop Clang command from settings Due to 01542cb7227614a93508b97ecad5b16dddeb6486 we no longer use the `runClang` function, and no longer need to configure into settings the Clang command. We used to determine options at runtime to pass clang when it was used as an assembler, but now that we configure at configure time we no longer need to. - - - - - 6fdcf969 by Torsten Schmits at 2023-07-06T12:12:09-04:00 Filter out nontrivial substituted expressions in substTickish Fixes #23272 - - - - - 41968fd6 by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: testsuite: use req_c predicate instead of js_broken - - - - - 74a4dd2e by Sylvain Henry at 2023-07-06T12:13:02-04:00 JS: implement some file primitives (lstat,rmdir) (#22374) - Implement lstat and rmdir. - Implement base_c_s_is* functions (testing a file type) - Enable passing tests - - - - - 7e759914 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: cleanup utils (#23314) - Removed unused code - Don't export unused functions - Move toTypeList to Closure module - - - - - f617655c by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: rename VarType/Vt into JSRep - - - - - 19216ca5 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: remove custom PrimRep conversion (#23314) We use the usual conversion to PrimRep and then we convert these PrimReps to JSReps. - - - - - d3de8668 by Sylvain Henry at 2023-07-07T02:39:38-04:00 JS: don't use isRuntimeRepKindedTy in JS FFI - - - - - 8d1b75cb by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Also updates ghcup-nightlies-0.0.7.yaml file Fixes #23600 - - - - - e524fa7f by Matthew Pickering at 2023-07-07T02:40:15-04:00 ghcup-metadata: Use dynamically linked alpine bindists In theory these will work much better on alpine to allow people to build statically linked applications there. We don't need to distribute a statically linked application ourselves in order to allow that. Fixes #23602 - - - - - b9e7beb9 by Ben Gamari at 2023-07-07T11:32:22-04:00 Drop circle-ci-job.sh - - - - - 9955eead by Ben Gamari at 2023-07-07T11:32:22-04:00 testsuite: Allow preservation of unexpected output Here we introduce a new flag to the testsuite driver, --unexpected-output-dir=<dir>, which allows the user to ask the driver to preserve unexpected output from tests. The intent is for this to be used in CI to allow users to more easily fix unexpected platform-dependent output. - - - - - 48f80968 by Ben Gamari at 2023-07-07T11:32:22-04:00 gitlab-ci: Preserve unexpected output Here we enable use of the testsuite driver's `--unexpected-output-dir` flag by CI, preserving the result as an artifact for use by users. - - - - - 76983a0d by Matthew Pickering at 2023-07-07T11:32:58-04:00 driver: Fix -S with .cmm files There was an oversight in the driver which assumed that you would always produce a `.o` file when compiling a .cmm file. Fixes #23610 - - - - - 6df15e93 by Mike Pilgrem at 2023-07-07T11:33:40-04:00 Update Hadrian's stack.yaml - - - - - 1dff43cf by Ben Gamari at 2023-07-08T05:05:37-04:00 compiler: Rework ShowSome Previously the field used to filter the sub-declarations to show was rather ad-hoc and was only able to show at most one sub-declaration. - - - - - 8165404b by Ben Gamari at 2023-07-08T05:05:37-04:00 testsuite: Add test to catch changes in core libraries This adds testing infrastructure to ensure that changes in core libraries (e.g. `base` and `ghc-prim`) are caught in CI. - - - - - ec1c32e2 by Melanie Phoenix at 2023-07-08T05:06:14-04:00 Deprecate Data.List.NonEmpty.unzip - - - - - 5d2442b8 by Ben Gamari at 2023-07-08T05:06:51-04:00 Drop latent mentions of -split-objs Closes #21134. - - - - - a9bc20cb by Oleg Grenrus at 2023-07-08T05:07:31-04:00 Add warn_and_run test kind This is a compile_and_run variant which also captures the GHC's stderr. The warn_and_run name is best I can come up with, as compile_and_run is taken. This is useful specifically for testing warnings. We want to test that when warning triggers, and it's not a false positive, i.e. that the runtime behaviour is indeed "incorrect". As an example a single test is altered to use warn_and_run - - - - - c7026962 by Ben Gamari at 2023-07-08T05:08:11-04:00 configure: Don't use ld.gold on i386 ld.gold appears to produce invalid static constructor tables on i386. While ideally we would add an autoconf check to check for this brokenness, sadly such a check isn't easy to compose. Instead to summarily reject such linkers on i386. Somewhat hackily closes #23579. - - - - - 054261dd by Andrew Lelechenko at 2023-07-08T19:32:47-04:00 Add since annotations for Data.Foldable1 - - - - - 550af505 by Sylvain Henry at 2023-07-08T19:33:28-04:00 JS: support -this-unit-id for programs in the linker (#23613) - - - - - d284470a by Andrew Lelechenko at 2023-07-08T19:34:08-04:00 Bump text submodule - - - - - 8e11630e by jade at 2023-07-10T16:58:40-04:00 Add a hint to enable ExplicitNamespaces for type operator imports (Fixes/Enhances #20007) As suggested in #20007 and implemented in !8895, trying to import type operators will suggest a fix to use the 'type' keyword, without considering whether ExplicitNamespaces is enabled. This patch will query whether ExplicitNamespaces is enabled and add a hint to suggest enabling ExplicitNamespaces if it isn't enabled, alongside the suggestion of adding the 'type' keyword. - - - - - 61b1932e by sheaf at 2023-07-10T16:59:26-04:00 tyThingLocalGREs: include all DataCons for RecFlds The GREInfo for a record field should include the collection of all the data constructors of the parent TyCon that have this record field. This information was being incorrectly computed in the tyThingLocalGREs function for a DataCon, as we were not taking into account other DataCons with the same parent TyCon. Fixes #23546 - - - - - e6627cbd by Alan Zimmerman at 2023-07-10T17:00:05-04:00 EPA: Simplify GHC/Parser.y comb3 A follow up to !10743 - - - - - ee20da34 by Andrew Lelechenko at 2023-07-10T17:01:01-04:00 Document that compareByteArrays# is available since ghc-prim-0.5.2.0 - - - - - 4926af7b by Matthew Pickering at 2023-07-10T17:01:38-04:00 Revert "Bump text submodule" This reverts commit d284470a77042e6bc17bdb0ab0d740011196958a. This commit requires that we bootstrap with ghc-9.4, which we do not require until #23195 has been completed. Subsequently this has broken nighty jobs such as the rocky8 job which in turn has broken nightly releases. - - - - - d1c92bf3 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Fingerprint more code generation flags Previously our recompilation check was quite inconsistent in its coverage of non-optimisation code generation flags. Specifically, we failed to account for most flags that would affect the behavior of generated code in ways that might affect the result of a program's execution (e.g. `-feager-blackholing`, `-fstrict-dicts`) Closes #23369. - - - - - eb623149 by Ben Gamari at 2023-07-11T08:07:02-04:00 compiler: Record original thunk info tables on stack Here we introduce a new code generation option, `-forig-thunk-info`, which ensures that an `stg_orig_thunk_info` frame is pushed before every update frame. This can be invaluable when debugging thunk cycles and similar. See Note [Original thunk info table frames] for details. Closes #23255. - - - - - 4731f44e by Jaro Reinders at 2023-07-11T08:07:40-04:00 Fix wrong MIN_VERSION_GLASGOW_HASKELL macros I forgot to change these after rebasing. - - - - - dd38aca9 by Andreas Schwab at 2023-07-11T13:55:56+00:00 Hadrian: enable GHCi support on riscv64 - - - - - 09a5c6cc by Josh Meredith at 2023-07-12T11:25:13-04:00 JavaScript: support unicode code points > 2^16 in toJSString using String.fromCodePoint (#23628) - - - - - 29fbbd4e by Matthew Pickering at 2023-07-12T11:25:49-04:00 Remove references to make build system in mk/build.mk Fixes #23636 - - - - - 630e3026 by sheaf at 2023-07-12T11:26:43-04:00 Valid hole fits: don't panic on a Given The function GHC.Tc.Errors.validHoleFits would end up panicking when encountering a Given constraint. To fix this, it suffices to filter out the Givens before continuing. Fixes #22684 - - - - - c39f279b by Matthew Pickering at 2023-07-12T23:18:38-04:00 Use deb10 for i386 bindists deb9 is now EOL so it's time to upgrade the i386 bindist to use deb10 Fixes #23585 - - - - - bf9b9de0 by Krzysztof Gogolewski at 2023-07-12T23:19:15-04:00 Fix #23567, a specializer bug Found by Simon in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507834 The testcase isn't ideal because it doesn't detect the bug in master, unless doNotUnbox is removed as in https://gitlab.haskell.org/ghc/ghc/-/issues/23567#note_507692. But I have confirmed that with that modification, it fails before and passes afterwards. - - - - - 84c1a4a2 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 Comments - - - - - b2846cb5 by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 updates to comments - - - - - 2af23f0e by Bartłomiej Cieślar at 2023-07-12T23:20:08-04:00 changes - - - - - 6143838a by sheaf at 2023-07-13T08:02:17-04:00 Fix deprecation of record fields Commit 3f374399 inadvertently broke the deprecation/warning mechanism for record fields due to its introduction of record field namespaces. This patch ensures that, when a top-level deprecation is applied to an identifier, it applies to all the record fields as well. This is achieved by refactoring GHC.Rename.Env.lookupLocalTcNames, and GHC.Rename.Env.lookupBindGroupOcc, to not look up a fixed number of NameSpaces but to look up all NameSpaces and filter out the irrelevant ones. - - - - - 6fd8f566 by sheaf at 2023-07-13T08:02:17-04:00 Introduce greInfo, greParent These are simple helper functions that wrap the internal field names gre_info, gre_par. - - - - - 7f0a86ed by sheaf at 2023-07-13T08:02:17-04:00 Refactor lookupGRE_... functions This commit consolidates all the logic for looking up something in the Global Reader Environment into the single function lookupGRE. This allows us to declaratively specify all the different modes of looking up in the GlobalRdrEnv, and avoids manually passing around filtering functions as was the case in e.g. the function GHC.Rename.Env.lookupSubBndrOcc_helper. ------------------------- Metric Decrease: T8095 ------------------------- ------------------------- Metric Increase: T8095 ------------------------- - - - - - 5e951395 by Rodrigo Mesquita at 2023-07-13T08:02:54-04:00 configure: Drop DllWrap command We used to configure into settings a DllWrap command for windows builds and distributions, however, we no longer do, and dllwrap is effectively unused. This simplification is motivated in part by the larger toolchain-selection project (#19877, !9263) - - - - - e10556b6 by Teo Camarasu at 2023-07-14T16:28:46-04:00 base: fix haddock syntax in GHC.Profiling - - - - - 0f3fda81 by Matthew Pickering at 2023-07-14T16:29:23-04:00 Revert "CI: add JS release and debug builds, regen CI jobs" This reverts commit 59c5fe1d4b624423b1c37891710f2757bb58d6af. This commit added two duplicate jobs on all validate pipelines, so we are reverting for now whilst we work out what the best way forward is. Ticket #23618 - - - - - 54bca324 by Alan Zimmerman at 2023-07-15T03:23:26-04:00 EPA: Simplify GHC/Parser.y sLL Follow up to !10743 - - - - - c8863828 by sheaf at 2023-07-15T03:24:06-04:00 Configure: canonicalise PythonCmd on Windows This change makes PythonCmd resolve to a canonical absolute path on Windows, which prevents HLS getting confused (now that we have a build-time dependency on python). fixes #23652 - - - - - ca1e636a by Rodrigo Mesquita at 2023-07-15T03:24:42-04:00 Improve Note [Binder-swap during float-out] - - - - - cf86f3ec by Matthew Craven at 2023-07-16T01:42:09+02:00 Equality of forall-types is visibility aware This patch finally (I hope) nails the question of whether (forall a. ty) and (forall a -> ty) are `eqType`: they aren't! There is a long discussion in #22762, plus useful Notes: * Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare * Note [Comparing visiblities] in GHC.Core.TyCo.Compare * Note [ForAllCo] in GHC.Core.TyCo.Rep It also establishes a helpful new invariant for ForAllCo, and ForAllTy, when the bound variable is a CoVar:in that case the visibility must be coreTyLamForAllTyFlag. All this is well documented in revised Notes. - - - - - 7f13acbf by Vladislav Zavialov at 2023-07-16T01:56:27-04:00 List and Tuple<n>: update documentation Add the missing changelog.md entries and @since-annotations. - - - - - 2afbddb0 by Andrei Borzenkov at 2023-07-16T10:21:24+04:00 Type patterns (#22478, #18986) Improved name resolution and type checking of type patterns in constructors: 1. HsTyPat: a new dedicated data type that represents type patterns in HsConPatDetails instead of reusing HsPatSigType 2. rnHsTyPat: a new function that renames a type pattern and collects its binders into three groups: - explicitly bound type variables, excluding locally bound variables - implicitly bound type variables from kind signatures (only if ScopedTypeVariables are enabled) - named wildcards (only from kind signatures) 2a. rnHsPatSigTypeBindingVars: removed in favour of rnHsTyPat 2b. rnImplcitTvBndrs: removed because no longer needed 3. collect_pat: updated to collect type variable binders from type patterns (this means that types and terms use the same infrastructure to detect conflicting bindings, unused variables and name shadowing) 3a. CollVarTyVarBinders: a new CollectFlag constructor that enables collection of type variables 4. tcHsTyPat: a new function that typechecks type patterns, capable of handling polymorphic kinds. See Note [Type patterns: binders and unifiers] Examples of code that is now accepted: f = \(P @a) -> \(P @a) -> ... -- triggers -Wname-shadowing g :: forall a. Proxy a -> ... g (P @a) = ... -- also triggers -Wname-shadowing h (P @($(TH.varT (TH.mkName "t")))) = ... -- t is bound at splice time j (P @(a :: (x,x))) = ... -- (x,x) is no longer rejected data T where MkT :: forall (f :: forall k. k -> Type). f Int -> f Maybe -> T k :: T -> () k (MkT @f (x :: f Int) (y :: f Maybe)) = () -- f :: forall k. k -> Type Examples of code that is rejected with better error messages: f (Left @a @a _) = ... -- new message: -- • Conflicting definitions for ‘a’ -- Bound at: Test.hs:1:11 -- Test.hs:1:14 Examples of code that is now rejected: {-# OPTIONS_GHC -Werror=unused-matches #-} f (P @a) = () -- Defined but not used: type variable ‘a’ - - - - - eb1a6ab1 by sheaf at 2023-07-16T09:20:45-04:00 Don't use substTyUnchecked in newMetaTyVar There were some comments that explained that we needed to use an unchecked substitution function because of issue #12931, but that has since been fixed, so we should be able to use substTy instead now. - - - - - c7bbad9a by sheaf at 2023-07-17T02:48:19-04:00 rnImports: var shouldn't import NoFldSelectors In an import declaration such as import M ( var ) the import of the variable "var" should **not** bring into scope record fields named "var" which are defined with NoFieldSelectors. Doing so can cause spurious "unused import" warnings, as reported in ticket #23557. Fixes #23557 - - - - - 1af2e773 by sheaf at 2023-07-17T02:48:19-04:00 Suggest similar names in imports This commit adds similar name suggestions when importing. For example module A where { spelling = 'o' } module B where { import B ( speling ) } will give rise to the error message: Module ‘A’ does not export ‘speling’. Suggested fix: Perhaps use ‘spelling’ This also provides hints when users try to import record fields defined with NoFieldSelectors. - - - - - 654fdb98 by Alan Zimmerman at 2023-07-17T02:48:55-04:00 EPA: Store leading AnnSemi for decllist in al_rest This simplifies the markAnnListA implementation in ExactPrint - - - - - 22565506 by sheaf at 2023-07-17T21:12:59-04:00 base: add COMPLETE pragma to BufferCodec PatSyn This implements CLC proposal #178, rectifying an oversight in the implementation of CLC proposal #134 which could lead to spurious pattern match warnings. https://github.com/haskell/core-libraries-committee/issues/178 https://github.com/haskell/core-libraries-committee/issues/134 - - - - - 860f6269 by sheaf at 2023-07-17T21:13:00-04:00 exactprint: silence incomplete record update warnings - - - - - df706de3 by sheaf at 2023-07-17T21:13:00-04:00 Re-instate -Wincomplete-record-updates Commit e74fc066 refactored the handling of record updates to use the HsExpanded mechanism. This meant that the pattern matching inherent to a record update was considered to be "generated code", and thus we stopped emitting "incomplete record update" warnings entirely. This commit changes the "data Origin = Source | Generated" datatype, adding a field to the Generated constructor to indicate whether we still want to perform pattern-match checking. We also have to do a bit of plumbing with HsCase, to record that the HsCase arose from an HsExpansion of a RecUpd, so that the error message continues to mention record updates as opposed to a generic "incomplete pattern matches in case" error. Finally, this patch also changes the way we handle inaccessible code warnings. Commit e74fc066 was also a regression in this regard, as we were emitting "inaccessible code" warnings for case statements spuriously generated when desugaring a record update (remember: the desugaring mechanism happens before typechecking; it thus can't take into account e.g. GADT information in order to decide which constructors to include in the RHS of the desugaring of the record update). We fix this by changing the mechanism through which we disable inaccessible code warnings: we now check whether we are in generated code in GHC.Tc.Utils.TcMType.newImplication in order to determine whether to emit inaccessible code warnings. Fixes #23520 Updates haddock submodule, to avoid incomplete record update warnings - - - - - 1d05971e by sheaf at 2023-07-17T21:13:00-04:00 Propagate long-distance information in do-notation The preceding commit re-enabled pattern-match checking inside record updates. This revealed that #21360 was in fact NOT fixed by e74fc066. This commit makes sure we correctly propagate long-distance information in do blocks, e.g. in ```haskell data T = A { fld :: Int } | B f :: T -> Maybe T f r = do a at A{} <- Just r Just $ case a of { A _ -> A 9 } ``` we need to propagate the fact that "a" is headed by the constructor "A" to see that the case expression "case a of { A _ -> A 9 }" cannot fail. Fixes #21360 - - - - - bea0e323 by sheaf at 2023-07-17T21:13:00-04:00 Skip PMC for boring patterns Some patterns introduce no new information to the pattern-match checker (such as plain variable or wildcard patterns). We can thus skip doing any pattern-match checking on them when the sole purpose for doing so was introducing new long-distance information. See Note [Boring patterns] in GHC.Hs.Pat. Doing this avoids regressing in performance now that we do additional pattern-match checking inside do notation. - - - - - ddcdd88c by Rodrigo Mesquita at 2023-07-17T21:13:36-04:00 Split GHC.Platform.ArchOS from ghc-boot into ghc-platform Split off the `GHC.Platform.ArchOS` module from the `ghc-boot` package into this reinstallable standalone package which abides by the PVP, in part motivated by the ongoing work on `ghc-toolchain` towards runtime retargetability. - - - - - b55a8ea7 by Sylvain Henry at 2023-07-17T21:14:27-04:00 JS: better implementation for plusWord64 (#23597) - - - - - 889c2bbb by sheaf at 2023-07-18T06:37:32-04:00 Do primop rep-poly checks when instantiating This patch changes how we perform representation-polymorphism checking for primops (and other wired-in Ids such as coerce). When instantiating the primop, we check whether each type variable is required to instantiated to a concrete type, and if so we create a new concrete metavariable (a ConcreteTv) instead of a simple MetaTv. (A little subtlety is the need to apply the substitution obtained from instantiating to the ConcreteTvOrigins, see Note [substConcreteTvOrigin] in GHC.Tc.Utils.TcMType.) This allows us to prevent representation-polymorphism in non-argument position, as that is required for some of these primops. We can also remove the logic in tcRemainingValArgs, except for the part concerning representation-polymorphic unlifted newtypes. The function has been renamed rejectRepPolyNewtypes; all it does now is reject unsaturated occurrences of representation-polymorphic newtype constructors when the representation of its argument isn't a concrete RuntimeRep (i.e. still a PHASE 1 FixedRuntimeRep check). The Note [Eta-expanding rep-poly unlifted newtypes] in GHC.Tc.Gen.Head gives more explanation about a possible path to PHASE 2, which would be in line with the treatment for primops taken in this patch. We also update the Core Lint check to handle this new framework. This means Core Lint now checks representation-polymorphism in continuation position like needed for catch#. Fixes #21906 ------------------------- Metric Increase: LargeRecord ------------------------- - - - - - 00648e5d by Krzysztof Gogolewski at 2023-07-18T06:38:10-04:00 Core Lint: distinguish let and letrec in locations Lint messages were saying "in the body of letrec" even for non-recursive let. I've also renamed BodyOfLetRec to BodyOfLet in stg, since there's no separate letrec. - - - - - 787bae96 by Krzysztof Gogolewski at 2023-07-18T06:38:50-04:00 Use extended literals when deriving Show This implements GHC proposal https://github.com/ghc-proposals/ghc-proposals/pull/596 Also add support for Int64# and Word64#; see testcase ShowPrim. - - - - - 257f1567 by Jaro Reinders at 2023-07-18T06:39:29-04:00 Add StgFromCore and StgCodeGen linting - - - - - 34d08a20 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Strictness - - - - - c5deaa27 by Ben Gamari at 2023-07-19T03:33:22-04:00 Reg.Liveness: Don't repeatedly construct UniqSets - - - - - b947250b by Ben Gamari at 2023-07-19T03:33:22-04:00 compiler/Types: Ensure that fromList-type operations can fuse In #20740 I noticed that mkUniqSet does not fuse. In practice, allowing it to do so makes a considerable difference in allocations due to the backend. Metric Decrease: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 6c88c2ba by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 Codegen: Implement MO_S_MulMayOflo for W16 - - - - - 5f1154e0 by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: MO_S_MulMayOflo better error message for rep > W64 It's useful to see which value made the pattern match fail. (If it ever occurs.) - - - - - e8c9a95f by Sven Tennie at 2023-07-19T03:33:59-04:00 x86 CodeGen: Implement MO_S_MulMayOflo for W8 This case wasn't handled before. But, the test-primops test suite showed that it actually might appear. - - - - - a36f9dc9 by Sven Tennie at 2023-07-19T03:33:59-04:00 Add test for %mulmayoflo primop The test expects a perfect implementation with no false positives. - - - - - 38a36248 by Matthew Pickering at 2023-07-19T03:34:36-04:00 lint-ci-config: Generate jobs-metadata.json We also now save the jobs-metadata.json and jobs.yaml file as artifacts as: * It might be useful for someone who is modifying CI to copy jobs.yaml if they are having trouble regenerating locally. * jobs-metadata.json is very useful for downstream pipelines to work out the right job to download. Fixes #23654 - - - - - 1535a671 by Vladislav Zavialov at 2023-07-19T03:35:12-04:00 Initialize 9.10.1-notes.rst Create new release notes for the next GHC release (GHC 9.10) - - - - - 3bd4d5b5 by sheaf at 2023-07-19T03:35:53-04:00 Prioritise Parent when looking up class sub-binder When we look up children GlobalRdrElts of a given Parent, we sometimes would rather prioritise those GlobalRdrElts which have the right Parent, and sometimes prioritise those that have the right NameSpace: - in export lists, we should prioritise NameSpace - for class/instance binders, we should prioritise Parent See Note [childGREPriority] in GHC.Types.Name.Reader. fixes #23664 - - - - - 9c8fdda3 by Alan Zimmerman at 2023-07-19T03:36:29-04:00 EPA: Improve annotation management in getMonoBind Ensure the LHsDecl for a FunBind has the correct leading comments and trailing annotations. See the added note for details. - - - - - ff884b77 by Matthew Pickering at 2023-07-19T11:42:02+01:00 Remove unused files in .gitlab These were left over after 6078b429 - - - - - 29ef590c by Matthew Pickering at 2023-07-19T11:42:52+01:00 gen_ci: Add hie.yaml file This allows you to load `gen_ci.hs` into HLS, and now it is a huge module, that is quite useful. - - - - - 808b55cf by Matthew Pickering at 2023-07-19T12:24:41+01:00 ci: Make "fast-ci" the default validate configuration We are trying out a lighter weight validation pipeline where by default we just test on 5 platforms: * x86_64-deb10-slow-validate * windows * x86_64-fedora33-release * aarch64-darwin * aarch64-linux-deb10 In order to enable the "full" validation pipeline you can apply the `full-ci` label which will enable all the validation pipelines. All the validation jobs are still run on a marge batch. The goal is to reduce the overall CI capacity so that pipelines start faster for MRs and marge bot batches are faster. Fixes #23694 - - - - - 0b23db03 by Alan Zimmerman at 2023-07-20T05:28:47-04:00 EPA: Simplify GHC/Parser.y sL1 This is the next patch in a series simplifying location management in GHC/Parser.y This one simplifies sL1, to use the HasLoc instances introduced in !10743 (closed) - - - - - 3ece9856 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Explicitly set flags of text sections on Windows The binutils documentation (for COFF) claims, > If no flags are specified, the default flags depend upon the section > name. If the section name is not recognized, the default will be for the > section to be loaded and writable. We previously assumed that this would do the right thing for split sections (e.g. a section named `.text$foo` would be correctly inferred to be a text section). However, we have observed that this is not the case (at least under the clang toolchain used on Windows): when split-sections is enabled, text sections are treated by the assembler as data (matching the "default" behavior specified by the documentation). Avoid this by setting section flags explicitly. This should fix split sections on Windows. Fixes #22834. - - - - - db7f7240 by Ben Gamari at 2023-07-21T07:30:45-04:00 nativeGen: Set explicit section types on all platforms - - - - - b444c16f by Finley McIlwaine at 2023-07-21T07:31:28-04:00 Insert documentation into parsed signature modules Causes haddock comments in signature modules to be properly inserted into the AST (just as they are for regular modules) if the `-haddock` flag is given. Also adds a test that compares `-ddump-parsed-ast` output for a signature module to prevent further regressions. Fixes #23315 - - - - - c30cea53 by Ben Gamari at 2023-07-21T23:23:49-04:00 primops: Introduce unsafeThawByteArray# This addresses an odd asymmetry in the ByteArray# primops, which previously provided unsafeFreezeByteArray# but no corresponding thaw operation. Closes #22710 - - - - - 87f9bd47 by Ben Gamari at 2023-07-21T23:23:49-04:00 testsuite: Elaborate in interface stability README This discussion didn't make it into the original MR. - - - - - e4350b41 by Matthew Pickering at 2023-07-21T23:24:25-04:00 Allow users to override non-essential haddock options in a Flavour We now supply the non-essential options to haddock using the `extraArgs` field, which can be specified in a Flavour so that if an advanced user wants to change how documentation is generated then they can use something other than the `defaultHaddockExtraArgs`. This does have the potential to regress some packaging if a user has overridden `extraArgs` themselves, because now they also need to add the haddock options to extraArgs. This can easily be done by appending `defaultHaddockExtraArgs` to their extraArgs invocation but someone might not notice this behaviour has changed. In any case, I think passing the non-essential options in this manner is the right thing to do and matches what we do for the "ghc" builder, which by default doesn't pass any optmisation levels, and would likewise be very bad if someone didn't pass suitable `-O` levels for builds. Fixes #23625 - - - - - fc186b0c by Ilias Tsitsimpis at 2023-07-21T23:25:03-04:00 ghc-prim: Link against libatomic Commit b4d39adbb58 made 'hs_cmpxchg64()' available to all architectures. Unfortunately this made GHC to fail to build on armel, since armel needs libatomic to support atomic operations on 64-bit word sizes. Configure libraries/ghc-prim/ghc-prim.cabal to link against libatomic, the same way as we do in rts/rts.cabal. - - - - - 4f5538a8 by Matthew Pickering at 2023-07-21T23:25:39-04:00 simplifier: Correct InScopeSet in rule matching The in-scope set passedto the `exprIsLambda_maybe` call lacked all the in-scope binders. @simonpj suggests this fix where we augment the in-scope set with the free variables of expression which fixes this failure mode in quite a direct way. Fixes #23630 - - - - - 5ad8d597 by Krzysztof Gogolewski at 2023-07-21T23:26:17-04:00 Add a test for #23413 It was fixed by commit e1590ddc661d6: Add the SolverStage monad. - - - - - 7e05f6df by sheaf at 2023-07-21T23:26:56-04:00 Finish migration of diagnostics in GHC.Tc.Validity This patch finishes migrating the error messages in GHC.Tc.Validity to use the new diagnostic infrastructure. It also refactors the error message datatypes for class and family instances, to common them up under a single datatype as much as possible. - - - - - 4876fddc by Matthew Pickering at 2023-07-21T23:27:33-04:00 ci: Enable some more jobs to run in a marge batch In !10907 I made the majority of jobs not run on a validate pipeline but then forgot to renable a select few jobs on the marge batch MR. - - - - - 026991d7 by Jens Petersen at 2023-07-21T23:28:13-04:00 user_guide/flags.py: python-3.12 no longer includes distutils packaging.version seems able to handle this fine - - - - - b91bbc2b by Matthew Pickering at 2023-07-21T23:28:50-04:00 ci: Mention ~full-ci label in MR template We mention that if you need a full validation pipeline then you can apply the ~full-ci label to your MR in order to test against the full validation pipeline (like we do for marge). - - - - - 42b05e9b by sheaf at 2023-07-22T12:36:00-04:00 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 - - - - - a72015d6 by sheaf at 2023-07-22T12:36:01-04:00 Mark plugins-external as broken on Windows This test is broken on Windows, so we explicitly mark it as such now that we stop skipping plugin tests on Windows. - - - - - cb9c93d7 by sheaf at 2023-07-22T12:36:01-04:00 Stop marking plugin tests as fragile on Windows Now that b2bb3e62 has landed we are in a better situation with regards to plugins on Windows, allowing us to unmark many plugin tests as fragile. Fixes #16405 - - - - - a7349217 by Krzysztof Gogolewski at 2023-07-22T12:36:37-04:00 Misc cleanup - Remove unused RDR names - Fix typos in comments - Deriving: simplify boxConTbl and remove unused litConTbl - chmod -x GHC/Exts.hs, this seems accidental - - - - - 33b6850a by Vladislav Zavialov at 2023-07-23T10:27:37-04:00 Visible forall in types of terms: Part 1 (#22326) This patch implements part 1 of GHC Proposal #281, introducing explicit `type` patterns and `type` arguments. Summary of the changes: 1. New extension flag: RequiredTypeArguments 2. New user-facing syntax: `type p` patterns (represented by EmbTyPat) `type e` expressions (represented by HsEmbTy) 3. Functions with required type arguments (visible forall) can now be defined and applied: idv :: forall a -> a -> a -- signature (relevant change: checkVdqOK in GHC/Tc/Validity.hs) idv (type a) (x :: a) = x -- definition (relevant change: tcPats in GHC/Tc/Gen/Pat.hs) x = idv (type Int) 42 -- usage (relevant change: tcInstFun in GHC/Tc/Gen/App.hs) 4. template-haskell support: TH.TypeE corresponds to HsEmbTy TH.TypeP corresponds to EmbTyPat 5. Test cases and a new User's Guide section Changes *not* included here are the t2t (term-to-type) transformation and term variable capture; those belong to part 2. - - - - - 73b5c7ce by sheaf at 2023-07-23T10:28:18-04:00 Add test for #22424 This is a simple Template Haskell test in which we refer to record selectors by their exact Names, in two different ways. Fixes #22424 - - - - - 83cbc672 by Ben Gamari at 2023-07-24T07:40:49+00:00 ghc-toolchain: Initial commit - - - - - 31dcd26c by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 ghc-toolchain: Toolchain Selection This commit integrates ghc-toolchain, the brand new way of configuring toolchains for GHC, with the Hadrian build system, with configure, and extends and improves the first iteration of ghc-toolchain. The general overview is * We introduce a program invoked `ghc-toolchain --triple=...` which, when run, produces a file with a `Target`. A `GHC.Toolchain.Target.Target` describes the properties of a target and the toolchain (executables and configured flags) to produce code for that target * Hadrian was modified to read Target files, and will both * Invoke the toolchain configured in the Target file as needed * Produce a `settings` file for GHC based on the Target file for that stage * `./configure` will invoke ghc-toolchain to generate target files, but it will also generate target files based on the flags configure itself configured (through `.in` files that are substituted) * By default, the Targets generated by configure are still (for now) the ones used by Hadrian * But we additionally validate the Target files generated by ghc-toolchain against the ones generated by configure, to get a head start on catching configuration bugs before we transition completely. * When we make that transition, we will want to drop a lot of the toolchain configuration logic from configure, but keep it otherwise. * For each compiler stage we should have 1 target file (up to a stage compiler we can't run in our machine) * We just have a HOST target file, which we use as the target for stage0 * And a TARGET target file, which we use for stage1 (and later stages, if not cross compiling) * Note there is no BUILD target file, because we only support cross compilation where BUILD=HOST * (for more details on cross-compilation see discussion on !9263) See also * Note [How we configure the bundled windows toolchain] * Note [ghc-toolchain consistency checking] * Note [ghc-toolchain overview] Ticket: #19877 MR: !9263 - - - - - a732b6d3 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Add flag to enable/disable ghc-toolchain based configurations This flag is disabled by default, and we'll use the configure-generated-toolchains by default until we remove the toolchain configuration logic from configure. - - - - - 61eea240 by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Split ghc-toolchain executable to new packge In light of #23690, we split the ghc-toolchain executable out of the library package to be able to ship it in the bindist using Hadrian. Ideally, we eventually revert this commit. - - - - - 38e795ff by Rodrigo Mesquita at 2023-07-24T07:40:49+00:00 Ship ghc-toolchain in the bindist Add the ghc-toolchain binary to the binary distribution we ship to users, and teach the bindist configure to use the existing ghc-toolchain. - - - - - 32cae784 by Matthew Craven at 2023-07-24T16:48:24-04:00 Kill off gen_bytearray_addr_access_ops.py The relevant primop descriptions are now generated directly by genprimopcode. This makes progress toward fixing #23490, but it is not a complete fix since there is more than one way in which cabal-reinstall (hadrian/build build-cabal) is broken. - - - - - 02e6a6ce by Matthew Pickering at 2023-07-24T16:49:00-04:00 compiler: Remove unused `containers.h` include Fixes #23712 - - - - - 822ef66b by Matthew Pickering at 2023-07-25T08:44:50-04:00 Fix pretty printing of WARNING pragmas There is still something quite unsavoury going on with WARNING pragma printing because the printing relies on the fact that for decl deprecations the SourceText of WarningTxt is empty. However, I let that lion sleep and just fixed things directly. Fixes #23465 - - - - - e7b38ede by Matthew Pickering at 2023-07-25T08:45:28-04:00 ci-images: Bump to commit which has 9.6 image The test-bootstrap job has been failing for 9.6 because we accidentally used a non-master commit. - - - - - bb408936 by Matthew Pickering at 2023-07-25T08:45:28-04:00 Update bootstrap plans for 9.6.2 and 9.4.5 - - - - - 355e1792 by Alan Zimmerman at 2023-07-26T10:17:32-04:00 EPA: Simplify GHC/Parser.y comb4/comb5 Use the HasLoc instance from Ast.hs to allow comb4/comb5 to work with anything with a SrcSpan Also get rid of some more now unnecessary reLoc calls. - - - - - 9393df83 by Gavin Zhao at 2023-07-26T10:18:16-04:00 compiler: make -ddump-asm work with wasm backend NCG Fixes #23503. Now the `-ddump-asm` flag is respected in the wasm backend NCG, so developers can directly view the generated ASM instead of needing to pass `-S` or `-keep-tmp-files` and manually find & open the assembly file. Ideally, we should be able to output the assembly files in smaller chunks like in other NCG backends. This would also make dumping assembly stats easier. However, this would require a large refactoring, so for short-term debugging purposes I think the current approach works fine. Signed-off-by: Gavin Zhao <git at gzgz.dev> - - - - - 79463036 by Krzysztof Gogolewski at 2023-07-26T10:18:54-04:00 llvm: Restore accidentally deleted code in 0fc5cb97 Fixes #23711 - - - - - 20db7e26 by Rodrigo Mesquita at 2023-07-26T10:19:33-04:00 configure: Default missing options to False when preparing ghc-toolchain Targets This commit fixes building ghc with 9.2 as the boostrap compiler. The ghc-toolchain patch assumed all _STAGE0 options were available, and forgot to account for this missing information in 9.2. Ghc 9.2 does not have in settings whether ar supports -l, hence can't report it with --info (unliked 9.4 upwards). The fix is to default the missing information (we default "ar supports -l" and other missing options to False) - - - - - fac9e84e by Naïm Favier at 2023-07-26T10:20:16-04:00 docs: Fix typo - - - - - 503fd647 by Bartłomiej Cieślar at 2023-07-26T17:23:10-04:00 This MR is an implementation of the proposal #516. It adds a warning -Wincomplete-record-selectors for usages of a record field access function (either a record selector or getField @"rec"), while trying to silence the warning whenever it can be sure that a constructor without the record field would not be invoked (which would otherwise cause the program to fail). For example: data T = T1 | T2 {x :: Bool} f a = x a -- this would throw an error g T1 = True g a = x a -- this would not throw an error h :: HasField "x" r Bool => r -> Bool h = getField @"x" j :: T -> Bool j = h -- this would throw an error because of the `HasField` -- constraint being solved See the tests DsIncompleteRecSel* and TcIncompleteRecSel for more examples of the warning. See Note [Detecting incomplete record selectors] in GHC.HsToCore.Expr for implementation details - - - - - af6fdf42 by Arnaud Spiwack at 2023-07-26T17:23:52-04:00 Fix user-facing label in MR template - - - - - 5d45b92a by Matthew Pickering at 2023-07-27T05:46:46-04:00 ci: Test bootstrapping configurations with full-ci and on marge batches There have been two incidents recently where bootstrapping has been broken by removing support for building with 9.2.*. The process for bumping the minimum required version starts with bumping the configure version and then other CI jobs such as the bootstrap jobs have to be updated. We must not silently bump the minimum required version. Now we are running a slimmed down validate pipeline it seems worthwile to test these bootstrap configurations in the full-ci pipeline. - - - - - 25d4fee7 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Remove ghc-9_2_* plans We are anticipating shortly making it necessary to use ghc-9.4 to boot the compiler. - - - - - 2f66da16 by Matthew Pickering at 2023-07-27T05:46:46-04:00 Update bootstrap plans for ghc-platform and ghc-toolchain dependencies Fixes #23735 - - - - - c8c6eab1 by Matthew Pickering at 2023-07-27T05:46:46-04:00 bootstrap: Disable -selftest flag from bootstrap plans This saves on building one dependency (QuickCheck) which is unecessary for bootstrapping. - - - - - a80ca086 by Andrew Lelechenko at 2023-07-27T05:47:26-04:00 Link reference paper and package from System.Mem.{StableName,Weak} - - - - - a5319358 by David Knothe at 2023-07-28T13:13:10-04:00 Update Match Datatype EquationInfo currently contains a list of the equation's patterns together with a CoreExpr that is to be evaluated after a successful match on this equation. All the match-functions only operate on the first pattern of an equation - after successfully matching it, match is called recursively on the tail of the pattern list. We can express this more clearly and make the code a little more elegant by updating the datatype of EquationInfo as follows: data EquationInfo = EqnMatch { eqn_pat = Pat GhcTc, eqn_rest = EquationInfo } | EqnDone { eqn_rhs = MatchResult CoreExpr } An EquationInfo now explicitly exposes its first pattern which most functions operate on, and exposes the equation that remains after processing the first pattern. An EqnDone signifies an empty equation where the CoreExpr can now be evaluated. - - - - - 86ad1af9 by David Binder at 2023-07-28T13:13:53-04:00 Improve documentation for Data.Fixed - - - - - f8fa1d08 by Ben Gamari at 2023-07-28T13:14:31-04:00 ghc-prim: Use C11 atomics Previously `ghc-prim`'s atomic wrappers used the legacy `__sync_*` family of C builtins. Here we refactor these to rather use the appropriate C11 atomic equivalents, allowing us to be more explicit about the expected ordering semantics. - - - - - 0bfc8908 by Finley McIlwaine at 2023-07-28T18:46:26-04:00 Include -haddock in DynFlags fingerprint The -haddock flag determines whether or not the resulting .hi files contain haddock documentation strings. If the existing .hi files do not contain haddock documentation strings and the user requests them, we should recompile. - - - - - 40425c50 by Andreas Klebinger at 2023-07-28T18:47:02-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - e9a0fa3f by Andrew Lelechenko at 2023-07-28T18:47:42-04:00 Bump filepath submodule to 1.4.100.4 Resolves #23741 Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T12234 T12425 T13035 T13701 T13719 T16875 T18304 T18698a T18698b T21839c T9198 TcPlugin_RewritePerf hard_hole_fits Metric decrease on Windows can be probably attributed to https://github.com/haskell/filepath/pull/183 - - - - - ee93edfd by Andrew Lelechenko at 2023-07-28T18:48:21-04:00 Add since pragmas to GHC.IO.Handle.FD - - - - - d0369802 by Simon Peyton Jones at 2023-07-30T09:24:48+01:00 Make the occurrence analyser smarter about join points This MR addresses #22404. There is a big Note Note [Occurrence analysis for join points] that explains it all. Significant changes * New field occ_join_points in OccEnv * The NonRec case of occAnalBind splits into two cases: one for existing join points (which does the special magic for Note [Occurrence analysis for join points], and one for other bindings. * mkOneOcc adds in info from occ_join_points. * All "bring into scope" activity is centralised in the new function `addInScope`. * I made a local data type LocalOcc for use inside the occurrence analyser It is like OccInfo, but lacks IAmDead and IAmALoopBreaker, which in turn makes computationns over it simpler and more efficient. * I found quite a bit of allocation in GHC.Core.Rules.getRules so I optimised it a bit. More minor changes * I found I was using (Maybe Arity) a lot, so I defined a new data type JoinPointHood and used it everwhere. This touches a lot of non-occ-anal files, but it makes everything more perspicuous. * Renamed data constructor WithUsageDetails to WUD, and WithTailUsageDetails to WTUD This also fixes #21128, on the way. --------- Compiler perf ----------- I spent quite a time on performance tuning, so even though it does more than before, the occurrence analyser runs slightly faster on average. Here are the compile-time allocation changes over 0.5% CoOpt_Read(normal) ghc/alloc 766,025,520 754,561,992 -1.5% CoOpt_Singletons(normal) ghc/alloc 759,436,840 762,925,512 +0.5% LargeRecord(normal) ghc/alloc 1,814,482,440 1,799,530,456 -0.8% PmSeriesT(normal) ghc/alloc 68,159,272 67,519,720 -0.9% T10858(normal) ghc/alloc 120,805,224 118,746,968 -1.7% T11374(normal) ghc/alloc 164,901,104 164,070,624 -0.5% T11545(normal) ghc/alloc 79,851,808 78,964,704 -1.1% T12150(optasm) ghc/alloc 73,903,664 71,237,544 -3.6% GOOD T12227(normal) ghc/alloc 333,663,200 331,625,864 -0.6% T12234(optasm) ghc/alloc 52,583,224 52,340,344 -0.5% T12425(optasm) ghc/alloc 81,943,216 81,566,720 -0.5% T13056(optasm) ghc/alloc 294,517,928 289,642,512 -1.7% T13253-spj(normal) ghc/alloc 118,271,264 59,859,040 -49.4% GOOD T15164(normal) ghc/alloc 1,102,630,352 1,091,841,296 -1.0% T15304(normal) ghc/alloc 1,196,084,000 1,166,733,000 -2.5% T15630(normal) ghc/alloc 148,729,632 147,261,064 -1.0% T15703(normal) ghc/alloc 379,366,664 377,600,008 -0.5% T16875(normal) ghc/alloc 32,907,120 32,670,976 -0.7% T17516(normal) ghc/alloc 1,658,001,888 1,627,863,848 -1.8% T17836(normal) ghc/alloc 395,329,400 393,080,248 -0.6% T18140(normal) ghc/alloc 71,968,824 73,243,040 +1.8% T18223(normal) ghc/alloc 456,852,568 453,059,088 -0.8% T18282(normal) ghc/alloc 129,105,576 131,397,064 +1.8% T18304(normal) ghc/alloc 71,311,712 70,722,720 -0.8% T18698a(normal) ghc/alloc 208,795,112 210,102,904 +0.6% T18698b(normal) ghc/alloc 230,320,736 232,697,976 +1.0% BAD T19695(normal) ghc/alloc 1,483,648,128 1,504,702,976 +1.4% T20049(normal) ghc/alloc 85,612,024 85,114,376 -0.6% T21839c(normal) ghc/alloc 415,080,992 410,906,216 -1.0% GOOD T4801(normal) ghc/alloc 247,590,920 250,726,272 +1.3% T6048(optasm) ghc/alloc 95,699,416 95,080,680 -0.6% T783(normal) ghc/alloc 335,323,384 332,988,120 -0.7% T9233(normal) ghc/alloc 709,641,224 685,947,008 -3.3% GOOD T9630(normal) ghc/alloc 965,635,712 948,356,120 -1.8% T9675(optasm) ghc/alloc 444,604,152 428,987,216 -3.5% GOOD T9961(normal) ghc/alloc 303,064,592 308,798,800 +1.9% BAD WWRec(normal) ghc/alloc 503,728,832 498,102,272 -1.1% geo. mean -1.0% minimum -49.4% maximum +1.9% In fact these figures seem to vary between platforms; generally worse on i386 for some reason. The Windows numbers vary by 1% espec in benchmarks where the total allocation is low. But the geom mean stays solidly negative, which is good. The "increase/decrease" list below covers all platforms. The big win on T13253-spj comes because it has a big nest of join points, each occurring twice in the next one. The new occ-anal takes only one iteration of the simplifier to do the inlining; the old one took four. Moreover, we get much smaller code with the new one: New: Result size of Tidy Core = {terms: 429, types: 84, coercions: 0, joins: 14/14} Old: Result size of Tidy Core = {terms: 2,437, types: 304, coercions: 0, joins: 10/10} --------- Runtime perf ----------- No significant changes in nofib results, except a 1% reduction in compiler allocation. Metric Decrease: CoOpt_Read T13253-spj T9233 T9630 T9675 T12150 T21839c LargeRecord MultiComponentModulesRecomp T10421 T13701 T10421 T13701 T12425 Metric Increase: T18140 T9961 T18282 T18698a T18698b T19695 - - - - - 42aa7fbd by Julian Ospald at 2023-07-30T17:22:01-04:00 Improve documentation around IOException and ioe_filename See: * https://github.com/haskell/core-libraries-committee/issues/189 * https://github.com/haskell/unix/pull/279 * https://github.com/haskell/unix/pull/289 - - - - - 33598ecb by Sylvain Henry at 2023-08-01T14:45:54-04:00 JS: implement getMonotonicTime (fix #23687) - - - - - d2bedffd by Bartłomiej Cieślar at 2023-08-01T14:46:40-04:00 Implementation of the Deprecated Instances proposal #575 This commit implements the ability to deprecate certain instances, which causes the compiler to emit the desired deprecation message whenever they are instantiated. For example: module A where class C t where instance {-# DEPRECATED "dont use" #-} C Int where module B where import A f :: C t => t f = undefined g :: Int g = f -- "dont use" emitted here The implementation is as follows: - In the parser, we parse deprecations/warnings attached to instances: instance {-# DEPRECATED "msg" #-} Show X deriving instance {-# WARNING "msg2" #-} Eq Y (Note that non-standalone deriving instance declarations do not support this mechanism.) - We store the resulting warning message in `ClsInstDecl` (respectively, `DerivDecl`). In `GHC.Tc.TyCl.Instance.tcClsInstDecl` (respectively, `GHC.Tc.Deriv.Utils.newDerivClsInst`), we pass on that information to `ClsInst` (and eventually store it in `IfaceClsInst` too). - Finally, when we solve a constraint using such an instance, in `GHC.Tc.Instance.Class.matchInstEnv`, we emit the appropriate warning that was stored in `ClsInst`. Note that we only emit a warning when the instance is used in a different module than it is defined, which keeps the behaviour in line with the deprecation of top-level identifiers. Signed-off-by: Bartłomiej Cieślar <bcieslar2001 at gmail.com> - - - - - d5a65af6 by Ben Gamari at 2023-08-01T14:47:18-04:00 compiler: Style fixes - - - - - 7218c80a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Fix implicit cast This ensures that Task.h can be built with a C++ compiler. - - - - - d6d5aafc by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Fix warning in hs_try_putmvar001 - - - - - d9eddf7a by Ben Gamari at 2023-08-01T14:47:19-04:00 testsuite: Add AtomicModifyIORef test - - - - - f9eea4ba by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce NO_WARN macro This allows fine-grained ignoring of warnings. - - - - - 497b24ec by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Simplify atomicModifyMutVar2# implementation Previously we would perform a redundant load in the non-threaded RTS in atomicModifyMutVar2# implementation for the benefit of the non-moving GC's write barrier. Eliminate this. - - - - - 52ee082b by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce more principled fence operations - - - - - cd3c0377 by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Introduce SET_INFO_RELAXED - - - - - 6df2352a by Ben Gamari at 2023-08-01T14:47:19-04:00 rts: Style fixes - - - - - 4ef6f319 by Ben Gamari at 2023-08-01T14:47:19-04:00 codeGen/tsan: Rework handling of spilling - - - - - f9ca7e27 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More debug information - - - - - df4153ac by Ben Gamari at 2023-08-01T14:47:19-04:00 Improve TSAN documentation - - - - - fecae988 by Ben Gamari at 2023-08-01T14:47:19-04:00 hadrian: More selective TSAN instrumentation - - - - - 465a9a0b by Alan Zimmerman at 2023-08-01T14:47:56-04:00 EPA: Provide correct annotation span for ImportDecl Use the whole declaration, rather than just the span of the 'import' keyword. Metric Decrease: T9961 T5205 Metric Increase: T13035 - - - - - ae63d0fa by Bartłomiej Cieślar at 2023-08-01T14:48:40-04:00 Add cases to T23279: HasField for deprecated record fields This commit adds additional tests from ticket #23279 to ensure that we don't regress on reporting deprecated record fields in conjunction with HasField, either when using overloaded record dot syntax or directly through `getField`. Fixes #23279 - - - - - 00fb6e6b by Andreas Klebinger at 2023-08-01T14:49:17-04:00 AArch NCG: Pure refactor Combine some alternatives. Add some line breaks for overly long lines - - - - - 8f3b3b78 by Andreas Klebinger at 2023-08-01T14:49:54-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - 74a882dc by MorrowM at 2023-08-02T06:00:03-04:00 Add a RULE to make lookup fuse See https://github.com/haskell/core-libraries-committee/issues/175 Metric Increase: T18282 - - - - - cca74dab by Ben Gamari at 2023-08-02T06:00:39-04:00 hadrian: Ensure that way-flags are passed to CC Previously the way-specific compilation flags (e.g. `-DDEBUG`, `-DTHREADED_RTS`) would not be passed to the CC invocations. This meant that C dependency files would not correctly reflect dependencies predicated on the way, resulting in the rather painful #23554. Closes #23554. - - - - - 622b483c by Jaro Reinders at 2023-08-02T06:01:20-04:00 Native 32-bit Enum Int64/Word64 instances This commits adds more performant Enum Int64 and Enum Word64 instances for 32-bit platforms, replacing the Integer-based implementation. These instances are a copy of the Enum Int and Enum Word instances with minimal changes to manipulate Int64 and Word64 instead. On i386 this yields a 1.5x performance increase and for the JavaScript back end it even yields a 5.6x speedup. Metric Decrease: T18964 - - - - - c8bd7fa4 by Sylvain Henry at 2023-08-02T06:02:03-04:00 JS: fix typos in constants (#23650) - - - - - b9d5bfe9 by Josh Meredith at 2023-08-02T06:02:40-04:00 JavaScript: update MK_TUP macros to use current tuple constructors (#23659) - - - - - 28211215 by Matthew Pickering at 2023-08-02T06:03:19-04:00 ci: Pass -Werror when building hadrian in hadrian-ghc-in-ghci job Warnings when building Hadrian can end up cluttering the output of HLS, and we've had bug reports in the past about these warnings when building Hadrian. It would be nice to turn on -Werror on at least one build of Hadrian in CI to avoid a patch introducing warnings when building Hadrian. Fixes #23638 - - - - - aca20a5d by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers By using a proper release store instead of a fence. - - - - - 453c0531 by Ben Gamari at 2023-08-02T06:03:55-04:00 codeGen: Ensure that array reads have necessary barriers This was the cause of #23541. - - - - - 93a0d089 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Add test for #23550 - - - - - 6a2f4a20 by Arnaud Spiwack at 2023-08-02T06:04:37-04:00 Desugar non-recursive lets to non-recursive lets (take 2) This reverts commit 522bd584f71ddeda21efdf0917606ce3d81ec6cc. And takes care of the case that I missed in my previous attempt. Namely the case of an AbsBinds with no type variables and no dictionary variable. Ironically, the comment explaining why non-recursive lets were desugared to recursive lets were pointing specifically at this case as the reason. I just failed to understand that it was until Simon PJ pointed it out to me. See #23550 for more discussion. - - - - - ff81d53f by jade at 2023-08-02T06:05:20-04:00 Expand documentation of List & Data.List This commit aims to improve the documentation and examples of symbols exported from Data.List - - - - - fa4e5913 by Jade at 2023-08-02T06:06:03-04:00 Improve documentation of Semigroup & Monoid This commit aims to improve the documentation of various symbols exported from Data.Semigroup and Data.Monoid - - - - - e2c91bff by Gergő Érdi at 2023-08-03T02:55:46+01:00 Desugar bindings in the context of their evidence Closes #23172 - - - - - 481f4a46 by Gergő Érdi at 2023-08-03T07:48:43+01:00 Add flag to `-f{no-}specialise-incoherents` to enable/disable specialisation of incoherent instances Fixes #23287 - - - - - d751c583 by Profpatsch at 2023-08-04T12:24:26-04:00 base: Improve String & IsString documentation - - - - - 01db1117 by Ben Gamari at 2023-08-04T12:25:02-04:00 rts/win32: Ensure reliability of IO manager shutdown When the Win32 threaded IO manager shuts down, `ioManagerDie` sends an `IO_MANAGER_DIE` event to the IO manager thread using the `io_manager_event` event object. Finally, it will closes the event object, and invalidate `io_manager_event`. Previously, `readIOManagerEvent` would see that `io_manager_event` is invalid and return `0`, suggesting that everything is right with the world. This meant that if `ioManagerDie` invalidated the handle before the event manager was blocked on the event we would end up in a situation where the event manager would never realize it was asked to shut down. Fix this by ensuring that `readIOManagerEvent` instead returns `IO_MANAGER_DIE` when we detect that the event object has been invalidated by `ioManagerDie`. Fixes #23691. - - - - - fdef003a by Ryan Scott at 2023-08-04T12:25:39-04:00 Look through TH splices in splitHsApps This modifies `splitHsApps` (a key function used in typechecking function applications) to look through untyped TH splices and quasiquotes. Not doing so was the cause of #21077. This builds on !7821 by making `splitHsApps` match on `HsUntypedSpliceTop`, which contains the `ThModFinalizers` that must be run as part of invoking the TH splice. See the new `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Along the way, I needed to make the type of `splitHsApps.set` slightly more general to accommodate the fact that the location attached to a quasiquote is a `SrcAnn NoEpAnns` rather than a `SrcSpanAnnA`. Fixes #21077. - - - - - e77a0b41 by Ben Gamari at 2023-08-04T12:26:15-04:00 Bump deepseq submodule to 1.5. And bump bounds (cherry picked from commit 1228d3a4a08d30eaf0138a52d1be25b38339ef0b) - - - - - cebb5819 by Ben Gamari at 2023-08-04T12:26:15-04:00 configure: Bump minimal boot GHC version to 9.4 (cherry picked from commit d3ffdaf9137705894d15ccc3feff569d64163e8e) - - - - - 83766dbf by Ben Gamari at 2023-08-04T12:26:15-04:00 template-haskell: Bump version to 2.21.0.0 Bumps exceptions submodule. (cherry picked from commit bf57fc9aea1196f97f5adb72c8b56434ca4b87cb) - - - - - 1211112a by Ben Gamari at 2023-08-04T12:26:15-04:00 base: Bump version to 4.19 Updates all boot library submodules. (cherry picked from commit 433d99a3c24a55b14ec09099395e9b9641430143) - - - - - 3ab5efd9 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Normalise versions more aggressively In backpack hashes can contain `+` characters. (cherry picked from commit 024861af51aee807d800e01e122897166a65ea93) - - - - - d52be957 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Declare bkpcabal08 as fragile Due to spurious output changes described in #23648. (cherry picked from commit c046a2382420f2be2c4a657c56f8d95f914ea47b) - - - - - e75a58d1 by Ben Gamari at 2023-08-04T12:26:15-04:00 gitlab-ci: Only mark linker_unload_native as broken in static jobs This test passes on dynamically-linked Alpine. (cherry picked from commit f356a7e8ec8ec3d6b2b30fd175598b9b80065d87) - - - - - 8b176514 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite: Update base-exports - - - - - 4b647936 by Ben Gamari at 2023-08-04T12:26:15-04:00 testsuite/interface-stability: normalise versions This eliminates spurious changes from version bumps. - - - - - 0eb54c05 by Ben Gamari at 2023-08-04T12:26:51-04:00 linker/PEi386: Don't sign-extend symbol section number Previously we incorrectly interpreted PE section numbers as signed values. However, this isn't the case; rather, it's an unsigned 16-bit number with a few special bit-patterns (0xffff and 0xfffe). This resulted in #22941 as the linker would conclude that the sections were invalid. Fixing this required quite a bit of refactoring. Closes #22941. - - - - - fd7ce39c by Ben Gamari at 2023-08-04T12:27:28-04:00 testsuite: Mark MulMayOflo_full as broken rather than skipping To ensure that we don't accidentally fix it. See #23742. - - - - - 824092f2 by Ben Gamari at 2023-08-04T12:27:28-04:00 nativeGen/AArch64: Fix sign extension in MulMayOflo Previously the 32-bit implementations of MulMayOflo would use the a non-sensical sign-extension mode. Rewrite these to reflect what gcc 11 produces. Also similarly rework the 16- and 8-bit cases. This now passes the MulMayOflo tests in ghc/test-primops> in all four widths, including the precision tests. Fixes #23721. - - - - - 1b15dbc4 by Jan Hrček at 2023-08-04T12:28:08-04:00 Fix haddock markup in code example for coerce - - - - - 46fd8ced by Vladislav Zavialov at 2023-08-04T12:28:44-04:00 Fix (~) and (@) infix operators in TH splices (#23748) 8168b42a "Whitespace-sensitive bang patterns" allows GHC to accept the following infix operators: a ~ b = () a @ b = () But not if TH is used to generate those declarations: $([d| a ~ b = () a @ b = () |]) -- Test.hs:5:2: error: [GHC-55017] -- Illegal variable name: ‘~’ -- When splicing a TH declaration: (~_0) a_1 b_2 = GHC.Tuple.Prim.() This is easily fixed by modifying `reservedOps` in GHC.Utils.Lexeme - - - - - a1899d8f by Aaron Allen at 2023-08-04T12:29:24-04:00 [#23663] Show Flag Suggestions in GHCi Makes suggestions when using `:set` in GHCi with a misspelled flag. This mirrors how invalid flags are handled when passed to GHC directly. Logic for producing flag suggestions was moved to GHC.Driver.Sesssion so it can be shared. resolves #23663 - - - - - 03f2debd by Rodrigo Mesquita at 2023-08-04T12:30:00-04:00 Improve ghc-toolchain validation configure warning Fixes the layout of the ghc-toolchain validation warning produced by configure. - - - - - de25487d by Alan Zimmerman at 2023-08-04T12:30:36-04:00 EPA make getLocA a synonym for getHasLoc This is basically a no-op change, but allows us to make future changes that can rely on the HasLoc instances And I presume this means we can use more precise functions based on class resolution, so the Windows CI build reports Metric Decrease: T12234 T13035 - - - - - 3ac423b9 by Ben Gamari at 2023-08-04T12:31:13-04:00 ghc-platform: Add upper bound on base Hackage upload requires this. - - - - - 8ba20b21 by Matthew Craven at 2023-08-04T17:22:59-04:00 Adjust and clarify handling of primop effects Fixes #17900; fixes #20195. The existing "can_fail" and "has_side_effects" primop attributes that previously governed this were used in inconsistent and confusingly-documented ways, especially with regard to raising exceptions. This patch replaces them with a single "effect" attribute, which has four possible values: NoEffect, CanFail, ThrowsException, and ReadWriteEffect. These are described in Note [Classifying primop effects]. A substantial amount of related documentation has been re-drafted for clarity and accuracy. In the process of making this attribute format change for literally every primop, several existing mis-classifications were detected and corrected. One of these mis-classifications was tagToEnum#, which is now considered CanFail; this particular fix is known to cause a regression in performance for derived Enum instances. (See #23782.) Fixing this is left as future work. New primop attributes "cheap" and "work_free" were also added, and used in the corresponding parts of GHC.Core.Utils. In view of their actual meaning and uses, `primOpOkForSideEffects` and `exprOkForSideEffects` have been renamed to `primOpOkToDiscard` and `exprOkToDiscard`, respectively. Metric Increase: T21839c - - - - - 41bf2c09 by sheaf at 2023-08-04T17:23:42-04:00 Update inert_solved_dicts for ImplicitParams When adding an implicit parameter dictionary to the inert set, we must make sure that it replaces any previous implicit parameter dictionaries that overlap, in order to get the appropriate shadowing behaviour, as in let ?x = 1 in let ?x = 2 in ?x We were already doing this for inert_cans, but we weren't doing the same thing for inert_solved_dicts, which lead to the bug reported in #23761. The fix is thus to make sure that, when handling an implicit parameter dictionary in updInertDicts, we update **both** inert_cans and inert_solved_dicts to ensure a new implicit parameter dictionary correctly shadows old ones. Fixes #23761 - - - - - 43578d60 by Matthew Craven at 2023-08-05T01:05:36-04:00 Bump bytestring submodule to 0.11.5.1 - - - - - 91353622 by Ben Gamari at 2023-08-05T01:06:13-04:00 Initial commit of Note [Thunks, blackholes, and indirections] This Note attempts to summarize the treatment of thunks, thunk update, and indirections. This fell out of work on #23185. - - - - - 8d686854 by sheaf at 2023-08-05T01:06:54-04:00 Remove zonk in tcVTA This removes the zonk in GHC.Tc.Gen.App.tc_inst_forall_arg and its accompanying Note [Visible type application zonk]. Indeed, this zonk is no longer necessary, as we no longer maintain the invariant that types are well-kinded without zonking; only that typeKind does not crash; see Note [The Purely Kinded Type Invariant (PKTI)]. This commit removes this zonking step (as well as a secondary zonk), and replaces the aforementioned Note with the explanatory Note [Type application substitution], which justifies why the substitution performed in tc_inst_forall_arg remains valid without this zonking step. Fixes #23661 - - - - - 19dea673 by Ben Gamari at 2023-08-05T01:07:30-04:00 Bump nofib submodule Ensuring that nofib can be build using the same range of bootstrap compilers as GHC itself. - - - - - aa07402e by Luite Stegeman at 2023-08-05T23:15:55+09:00 JS: Improve compatibility with recent emsdk The JavaScript code in libraries/base/jsbits/base.js had some hardcoded offsets for fields in structs, because we expected the layout of the data structures to remain unchanged. Emsdk 3.1.42 changed the layout of the stat struct, breaking this assumption, and causing code in .hsc files accessing the stat struct to fail. This patch improves compatibility with recent emsdk by removing the assumption that data layouts stay unchanged: 1. offsets of fields in structs used by JavaScript code are now computed by the configure script, so both the .js and .hsc files will automatically use the new layout if anything changes. 2. the distrib/configure script checks that the emsdk version on a user's system is the same version that a bindist was booted with, to avoid data layout inconsistencies See #23641 - - - - - b938950d by Luite Stegeman at 2023-08-07T06:27:51-04:00 JS: Fix missing local variable declarations This fixes some missing local variable declarations that were found by running the testsuite in strict mode. Fixes #23775 - - - - - 6c0e2247 by sheaf at 2023-08-07T13:31:21-04:00 Update Haddock submodule to fix #23368 This submodule update adds the following three commits: bbf1c8ae - Check for puns 0550694e - Remove fake exports for (~), List, and Tuple<n> 5877bceb - Fix pretty-printing of Solo and MkSolo These commits fix the issues with Haddock HTML rendering reported in ticket #23368. Fixes #23368 - - - - - 5b5be3ea by Matthew Pickering at 2023-08-07T13:32:00-04:00 Revert "Bump bytestring submodule to 0.11.5.1" This reverts commit 43578d60bfc478e7277dcd892463cec305400025. Fixes #23789 - - - - - 01961be3 by Ben Gamari at 2023-08-08T02:47:14-04:00 configure: Derive library version from ghc-prim.cabal.in Since ghc-prim.cabal is now generated by Hadrian, we cannot depend upon it. Closes #23726. - - - - - 3b373838 by Ryan Scott at 2023-08-08T02:47:49-04:00 tcExpr: Push expected types for untyped TH splices inwards In !10911, I deleted a `tcExpr` case for `HsUntypedSplice` in favor of a much simpler case that simply delegates to `tcApp`. Although this passed the test suite at the time, this was actually an error, as the previous `tcExpr` case was critically pushing the expected type inwards. This actually matters for programs like the one in #23796, which GHC would not accept with type inference alone—we need full-blown type _checking_ to accept these. I have added back the previous `tcExpr` case for `HsUntypedSplice` and now explain why we have two different `HsUntypedSplice` cases (one in `tcExpr` and another in `splitHsApps`) in `Note [Looking through Template Haskell splices in splitHsApps]` in `GHC.Tc.Gen.Head`. Fixes #23796. - - - - - 0ef1d8ae by sheaf at 2023-08-08T21:26:51-04:00 Compute all emitted diagnostic codes This commit introduces in GHC.Types.Error.Codes the function constructorCodes :: forall diag. (...) => Map DiagnosticCode String which computes a collection of all the diagnostic codes that correspond to a particular type. In particular, we can compute the collection of all diagnostic codes emitted by GHC using the invocation constructorCodes @GhcMessage We then make use of this functionality in the new "codes" test which checks consistency and coverage of GHC diagnostic codes. It performs three checks: - check 1: all non-outdated GhcDiagnosticCode equations are statically used. - check 2: all outdated GhcDiagnosticCode equations are statically unused. - check 3: all statically used diagnostic codes are covered by the testsuite (modulo accepted exceptions). - - - - - 4bc7b1e5 by Fraser Tweedale at 2023-08-08T21:27:32-04:00 numberToRangedRational: fix edge cases for exp ≈ (maxBound :: Int) Currently a negative exponent less than `minBound :: Int` results in Infinity, which is very surprising and obviously wrong. ``` λ> read "1e-9223372036854775808" :: Double 0.0 λ> read "1e-9223372036854775809" :: Double Infinity ``` There is a further edge case where the exponent can overflow when increased by the number of tens places in the integer part, or underflow when decreased by the number of leading zeros in the fractional part if the integer part is zero: ``` λ> read "10e9223372036854775807" :: Double 0.0 λ> read "0.01e-9223372036854775808" :: Double Infinity ``` To resolve both of these issues, perform all arithmetic and comparisons involving the exponent in type `Integer`. This approach also eliminates the need to explicitly check the exponent against `maxBound :: Int` and `minBound :: Int`, because the allowed range of the exponent (i.e. the result of `floatRange` for the target floating point type) is certainly within those bounds. This change implements CLC proposal 192: https://github.com/haskell/core-libraries-committee/issues/192 - - - - - 6eab07b2 by Alan Zimmerman at 2023-08-08T21:28:10-04:00 EPA: Remove Location from WarningTxt source This is not needed. - - - - - 1a98d673 by Sebastian Graf at 2023-08-09T16:24:29-04:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 2274abc8 by Sebastian Graf at 2023-08-09T16:24:29-04:00 More explicit strictness in GHC.Real - - - - - ce8aa54c by Sebastian Graf at 2023-08-09T16:24:30-04:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - d004a36d by Sebastian Graf at 2023-08-09T16:24:30-04:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 8c73505e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - d8d993f1 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Disable tests RepPolyWrappedVar2 and RepPolyUnsafeCoerce1 in JS backend ... because those coerce between incompatible/unknown PrimReps. - - - - - f06e87e4 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Inlining literals into boring contexts is OK - - - - - 4a6b7c87 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Clarify floating of unsafeEqualityProofs (#23754) - - - - - b0f4752e by Sebastian Graf at 2023-08-09T16:24:30-04:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 7e0c8b3b by Sebastian Graf at 2023-08-09T16:24:30-04:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Annoyingly, in -O0 we sometimes generate ``` foo = case "blah"# of sat { __DEFAULT -> unpackCString# sat } ``` which makes it a bit harder to spot that we can emit a standard `stg_unpack_cstring` thunk. Fixes #23270. - - - - - 357f2738 by Sebastian Graf at 2023-08-09T16:24:30-04:00 Deactivate -fcatch-nonexhaustive-cases in ghc-bignum (#23345) - - - - - 59202c80 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. In the ghc/alloc perf test `LargeRecord`, we introduce an additional Simplifier iteration due to #17910. E.g., FloatOut produces a binding ``` lvl_s6uK [Occ=Once1] :: GHC.Types.Int [LclId] lvl_s6uK = GHC.Types.I# 2# lvl_s6uL [Occ=Once1] :: GHC.Types.Any [LclId] lvl_s6uL = case Unsafe.Coerce.unsafeEqualityProof ... of { Unsafe.Coerce.UnsafeRefl v2_i6tr -> lvl_s6uK `cast` (... v2_i6tr ...) } ``` That occurs once and hence is pre-inlined unconditionally in the next Simplifier pass. It's non-trivial to find a way around that, but not really harmful otherwise. Hence we accept a 1.2% increase on some architectures. Metric Increase: LargeRecord - - - - - 00d31188 by Sebastian Graf at 2023-08-09T16:24:30-04:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - bf885d7a by Matthew Craven at 2023-08-09T16:25:07-04:00 Bump bytestring submodule to 0.11.5, again Fixes #23789. The bytestring commit used here is unreleased; a release can be made when necessary. - - - - - 7acbf0fd by Sven Tennie at 2023-08-10T19:17:11-04:00 Serialize CmmRetInfo in .rodata The handling of case was missing. - - - - - 0c3136f2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Reference StgRetFun payload by its struct field address This is easier to grasp than relative pointer offsets. - - - - - f68ff313 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better variable name: u -> frame The 'u' was likely introduced by copy'n'paste. - - - - - 0131bb7f by Sven Tennie at 2023-08-10T19:17:11-04:00 Make checkSTACK() public Such that it can also be used in tests. - - - - - 7b6e1e53 by Sven Tennie at 2023-08-10T19:17:11-04:00 Publish stack related fields in DerivedConstants.h These will be used in ghc-heap to decode these parts of the stack. - - - - - 907ed054 by Sven Tennie at 2023-08-10T19:17:11-04:00 ghc-heap: Decode StgStack and its stack frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 6beb6ac2 by Sven Tennie at 2023-08-10T19:17:11-04:00 Remove RetFunType from RetFun stack frame representation It's a technical detail. The single usage is replaced by a predicate. - - - - - 006bb4f3 by Sven Tennie at 2023-08-10T19:17:11-04:00 Better parameter name The call-site uses the term "offset", too. - - - - - d4c2c1af by Sven Tennie at 2023-08-10T19:17:11-04:00 Make closure boxing pure There seems to be no need to do something complicated. However, the strictness of the closure pointer matters, otherwise a thunk gets decoded. - - - - - 8d8426c9 by Sven Tennie at 2023-08-10T19:17:11-04:00 Document entertainGC in test It wasn't obvious why it's there and what its role is. Also, increase the "entertainment level" a bit. I checked in STG and Cmm dumps that this really generates closures (and is not e.g. constant folded away.) - - - - - cc52c358 by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -dipe-stats flag This is useful for seeing which info tables have information. - - - - - 261c4acb by Finley McIlwaine at 2023-08-10T19:17:47-04:00 Add -finfo-table-map-with-fallback -finfo-table-map-with-stack The -fno-info-table-map-with-stack flag omits STACK info tables from the info table map, and the -fno-info-table-map-with-fallback flag omits info tables with defaulted source locations from the map. In a test on the Agda codebase the build results were about 7% smaller when both of those types of tables were omitted. Adds a test that verifies that passing each combination of these flags results in the correct output for -dipe-stats, which is disabled for the js backend since profiling is not implemented. This commit also refactors a lot of the logic around extracting info tables from the Cmm results and building the info table map. This commit also fixes some issues in the users guide rst source to fix warnings that were noticed while debugging the documentation for these flags. Fixes #23702 - - - - - d7047e0d by Jaro Reinders at 2023-08-14T04:41:42-04:00 Add changelog entry for specialised Enum Int64/Word64 instances - - - - - 52f5e8fb by cydparser at 2023-08-14T04:42:20-04:00 Fix -ddump-to-file and -ddump-timings interaction (#20316) - - - - - 1274c5d6 by cydparser at 2023-08-14T04:42:20-04:00 Update release notes (#20316) - - - - - 8e699b23 by Matthew Pickering at 2023-08-14T10:44:47-04:00 base: Add changelog entry for CLC #188 This proposal modified the implementations of copyBytes, moveBytes and fillBytes (as detailed in the proposal) https://github.com/haskell/core-libraries-committee/issues/188 - - - - - 026f040a by Matthew Pickering at 2023-08-14T10:45:23-04:00 packaging: Build manpage in separate directory to other documentation We were installing two copies of the manpage: * One useless one in the `share/doc` folder, because we copy the doc/ folder into share/ * The one we deliberately installed into `share/man` etc The solution is to build the manpage into the `manpage` directory when building the bindist, and then just install it separately. Fixes #23707 - - - - - 524c60c8 by Bartłomiej Cieślar at 2023-08-14T13:46:33-04:00 Report deprecated fields bound by record wildcards when used This commit ensures that we emit the appropriate warnings when a deprecated record field bound by a record wildcard is used. For example: module A where data Foo = Foo {x :: Int, y :: Bool, z :: Char} {-# DEPRECATED x "Don't use x" #-} {-# WARNING y "Don't use y" #-} module B where import A foo (Foo {..}) = x This will cause us to emit a "Don't use x" warning, with location the location of the record wildcard. Note that we don't warn about `y`, because it is unused in the RHS of `foo`. Fixes #23382 - - - - - d6130065 by Matthew Pickering at 2023-08-14T13:47:11-04:00 Add zstd suffix to jobs which rely on zstd This was causing some confusion as the job was named simply "x86_64-linux-deb10-validate", which implies a standard configuration rather than any dependency on libzstd. - - - - - e24e44fc by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Always run project-version job This is needed for the downstream test-primops pipeline to workout what the version of a bindist produced by a pipeline is. - - - - - f17b9d62 by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rework how jobs-metadata.json is generated * We now represent a job group a triple of Maybes, which makes it easier to work out when jobs are enabled/disabled on certain pipelines. ``` data JobGroup a = StandardTriple { v :: Maybe (NamedJob a) , n :: Maybe (NamedJob a) , r :: Maybe (NamedJob a) } ``` * `jobs-metadata.json` generation is reworked using the following algorithm. - For each pipeline type, find all the platforms we are doing builds for. - Select one build per platform - Zip together the results This way we can choose different pipelines for validate/nightly/release which makes the metadata also useful for validate pipelines. This feature is used by the test-primops downstream CI in order to select the right bindist for testing validate pipelines. This makes it easier to inspect which jobs are going to be enabled on a particular pipeline. - - - - - f9a5563d by Matthew Pickering at 2023-08-14T13:47:11-04:00 gen_ci: Rules rework In particular we now distinguish between whether we are dealing with a Nightly/Release pipeline (which labels don't matter for) and a validate pipeline where labels do matter. The overall goal here is to allow a disjunction of labels for validate pipelines, for example, > Run a job if we have the full-ci label or test-primops label Therefore the "ValidateOnly" rules are treated as a set of disjunctions rather than conjunctions like before. What this means in particular is that if we want to ONLY run a job if a label is set, for example, "FreeBSD" label then we have to override the whole label set. Fixes #23772 - - - - - d54b0c1d by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: set -e for lint-ci-config scripts - - - - - 994a9b35 by Matthew Pickering at 2023-08-14T13:47:11-04:00 ci: Fix job metadata generation - - - - - e194ed2b by Ben Gamari at 2023-08-15T00:58:09-04:00 users-guide: Note that GHC2021 doesn't include ExplicitNamespaces As noted in #23801. - - - - - d814bda9 by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Support both distutils and packaging As noted in #23818, some old distributions (e.g. Debian 9) only include `distutils` while newer distributions only include `packaging`. Fixes #23818. - - - - - 1726db3f by Ben Gamari at 2023-08-15T05:43:53-04:00 users-guide: Ensure extlinks is compatible with Sphinx <4 The semantics of the `extlinks` attribute annoyingly changed in Sphinx 4. Reflect this in our configuration. See #22690. Fixes #23807. - - - - - 173338cf by Matthew Pickering at 2023-08-15T22:00:24-04:00 ci: Run full-ci on master and release branches Fixes #23737 - - - - - bdab6898 by Andrew Lelechenko at 2023-08-15T22:01:03-04:00 Add @since pragmas for Data.Ord.clamp and GHC.Float.clamp - - - - - 662d351b by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Match CPP args with configure script At the moment we need ghc-toolchain to precisely match the output as provided by the normal configure script. The normal configure script (FP_HSCPP_CMD_WITH_ARGS) branches on whether we are using clang or gcc so we match that logic exactly in ghc-toolchain. The old implementation (which checks if certain flags are supported) is better but for now we have to match to catch any potential errors in the configuration. Ticket: #23720 - - - - - 09c6759e by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Fix `-Wl,--no-as-needed` check The check was failing because the args supplied by $$1 were quoted which failed because then the C compiler thought they were an input file. Fixes #23720 - - - - - 2129678b by Matthew Pickering at 2023-08-16T09:35:04-04:00 configure: Add flag which turns ghc-toolchain check into error We want to catch these errors in CI, but first we need to a flag which turns this check into an error. - - - - - 6e2aa8e0 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ci: Enable --enable-strict-ghc-toolchain-check for all CI jobs This will cause any CI job to fail if we have a mismatch between what ghc-toolchain reports and what ./configure natively reports. Fixing these kinds of issues is highest priority for 9.10 release. - - - - - 12d39e24 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Pass user-specified options to ghc-toolchain The current user interface to configuring target toolchains is `./configure`. In !9263 we added a new tool to configure target toolchains called `ghc-toolchain`, but the blessed way of creating these toolchains is still through configure. However, we were not passing the user-specified options given with the `./configure` invocation to the ghc-toolchain tool. This commit remedies that by storing the user options and environment variables in USER_* variables, which then get passed to GHC-toolchain. The exception to the rule is the windows bundled toolchain, which overrides the USER_* variables with whatever flags the windows bundled toolchain requires to work. We consider the bundled toolchain to be effectively the user specifying options, since the actual user delegated that configuration work. Closes #23678 - - - - - f7b3c3a0 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Parse javascript and ghcjs as a Arch and OS - - - - - 8a0ae4ee by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 ghc-toolchain: Fix ranlib option - - - - - 31e9ec96 by Rodrigo Mesquita at 2023-08-16T09:35:04-04:00 Check Link Works with -Werror - - - - - bc1998b3 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Only check for no_compact_unwind support on darwin While writing ghc-toolchain we noticed that the FP_PROG_LD_NO_COMPACT_UNWIND check is subtly wrong. Specifically, we pass -Wl,-no_compact_unwind to cc. However, ld.gold interprets this as -n o_compact_unwind, which is a valid argument. Fixes #23676 - - - - - 0283f36e by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add some javascript special cases to ghc-toolchain On javascript there isn't a choice of toolchain but some of the configure checks were not accurately providing the correct answer. 1. The linker was reported as gnu LD because the --version output mentioned gnu LD. 2. The --target flag makes no sense on javascript but it was just ignored by the linker, so we add a special case to stop ghc-toolchain thinking that emcc supports --target when used as a linker. - - - - - a48ec5f8 by Matthew Pickering at 2023-08-16T09:35:04-04:00 check for emcc in gnu_LD check - - - - - 50df2e69 by Matthew Pickering at 2023-08-16T09:35:04-04:00 Add ldOverrideWhitelist to only default to ldOverride on windows/linux On some platforms - ie darwin, javascript etc we really do not want to allow the user to use any linker other than the default one as this leads to all kinds of bugs. Therefore it is a bit more prudant to add a whitelist which specifies on which platforms it might be possible to use a different linker. - - - - - a669a39c by Matthew Pickering at 2023-08-16T09:35:04-04:00 Fix plaform glob in FPTOOLS_SET_C_LD_FLAGS A normal triple may look like x86_64-unknown-linux but when cross-compiling you get $target set to a quad such as.. aarch64-unknown-linux-gnu Which should also match this check. - - - - - c52b6769 by Matthew Pickering at 2023-08-16T09:35:04-04:00 ghc-toolchain: Pass ld-override onto ghc-toolchain - - - - - 039b484f by Matthew Pickering at 2023-08-16T09:35:04-04:00 ld override: Make whitelist override user given option - - - - - d2b63cbc by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Add format mode to normalise differences before diffing. The "format" mode takes an "--input" and "--ouput" target file and formats it. This is intended to be useful on windows where the configure/ghc-toolchain target files can't be diffed very easily because the path separators are different. - - - - - f2b39e4a by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: Bump ci-images commit to get new ghc-wasm-meta We needed to remove -Wno-unused-command-line-argument from the arguments passed in order for the configure check to report correctly. See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10976#note_516335 - - - - - 92103830 by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: MergeObjsCmd - distinguish between empty string and unset variable If `MergeObjsCmd` is explicitly set to the empty string then we should assume that MergeObjs is just not supported. This is especially important for windows where we set MergeObjsCmd to "" in m4/fp_setup_windows_toolchain.m4. - - - - - 3500bb2c by Matthew Pickering at 2023-08-16T09:35:05-04:00 configure: Add proper check to see if object merging works - - - - - 08c9a014 by Matthew Pickering at 2023-08-16T09:35:05-04:00 ghc-toolchain: If MergeObjsCmd is not set, replace setting with Nothing If the user explicitly chooses to not set a MergeObjsCmd then it is correct to use Nothing for tgtMergeObjs field in the Target file. - - - - - c9071d94 by Matthew Pickering at 2023-08-16T09:35:05-04:00 HsCppArgs: Augment the HsCppOptions This is important when we pass -I when setting up the windows toolchain. - - - - - 294a6d80 by Matthew Pickering at 2023-08-16T09:35:05-04:00 Set USER_CPP_ARGS when setting up windows toolchain - - - - - bde4b5d4 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 Improve handling of Cc as a fallback - - - - - f4c1c3a3 by Rodrigo Mesquita at 2023-08-16T09:35:05-04:00 ghc-toolchain: Configure Cpp and HsCpp correctly when user specifies flags In ghc-toolchain, we were only /not/ configuring required flags when the user specified any flags at all for the of the HsCpp and Cpp tools. Otherwise, the linker takes into consideration the user specified flags to determine whether to search for a better linker implementation, but already configured the remaining GHC and platform-specific flags regardless of the user options. Other Tools consider the user options as a baseline for further configuration (see `findProgram`), so #23689 is not applicable. Closes #23689 - - - - - bfe4ffac by Matthew Pickering at 2023-08-16T09:35:05-04:00 CPP_ARGS: Put new options after user specified options This matches up with the behaviour of ghc-toolchain, so that the output of both matches. - - - - - a6828173 by Gergő Érdi at 2023-08-16T09:35:41-04:00 If a defaulting plugin made progress, re-zonk wanteds before built-in defaulting Fixes #23821. - - - - - e2b38115 by Sylvain Henry at 2023-08-17T07:54:06-04:00 JS: implement openat(AT_FDCWD...) (#23697) Use `openSync` to implement `openat(AT_FDCWD...)`. - - - - - a975c663 by sheaf at 2023-08-17T07:54:47-04:00 Use unsatisfiable for missing methods w/ defaults When a class instance has an Unsatisfiable constraint in its context and the user has not explicitly provided an implementation of a method, we now always provide a RHS of the form `unsatisfiable @msg`, even if the method has a default definition available. This ensures that, when deferring type errors, users get the appropriate error message instead of a possible runtime loop, if class default methods were defined recursively. Fixes #23816 - - - - - 45ca51e5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-internal: Initial commit of the skeleton - - - - - 88bbf8c5 by Ben Gamari at 2023-08-17T15:16:41-04:00 ghc-experimental: Initial commit - - - - - 664468c0 by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite/cloneStackLib: Fix incorrect format specifiers - - - - - eaa835bb by Ben Gamari at 2023-08-17T15:17:17-04:00 rts/ipe: Fix const-correctness of IpeBufferListNode Both info tables and the string table should be `const` - - - - - 78f6f6fd by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Drop dead debugging utilities These are largely superceded by support in the ghc-utils GDB extension. - - - - - 3f6e8f42 by Ben Gamari at 2023-08-17T15:17:17-04:00 nonmoving: Refactor management of mark thread Here we refactor that treatment of the worker thread used by the nonmoving GC for concurrent marking, avoiding creating a new thread with every major GC cycle. As well, the new scheme is considerably easier to reason about, consolidating all state in one place, accessed via a small set of accessors with clear semantics. - - - - - 88c32b7d by Ben Gamari at 2023-08-17T15:17:17-04:00 testsuite: Skip T23221 in nonmoving GC ways This test is very dependent upon GC behavior. - - - - - 381cfaed by Ben Gamari at 2023-08-17T15:17:17-04:00 ghc-heap: Don't expose stack dirty and marking fields These are GC metadata and are not relevant to the end-user. Moreover, they are unstable which makes ghc-heap harder to test than necessary. - - - - - 16828ca5 by Luite Stegeman at 2023-08-21T18:42:53-04:00 bump process submodule to include macOS fix and JS support - - - - - b4d5f6ed by Matthew Pickering at 2023-08-21T18:43:29-04:00 ci: Add support for triggering test-primops pipelines This commit adds 4 ways to trigger testing with test-primops. 1. Applying the ~test-primops label to a validate pipeline. 2. A manually triggered job on a validate pipeline 3. A nightly pipeline job 4. A release pipeline job Fixes #23695 - - - - - 32c50daa by Matthew Pickering at 2023-08-21T18:43:29-04:00 Add test-primops label support The test-primops CI job requires some additional builds in the validation pipeline, so we make sure to enable these jobs when test-primops label is set. - - - - - 73ca8340 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch ncg: Optimize immediate use for address calculations" This reverts commit 8f3b3b78a8cce3bd463ed175ee933c2aabffc631. See #23793 - - - - - 5546ad9e by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "AArch NCG: Pure refactor" This reverts commit 00fb6e6b06598752414a0b9a92840fb6ca61338d. See #23793 - - - - - 02dfcdc2 by Matthew Pickering at 2023-08-21T18:43:29-04:00 Revert "Aarch64 NCG: Use encoded immediates for literals." This reverts commit 40425c5021a9d8eb5e1c1046e2d5fa0a2918f96c. See #23793 ------------------------- Metric Increase: T4801 T5321FD T5321Fun ------------------------- - - - - - 7be4a272 by Matthew Pickering at 2023-08-22T08:55:20+01:00 ci: Remove manually triggered test-ci job This doesn't work on slimmed down pipelines as the needed jobs don't exist. If you want to run test-primops then apply the label. - - - - - 76a4d11b by Jaro Reinders at 2023-08-22T08:08:13-04:00 Remove Ptr example from roles docs - - - - - 069729d3 by Bryan Richter at 2023-08-22T08:08:49-04:00 Guard against duplicate pipelines in forks - - - - - f861423b by Rune K. Svendsen at 2023-08-22T08:09:35-04:00 dump-decls: fix "Ambiguous module name"-error Fixes errors of the following kind, which happen when dump-decls is run on a package that contains a module name that clashes with that of another package. ``` dump-decls: <no location info>: error: Ambiguous module name `System.Console.ANSI.Types': it was found in multiple packages: ansi-terminal-0.11.4 ansi-terminal-types-0.11.5 ``` - - - - - edd8bc43 by Krzysztof Gogolewski at 2023-08-22T12:31:20-04:00 Fix MultiWayIf linearity checking (#23814) Co-authored-by: Thomas BAGREL <thomas.bagrel at tweag.io> - - - - - 4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00 Update `Control.Concurrent.*` documentation - - - - - 015886ec by ARATA Mizuki at 2023-08-22T15:13:13-04:00 Support 128-bit SIMD on AArch64 via LLVM backend - - - - - 52a6d868 by Krzysztof Gogolewski at 2023-08-22T15:13:51-04:00 Testsuite cleanup - Remove misleading help text in perf_notes, ways are not metrics - Remove no_print_summary - this was used for Phabricator - In linters tests, run 'git ls-files' just once. Previously, it was called on each has_ls_files() - Add ghc-prim.cabal to gitignore, noticed in #23726 - Remove ghc-prim.cabal, it was accidentally committed in 524c60c8cd - - - - - ab40aa52 by Alan Zimmerman at 2023-08-22T15:14:28-04:00 EPA: Use Introduce [DeclTag] in AnnSortKey The AnnSortKey is used to keep track of the order of declarations for printing when the container has split them apart. This applies to HsValBinds and ClassDecl, ClsInstDecl. When making modifications to the list of declarations, the new order must be captured for when it must be printed. For each list of declarations (binds and sigs for a HsValBind) we can just store the list in order. To recreate the list when printing, we must merge them, and this is what the AnnSortKey records. It used to be indexed by SrcSpan, we now simply index by a marker as to which list to take the next item from. - - - - - e7db36c1 by sheaf at 2023-08-23T08:41:28-04:00 Don't attempt pattern synonym error recovery This commit gets rid of the pattern synonym error recovery mechanism (recoverPSB). The rationale is that the fake pattern synonym binding that the recovery mechanism introduced could lead to undesirable knock-on errors, and it isn't really feasible to conjure up a satisfactory binding as pattern synonyms can be used both in expressions and patterns. See Note [Pattern synonym error recovery] in GHC.Tc.TyCl.PatSyn. It isn't such a big deal to eagerly fail compilation on a pattern synonym that doesn't typecheck anyway. Fixes #23467 - - - - - 6ccd9d65 by Ben Gamari at 2023-08-23T08:42:05-04:00 base: Don't use Data.ByteString.Internals.memcpy This function is now deprecated from `bytestring`. Use `Foreign.Marshal.Utils.copyBytes` instead. Fixes #23880. - - - - - 0bfa0031 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Uniformly pass buildOptions to all builders in runBuilder In Builder.hs, runBuilderWith mostly ignores the buildOptions in BuildInfo. This leads to hard to diagnose bugs as any build options you pass with runBuilderWithCmdOptions are ignored for many builders. Solution: Uniformly pass buildOptions to the invocation of cmd. Fixes #23845 - - - - - 9cac8f11 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Abstract windows toolchain setup This commit splits up the windows toolchain setup logic into two functions. * FP_INSTALL_WINDOWS_TOOLCHAIN - deals with downloading the toolchain if it isn't already downloaded * FP_SETUP_WINDOWS_TOOLCHAIN - sets the environment variables to point to the correct place FP_SETUP_WINDOWS_TOOLCHAIN is abstracted from the location of the mingw toolchain and also the eventual location where we will install the toolchain in the installed bindist. This is the first step towards #23608 - - - - - 6c043187 by Matthew Pickering at 2023-08-23T13:43:48-04:00 Generate build.mk for bindists The config.mk.in script was relying on some variables which were supposed to be set by build.mk but therefore never were when used to install a bindist. Specifically * BUILD_PROF_LIBS to determine whether we had profiled libraries or not * DYNAMIC_GHC_PROGRAMS to determine whether we had shared libraries or not Not only were these never set but also not really accurate because you could have shared libaries but still statically linked ghc executable. In addition variables like GhcLibWays were just never used, so those have been deleted from the script. Now instead we generate a build.mk file which just directly specifies which RtsWays we have supplied in the bindist and whether we have DYNAMIC_GHC_PROGRAMS. - - - - - fe23629b by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add reloc-binary-dist-* targets This adds a command line option to build a "relocatable" bindist. The bindist is created by first creating a normal bindist and then installing it using the `RelocatableBuild=YES` option. This creates a bindist without any wrapper scripts pointing to the libdir. The motivation for this feature is that we want to ship relocatable bindists on windows and this method is more uniform than the ad-hoc method which lead to bugs such as #23608 and #23476 The relocatable bindist can be built with the "reloc-binary-dist" target and supports the same suffixes as the normal "binary-dist" command to specify the compression style. - - - - - 41cbaf44 by Matthew Pickering at 2023-08-23T13:43:48-04:00 packaging: Fix installation scripts on windows/RelocatableBuild case This includes quite a lot of small fixes which fix the installation makefile to work on windows properly. This also required fixing the RelocatableBuild variable which seemed to have been broken for a long while. Sam helped me a lot writing this patch by providing a windows machine to test the changes. Without him it would have taken ages to tweak everything. Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 03474456 by Matthew Pickering at 2023-08-23T13:43:48-04:00 ci: Build relocatable bindist on windows We now build the relocatable bindist target on windows, which means we test and distribute the new method of creating a relocatable bindist. - - - - - d0b48113 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Add error when trying to build binary-dist target on windows The binary dist produced by `binary-dist` target doesn't work on windows because of the wrapper script the makefile installs. In order to not surprise any packagers we just give an error if someone tries to build the old binary-dist target rather than the reloc-binary-dist target. - - - - - 7cbf9361 by Matthew Pickering at 2023-08-23T13:43:48-04:00 hadrian: Remove query' logic to use tooldir - - - - - 03fad42e by Matthew Pickering at 2023-08-23T13:43:48-04:00 configure: Set WindresCmd directly and removed unused variables For some reason there was an indirection via the Windres variable before setting WindresCmd. That indirection led to #23855. I then also noticed that these other variables were just not used anywhere when trying to work out what the correct condition was for this bit of the configure script. - - - - - c82770f5 by sheaf at 2023-08-23T13:43:48-04:00 Apply shellcheck suggestion to SUBST_TOOLDIR - - - - - 896e35e5 by sheaf at 2023-08-23T13:44:34-04:00 Compute hints from TcSolverReportMsg This commit changes how hints are handled in conjunction with constraint solver report messages. Instead of storing `[GhcHint]` in the TcRnSolverReport error constructor, we compute the hints depending on the underlying TcSolverReportMsg. This disentangles the logic and makes it easier to add new hints for certain errors. - - - - - a05cdaf0 by Alexander Esgen at 2023-08-23T13:45:16-04:00 users-guide: remove note about fatal Haddock parse failures - - - - - 4908d798 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Introduce Data.Enum - - - - - f59707c7 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Integer - - - - - b1054053 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num - - - - - 6baa481d by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Num.Natural - - - - - 2ac15233 by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Float - - - - - f3c489de by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add export list to GHC.Real - - - - - 94f59eaa by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Eliminate module reexport in GHC.Exception The metric increase here isn't strictly due to this commit but it's a rather small, incidental change. Metric Increase: T8095 T13386 Metric Decrease: T8095 T13386 T18304 - - - - - be1fc7df by Ben Gamari at 2023-08-23T17:36:41-04:00 base: Add disclaimers in internal modules To warn users that these modules are internal and their interfaces may change with little warning. As proposed in Core Libraries Committee #146 [CLC146]. [CLC146]: https://github.com/haskell/core-libraries-committee/issues/146 - - - - - 0326f3f4 by sheaf at 2023-08-23T17:37:29-04:00 Bump Cabal submodule We need to bump the Cabal submodule to include commit ec75950 which fixes an issue with a dodgy import Rep(..) which relied on GHC bug #23570 - - - - - 0504cd08 by Facundo Domínguez at 2023-08-23T17:38:11-04:00 Fix typos in the documentation of Data.OldList.permutations - - - - - 1420b8cb by Antoine Leblanc at 2023-08-24T16:18:17-04:00 Be more eager in TyCon boot validity checking This commit performs boot-file consistency checking for TyCons into checkValidTyCl. This ensures that we eagerly catch any mismatches, which prevents the compiler from seeing these inconsistencies and panicking as a result. See Note [TyCon boot consistency checking] in GHC.Tc.TyCl. Fixes #16127 - - - - - d99c816f by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Refactor estimation of stack info table provenance This commit greatly refactors the way we compute estimated provenance for stack info tables. Previously, this process was done using an entirely separate traversal of the whole Cmm code stream to build the map from info tables to source locations. The separate traversal is now fused with the Cmm code generation pipeline in GHC.Driver.Main. This results in very significant code generation speed ups when -finfo-table-map is enabled. In testing, this patch reduces code generation times by almost 30% with -finfo-table-map and -O0, and 60% with -finfo-table-map and -O1 or -O2 . Fixes #23103 - - - - - d3e0124c by Finley McIlwaine at 2023-08-24T16:18:55-04:00 Add a test checking overhead of -finfo-table-map We want to make sure we don't end up with poor codegen performance resulting from -finfo-table-map again as in #23103. This test adds a performance test tracking total allocations while compiling ExactPrint with -finfo-table-map. - - - - - fcfc1777 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Add export list to GHC.Llvm.MetaData - - - - - 5880fff6 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Allow LlvmLits in MetaExprs This omission appears to be an oversight. - - - - - 86ce92a2 by Ben Gamari at 2023-08-25T10:58:16-04:00 compiler: Move platform feature predicates to GHC.Driver.DynFlags These are useful in `GHC.Driver.Config.*`. - - - - - a6a38742 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Introduce infrastructure for module flag metadata - - - - - e9af2cf3 by Ben Gamari at 2023-08-25T10:58:16-04:00 llvmGen: Don't pass stack alignment via command line As of https://reviews.llvm.org/D103048 LLVM no longer supports the `-stack-alignment=...` flag. Instead this information is passed via a module flag metadata node. This requires dropping support for LLVM 11 and 12. Fixes #23870 - - - - - a936f244 by Alan Zimmerman at 2023-08-25T10:58:56-04:00 EPA: Keep track of "in" token for WarningTxt category A warning can now be written with a category, e.g. {-# WARNInG in "x-c" e "d" #-} Keep track of the location of the 'in' keyword and string, as well as the original SourceText of the label, in case it uses character escapes. - - - - - 3df8a653 by Matthew Pickering at 2023-08-25T17:42:18-04:00 Remove redundant import in InfoTableProv The copyBytes function is provided by the import of Foreign. Fixes #23889 - - - - - d6f807ec by Ben Gamari at 2023-08-25T17:42:54-04:00 gitlab/issue-template: Mention report-a-bug - - - - - 50b9f75d by Artin Ghasivand at 2023-08-26T20:02:50+03:30 Added StandaloneKindSignature examples to replace CUSKs ones - - - - - 2f6309a4 by Vladislav Zavialov at 2023-08-27T03:47:37-04:00 Remove outdated CPP in compiler/* and template-haskell/* The boot compiler was bumped to 9.4 in cebb5819b43. There is no point supporting older GHC versions with CPP. - - - - - 5248fdf7 by Zubin Duggal at 2023-08-28T15:01:09+05:30 testsuite: Add regression test for #23861 Simon says this was fixed by commit 8d68685468d0b6e922332a3ee8c7541efbe46137 Author: sheaf <sam.derbyshire at gmail.com> Date: Fri Aug 4 15:28:45 2023 +0200 Remove zonk in tcVTA - - - - - b6903f4d by Zubin Duggal at 2023-08-28T12:33:58-04:00 testsuite: Add regression test for #23864 Simon says this was fixed by commit 59202c800f2c97c16906120ab2561f6e1556e4af Author: Sebastian Graf <sebastian.graf at kit.edu> Date: Fri Mar 31 17:35:22 2023 +0200 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. - - - - - 9eecdf33 by sheaf at 2023-08-28T18:54:06+00:00 Remove ScopedTypeVariables => TypeAbstractions This commit implements [amendment 604](https://github.com/ghc-proposals/ghc-proposals/pull/604/) to [GHC proposal 448](https://github.com/ghc-proposals/ghc-proposals/pull/448) by removing the implication of language extensions ScopedTypeVariables => TypeAbstractions To limit breakage, we now allow type arguments in constructor patterns when both ScopedTypeVariables and TypeApplications are enabled, but we emit a warning notifying the user that this is deprecated behaviour that will go away starting in GHC 9.12. Fixes #23776 - - - - - fadd5b4d by sheaf at 2023-08-28T18:54:06+00:00 .stderr: ScopedTypeVariables =/> TypeAbstractions This commit accepts testsuite changes for the changes in the previous commit, which mean that TypeAbstractions is no longer implied by ScopedTypeVariables. - - - - - 4f5fb500 by Greg Steuck at 2023-08-29T07:55:13-04:00 Repair `codes` test on OpenBSD by explicitly requesting extended RE - - - - - 6bbde581 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23540 `T23540.hs` makes use of `explainEv` from `HieQueries.hs`, so `explainEv` has been moved to `TestUtils.hs`. - - - - - 257bb3bd by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Add test for #23120 - - - - - 4f192947 by Vasily Sterekhov at 2023-08-29T12:06:58-04:00 Make some evidence uses reachable by toHie Resolves #23540, #23120 This adds spans to certain expressions in the typechecker and renamer, and lets 'toHie' make use of those spans. Therefore the relevant evidence uses for the following syntax will now show up under the expected nodes in 'HieAst's: - Overloaded literals ('IsString', 'Num', 'Fractional') - Natural patterns and N+k patterns ('Eq', 'Ord', and instances from the overloaded literals being matched on) - Arithmetic sequences ('Enum') - Monadic bind statements ('Monad') - Monadic body statements ('Monad', 'Alternative') - ApplicativeDo ('Applicative', 'Functor') - Overloaded lists ('IsList') Also see Note [Source locations for implicit function calls] In the process of handling overloaded lists I added an extra 'SrcSpan' field to 'VAExpansion' - this allows us to more accurately reconstruct the locations from the renamer in 'rebuildHsApps'. This also happens to fix #23120. See the additions to Note [Looking through HsExpanded] - - - - - fe9fcf9d by Sylvain Henry at 2023-08-29T12:07:50-04:00 ghc-heap: rename C file (fix #23898) - - - - - b60d6576 by Krzysztof Gogolewski at 2023-08-29T12:08:29-04:00 Misc cleanup - Builtin.PrimOps: ReturnsAlg was used only for unboxed tuples. Rename to ReturnsTuple. - Builtin.Utils: use SDoc for a panic message. The comment about <<details unavailable>> was obsoleted by e8d356773b56. - TagCheck: fix wrong logic. It was zipping a list 'args' with its version 'args_cmm' after filtering. - Core.Type: remove an outdated 1999 comment about unlifted polymorphic types - hadrian: remove leftover debugging print - - - - - 3054fd6d by Krzysztof Gogolewski at 2023-08-29T12:09:08-04:00 Add a regression test for #23903 The bug has been fixed by commit bad2f8b8aa8424. - - - - - 21584b12 by Ben Gamari at 2023-08-29T19:52:02-04:00 README: Refer to ghc-hq repository for contributor and governance information - - - - - e542d590 by sheaf at 2023-08-29T19:52:40-04:00 Export setInertSet from GHC.Tc.Solver.Monad We used to export getTcSInerts and setTcSInerts from GHC.Tc.Solver.Monad. These got renamed to getInertSet/setInertSet in e1590ddc. That commit also removed the export of setInertSet, but that function is useful for the GHC API. - - - - - 694ec5b1 by sheaf at 2023-08-30T10:18:32-04:00 Don't bundle children for non-parent Avails We used to bundle all children of the parent Avail with things that aren't the parent, e.g. with class C a where type T a meth :: .. we would bundle the whole Avail (C, T, meth) with all of C, T and meth, instead of only with C. Avoiding this fixes #23570 - - - - - d926380d by Krzysztof Gogolewski at 2023-08-30T10:19:08-04:00 Fix typos - - - - - d07080d2 by Josh Meredith at 2023-08-30T19:42:32-04:00 JS: Implement missing C functions `rename`, `realpath`, and `getcwd` (#23806) - - - - - e2940272 by David Binder at 2023-08-30T19:43:08-04:00 Bump submodules of hpc and hpc-bin to version 0.7.0.0 hpc 0.7.0.0 dropped SafeHaskell safety guarantees in order to simplify compatibility with newer versions of the directory package which dropped all SafeHaskell guarantees. - - - - - 5d56d05c by David Binder at 2023-08-30T19:43:08-04:00 Bump hpc bound in ghc.cabal.in - - - - - 99fff496 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 ghc classes documentation: rm redundant comment - - - - - fe021bab by Dominik Schrempf at 2023-08-31T00:04:46-04:00 prelude documentation: various nits - - - - - 48c84547 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 integer documentation: minor corrections - - - - - 20cd12f4 by Dominik Schrempf at 2023-08-31T00:04:46-04:00 real documentation: nits - - - - - dd39bdc0 by sheaf at 2023-08-31T00:05:27-04:00 Add a test for #21765 This issue (of reporting a constraint as being redundant even though removing it causes typechecking to fail) was fixed in aed1974e. This commit simply adds a regression test. Fixes #21765 - - - - - f1ec3628 by Andrew Lelechenko at 2023-08-31T23:53:30-04:00 Export foldl' from Prelude and bump submodules See https://github.com/haskell/core-libraries-committee/issues/167 for discussion Metric Decrease: T8095 T13386 Metric Increase: T13386 T8095 T8095 ghc/alloc decreased on x86_64, but increased on aarch64. T13386 ghc/alloc decreased on x86_64-windows, but increased on other platforms. Neither has anything to do with `foldl'`, so I conclude that both are flaky. - - - - - 3181b97d by Gergő Érdi at 2023-08-31T23:54:06-04:00 Allow cross-tyvar defaulting proposals from plugins Fixes #23832. - - - - - e4af506e by Sebastian Graf at 2023-09-01T14:29:12-04:00 Clarify Note [GlobalId/LocalId] after CorePrep (#23797) Fixes #23797. - - - - - ac29787c by Sylvain Henry at 2023-09-01T14:30:02-04:00 Fix warning with UNPACK on sum type (#23921) - - - - - 9765ac7b by Zubin Duggal at 2023-09-05T00:37:45-04:00 hadrian: track python dependencies in doc rules - - - - - 1578215f by sheaf at 2023-09-05T00:38:26-04:00 Bump Haddock to fix #23616 This commit updates the Haddock submodule to include the fix to #23616. Fixes #23616 - - - - - 5a2fe35a by David Binder at 2023-09-05T00:39:07-04:00 Fix example in GHC user guide in SafeHaskell section The example given in the SafeHaskell section uses an implementation of Monad which no longer works. This MR removes the non-canonical return instance and adds the necessary instances of Functor and Applicative. - - - - - 291d81ae by Matthew Pickering at 2023-09-05T14:03:10-04:00 driver: Check transitive closure of haskell package dependencies when deciding whether to relink We were previously just checking whether direct package dependencies had been modified. This caused issues when compiling without optimisations as we wouldn't relink the direct dependency if one of its dependenices changed. Fixes #23724 - - - - - 35da0775 by Krzysztof Gogolewski at 2023-09-05T14:03:47-04:00 Re-export GHC.Utils.Panic.Plain from GHC.Utils.Panic Fixes #23930 - - - - - 3930d793 by Jaro Reinders at 2023-09-06T18:42:55-04:00 Make STG rewriter produce updatable closures - - - - - 0104221a by Krzysztof Gogolewski at 2023-09-06T18:43:32-04:00 configure: update message to use hadrian (#22616) - - - - - b34f8586 by Alan Zimmerman at 2023-09-07T10:58:38-04:00 EPA: Incorrect locations for UserTyVar with '@' In T13343.hs, the location for the @ is not within the span of the surrounding UserTyVar. type Bad @v = (forall (v1 :: RuntimeRep) (a1 :: TYPE v). a1) :: TYPE v Widen it so it is captured. Closes #23887 - - - - - 8046f020 by Finley McIlwaine at 2023-09-07T10:59:15-04:00 Bump haddock submodule to fix #23920 Removes the fake export of `FUN` from Prelude. Fixes #23920. Bumps haddock submodule. - - - - - e0aa8c6e by Krzysztof Gogolewski at 2023-09-07T11:00:03-04:00 Fix wrong role in mkSelCo_maybe In the Lint failure in #23938, we start with a coercion Refl :: T a ~R T a, and call mkSelCo (SelTyCon 1 nominal) Refl. The function incorrectly returned Refl :: a ~R a. The returned role should be nominal, according to the SelCo rule: co : (T s1..sn) ~r0 (T t1..tn) r = tyConRole tc r0 i ---------------------------------- SelCo (SelTyCon i r) : si ~r ti In this test case, r is nominal while r0 is representational. - - - - - 1d92f2df by Gergő Érdi at 2023-09-08T04:04:30-04:00 If we have multiple defaulting plugins, then we should zonk in between them after any defaulting has taken place, to avoid a defaulting plugin seeing a metavariable that has already been filled. Fixes #23821. - - - - - eaee4d29 by Gergő Érdi at 2023-09-08T04:04:30-04:00 Improvements to the documentation of defaulting plugins Based on @simonpj's draft and comments in !11117 - - - - - ede3df27 by Alan Zimmerman at 2023-09-08T04:05:06-04:00 EPA: Incorrect span for LWarnDec GhcPs The code (from T23465.hs) {-# WARNInG in "x-c" e "d" #-} e = e gives an incorrect span for the LWarnDecl GhcPs Closes #23892 It also fixes the Test23465/Test23464 mixup - - - - - a0ccef7a by Krzysztof Gogolewski at 2023-09-08T04:05:42-04:00 Valid hole fits: don't suggest unsafeCoerce (#17940) - - - - - 88b942c4 by Oleg Grenrus at 2023-09-08T19:58:42-04:00 Add warning for badly staged types. Resolves #23829. The stage violation results in out-of-bound names in splices. Technically this is an error, but someone might rely on this!? Internal changes: - we now track stages for TyVars. - thLevel (RunSplice _) = 0, instead of panic, as reifyInstances does in fact rename its argument type, and it can contain variables. - - - - - 9861f787 by Ben Gamari at 2023-09-08T19:59:19-04:00 rts: Fix invalid symbol type I suspect this code is dead since we haven't observed this failing despite the obviously incorrect macro name. - - - - - 03ed6a9a by Ben Gamari at 2023-09-08T19:59:19-04:00 testsuite: Add simple test exercising C11 atomics in GHCi See #22012. - - - - - 1aa5733a by Ben Gamari at 2023-09-08T19:59:19-04:00 rts/RtsSymbols: Add AArch64 outline atomic operations Fixes #22012 by adding the symbols described in https://github.com/llvm/llvm-project/blob/main/llvm/docs/Atomics.rst#libcalls-atomic. Ultimately this would be better addressed by #22011, but this is a first step in the right direction and fixes the immediate symptom. Note that we dropped the `__arch64_cas16` operations as these provided by all platforms's compilers. Also, we don't link directly against the libgcc/compiler-rt definitions but rather provide our own wrappers to work around broken toolchains (e.g. https://bugs.gentoo.org/868018). Generated via https://gitlab.haskell.org/ghc/ghc/-/snippets/5733. - - - - - 8f7d3041 by Matthew Pickering at 2023-09-08T19:59:55-04:00 ci: Build debian12 and fedora38 bindists This adds builds for the latest releases for fedora and debian We build these bindists in nightly and release pipelines. - - - - - a1f0d55c by Felix Leitz at 2023-09-08T20:00:37-04:00 Fix documentation around extension implication for MultiParamTypeClasses/ConstrainedClassMethods. - - - - - 98166389 by Teo Camarasu at 2023-09-12T04:30:54-04:00 docs: move -xn flag beside --nonmoving-gc It makes sense to have these beside each other as they are aliases. - - - - - f367835c by Teo Camarasu at 2023-09-12T04:30:55-04:00 nonmoving: introduce a family of dense allocators Supplement the existing power 2 sized nonmoving allocators with a family of dense allocators up to a configurable threshold. This should reduce waste from rounding up block sizes while keeping the amount of allocator sizes manageable. This patch: - Adds a new configuration option `--nonmoving-dense-allocator-count` to control the amount of these new dense allocators. - Adds some constants to `NonmovingAllocator` in order to keep marking fast with the new allocators. Resolves #23340 - - - - - 2b07bf2e by Teo Camarasu at 2023-09-12T04:30:55-04:00 Add changelog entry for #23340 - - - - - f96fe681 by sheaf at 2023-09-12T04:31:44-04:00 Use printGhciException in run{Stmt, Decls} When evaluating statements in GHCi, we need to use printGhciException instead of the printException function that GHC provides in order to get the appropriate error messages that are customised for ghci use. - - - - - d09b932b by psilospore at 2023-09-12T04:31:44-04:00 T23686: Suggest how to enable Language Extension when in ghci Fixes #23686 - - - - - da30f0be by Matthew Craven at 2023-09-12T04:32:24-04:00 Unarise: Split Rubbish literals in function args Fixes #23914. Also adds a check to STG lint that these args are properly unary or nullary after unarisation - - - - - 261b6747 by Matthew Pickering at 2023-09-12T04:33:04-04:00 darwin: Bump MAXOSX_DEPLOYMENT_TARGET to 10.13 This bumps the minumum supported version to 10.13 (High Sierra) which is 6 years old at this point. Fixes #22938 - - - - - f418f919 by Mario Blažević at 2023-09-12T04:33:45-04:00 Fix TH pretty-printing of nested GADTs, issue #23937 This commit fixes `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints GADTs declarations contained within data family instances. Fixes #23937 - - - - - d7a64753 by John Ericson at 2023-09-12T04:34:20-04:00 Put hadrian non-bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. This is picking up where ad8cfed4195b1bbfc15b841f010e75e71f63157d left off. - - - - - ff0a709a by Sylvain Henry at 2023-09-12T08:46:28-04:00 JS: fix some tests - Tests using Setup programs need to pass --with-hc-pkg - Several other fixes See https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/bug_triage for the current status - - - - - fc86f0e7 by Krzysztof Gogolewski at 2023-09-12T08:47:04-04:00 Fix in-scope set assertion failure (#23918) Patch by Simon - - - - - 21a906c2 by Matthew Pickering at 2023-09-12T17:21:04+02:00 Add -Winconsistent-flags warning The warning fires when inconsistent command line flags are passed. For example: * -dynamic-too and -dynamic * -dynamic-too on windows * -O and --interactive * etc This is on by default and allows users to control whether the warning is displayed and whether it should be an error or not. Fixes #22572 - - - - - dfc4f426 by Krzysztof Gogolewski at 2023-09-12T20:31:35-04:00 Avoid serializing BCOs with the internal interpreter Refs #23919 - - - - - 9217950b by Finley McIlwaine at 2023-09-13T08:06:03-04:00 Fix numa auto configure - - - - - 98e7c1cf by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Add -fno-cse to T15426 and T18964 This -fno-cse change is to avoid these performance tests depending on flukey CSE stuff. Each contains several independent tests, and we don't want them to interact. See #23925. By killing CSE we expect a 400% increase in T15426, and 100% in T18964. Metric Increase: T15426 T18964 - - - - - 236a134e by Simon Peyton Jones at 2023-09-13T08:06:40-04:00 Tiny refactor canEtaReduceToArity was only called internally, and always with two arguments equal to zero. This patch just specialises the function, and renames it to cantEtaReduceFun. No change in behaviour. - - - - - 56b403c9 by Ben Gamari at 2023-09-13T19:21:36-04:00 spec-constr: Lift argument limit for SPEC-marked functions When the user adds a SPEC argument to a function, they are informing us that they expect the function to be specialised. However, previously this instruction could be preempted by the specialised-argument limit (sc_max_args). Fix this. This fixes #14003. - - - - - 6840012e by Simon Peyton Jones at 2023-09-13T19:22:13-04:00 Fix eta reduction Issue #23922 showed that GHC was bogusly eta-reducing a join point. We should never eta-reduce (\x -> j x) to j, if j is a join point. It is extremly difficult to trigger this bug. It took me 45 mins of trying to make a small tests case, here immortalised as T23922a. - - - - - e5c00092 by Andreas Klebinger at 2023-09-14T08:57:43-04:00 Profiling: Properly escape characters when using `-pj`. There are some ways in which unusual characters like quotes or others can make it into cost centre names. So properly escape these. Fixes #23924 - - - - - ec490578 by Ellie Hermaszewska at 2023-09-14T08:58:24-04:00 Use clearer example variable names for bool eliminator - - - - - 5126a2fe by Sylvain Henry at 2023-09-15T11:18:02-04:00 Add missing int64/word64-to-double/float rules (#23907) CLC proposal: https://github.com/haskell/core-libraries-committee/issues/203 - - - - - 566ef411 by Mario Blažević at 2023-09-15T11:18:43-04:00 Fix and test TH pretty-printing of type operator role declarations This commit fixes and tests `Language.Haskell.TH.Ppr.pprint` so that it correctly pretty-prints `type role` declarations for operator names. Fixes #23954 - - - - - 8e05c54a by Simon Peyton Jones at 2023-09-16T01:42:33-04:00 Use correct FunTyFlag in adjustJoinPointType As the Lint error in #23952 showed, the function adjustJoinPointType was failing to adjust the FunTyFlag when adjusting the type. I don't think this caused the seg-fault reported in the ticket, but it is definitely. This patch fixes it. It is tricky to come up a small test case; Krzysztof came up with this one, but it only triggers a failure in GHC 9.6. - - - - - 778c84b6 by Pierre Le Marre at 2023-09-16T01:43:15-04:00 Update to Unicode 15.1.0 See: https://www.unicode.org/versions/Unicode15.1.0/ - - - - - f9d79a6c by Alan Zimmerman at 2023-09-18T00:00:14-04:00 EPA: track unicode version for unrestrictedFunTyCon Closes #23885 Updates haddock submodule - - - - - 9374f116 by Andrew Lelechenko at 2023-09-18T00:00:54-04:00 Bump parsec submodule to allow text-2.1 and bytestring-0.12 - - - - - 7ca0240e by Ben Gamari at 2023-09-18T15:16:48-04:00 base: Advertise linear time of readFloat As noted in #23538, `readFloat` has runtime that scales nonlinearly in the size of its input. Consequently, its use on untrusted input can be exploited as a denial-of-service vector. Point this out and suggest use of `read` instead. See #23538. - - - - - f3f58f13 by Simon Peyton Jones at 2023-09-18T15:17:24-04:00 Remove dead code GHC.CoreToStg.Prep.canFloat This function never fires, so we can delete it: #23965. - - - - - ccab5b15 by Ben Gamari at 2023-09-18T15:18:02-04:00 base/changelog: Move fix for #23907 to 9.8.1 section Since the fix was backported to 9.8.1 - - - - - 51b57d65 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64 alpine bindist This is dynamically linked and makes creating statically linked executables more straightforward. Fixes #23482 - - - - - 02c87213 by Matthew Pickering at 2023-09-19T08:44:31-04:00 Add aarch64-deb11 bindist This adds a debian 11 release job for aarch64. Fixes #22005 - - - - - 8b61dfd6 by Alexis King at 2023-09-19T08:45:13-04:00 Don’t store the async exception masking state in CATCH frames - - - - - 86d2971e by doyougnu at 2023-09-19T19:08:19-04:00 compiler,ghci: error codes link to HF error index closes: #23259 - adds -fprint-error-index-links={auto|always|never} flag - - - - - 5f826c18 by sheaf at 2023-09-19T19:09:03-04:00 Pass quantified tyvars in tcDefaultAssocDecl This commit passes the correct set of quantified type variables written by the user in associated type default declarations for validity checking. This ensures that validity checking of associated type defaults mirrors that of standalone type family instances. Fixes #23768 (see testcase T23734 in subsequent commit) - - - - - aba18424 by sheaf at 2023-09-19T19:09:03-04:00 Avoid panic in mkGADTVars This commit avoids panicking in mkGADTVars when we encounter a type variable as in #23784 that is bound by a user-written forall but not actually used. Fixes #23784 - - - - - a525a92a by sheaf at 2023-09-19T19:09:03-04:00 Adjust reporting of unused tyvars in data FamInsts This commit adjusts the validity checking of data family instances to improve the reporting of unused type variables. See Note [Out of scope tvs in data family instances] in GHC.Tc.Validity. The problem was that, in a situation such as data family D :: Type data instance forall (d :: Type). D = MkD the RHS passed to 'checkFamPatBinders' would be the TyCon app R:D d which mentions the type variable 'd' quantified in the user-written forall. Thus, when computing the set of unused type variables in the RHS of the data family instance, we would find that 'd' is used, and report a strange error message that would say that 'd' is not bound on the LHS. To fix this, we special-case the data-family instance case, manually extracting all the type variables that appear in the arguments of all the data constructores of the data family instance. Fixes #23778 - - - - - 28dd52ee by sheaf at 2023-09-19T19:09:03-04:00 Unused tyvars in FamInst: only report user tyvars This commit changes how we perform some validity checking for coercion axioms to mirror how we handle default declarations for associated type families. This allows us to keep track of whether type variables in type and data family instances were user-written or not, in order to only report the user-written ones in "unused type variable" error messages. Consider for example: {-# LANGUAGE PolyKinds #-} type family F type instance forall a. F = () In this case, we get two quantified type variables, (k :: Type) and (a :: k); the second being user-written, but the first is introduced by the typechecker. We should only report 'a' as being unused, as the user has no idea what 'k' is. Fixes #23734 - - - - - 1eed645c by sheaf at 2023-09-19T19:09:03-04:00 Validity: refactor treatment of data families This commit refactors the reporting of unused type variables in type and data family instances to be more principled. This avoids ad-hoc logic in the treatment of data family instances. - - - - - 35bc506b by John Ericson at 2023-09-19T19:09:40-04:00 Remove `ghc-cabal` It is dead code since the Make build system was removed. I tried to go over every match of `git grep -i ghc-cabal` to find other stray bits. Some of those might be workarounds that can be further removed. - - - - - 665ca116 by John Paul Adrian Glaubitz at 2023-09-19T19:10:39-04:00 Re-add unregisterised build support for sparc and sparc64 Closes #23959 - - - - - 142f8740 by Matthew Pickering at 2023-09-19T19:11:16-04:00 Bump ci-images to use updated version of Alex Fixes #23977 - - - - - fa977034 by John Ericson at 2023-09-21T12:55:25-04:00 Use Cabal 3.10 for Hadrian We need the newer version for `CABAL_FLAG_*` env vars for #17191. - - - - - a5d22cab by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: `need` any `configure` script we will call When the script is changed, we should reconfigure. - - - - - db882b57 by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Make it easier to debug Cabal configure Right now, output is squashed. This make per-package configure scripts extremely hard to maintain, because we get vague "library is missing" errors when the actually probably is usually completely unrelated except for also involving the C/C++ toolchain. (I can always pass `-VVV` to Hadrian locally, but these errors are subtle and I often cannot reproduce them locally!) `--disable-option-checking` was added back in 75c6e0684dda585c37b4ac254cd7a13537a59a91 but seems to be a bit overkill; if other flags are passed that are not recognized behind the two from Cabal mentioned in the former comment, we *do* want to know about it. - - - - - 7ed65f5a by John Ericson at 2023-09-21T12:55:25-04:00 hadrian: Increase verbosity of certain cabal commands This is a hack to get around the cabal function we're calling *decreasing* the verbosity it passes to another function, which is the stuff we often actually care about. Sigh. Keeping this a separate commit so if this makes things too verbose it is easy to revert. - - - - - a4fde569 by John Ericson at 2023-09-21T12:55:25-04:00 rts: Move most external symbols logic to the configure script This is much more terse because we are programmatically handling the leading underscore. `findPtr` however is still handled in the Cabal file because we need a newer Cabal to pass flags to the configure script automatically. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 56cc85fb by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump Cabal submodule to allow text-2.1 and bytestring-0.12 - - - - - 0cd6148c by Matthew Pickering at 2023-09-21T12:56:21-04:00 hadrian: Generate Distribution/Fields/Lexer.x before creating a source-dist - - - - - b10ba6a3 by Andrew Lelechenko at 2023-09-21T12:56:21-04:00 Bump hadrian's index-state to upgrade alex at least to 3.2.7.3 - - - - - 11ecc37b by Luite Stegeman at 2023-09-21T12:57:03-04:00 JS: correct file size and times Programs produced by the JavaScript backend were returning incorrect file sizes and modification times, causing cabal related tests to fail. This fixes the problem and adds an additional test that verifies basic file information operations. fixes #23980 - - - - - b35fd2cd by Ben Gamari at 2023-09-21T12:57:39-04:00 gitlab-ci: Drop libiserv from upload_ghc_libs libiserv has been merged into the ghci package. - - - - - 37ad04e8 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Fix Windows line endings - - - - - 5795b365 by Ben Gamari at 2023-09-21T12:58:15-04:00 testsuite: Use makefile_test - - - - - 15118740 by Ben Gamari at 2023-09-21T12:58:55-04:00 system-cxx-std-lib: Add license and description - - - - - 0208f1d5 by Ben Gamari at 2023-09-21T12:59:33-04:00 gitlab/issue-templates: Rename bug.md -> default.md So that it is visible by default. - - - - - 23cc3f21 by Andrew Lelechenko at 2023-09-21T20:18:11+01:00 Bump submodule text to 2.1 - - - - - b8e4fe23 by Andrew Lelechenko at 2023-09-22T20:05:05-04:00 Bump submodule unix to 2.8.2.1 - - - - - 54b2016e by John Ericson at 2023-09-23T11:40:41-04:00 Move lib{numa,dw} defines to RTS configure Clean up the m4 to handle the auto case always and be more consistent. Also simplify the CPP --- we should always have both headers if we are using libnuma. "side effects" (AC_DEFINE, and AC_SUBST) are removed from the macros to better separate searching from actions taken based on search results. This might seem overkill now, but will make shuffling logic between configure scripts easier later. The macro comments are converted from `dnl` to `#` following the recomendation in https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Macro-Definitions.html - - - - - d51b601b by John Ericson at 2023-09-23T11:40:50-04:00 Shuffle libzstd configuring between scripts Like the prior commit for libdw and libnuma, `AC_DEFINE` to RTS configure, `AC_SUBST` goes to the top-level configure script, and the documentation of the m4 macro is improved. - - - - - d1425af0 by John Ericson at 2023-09-23T11:41:03-04:00 Move `FP_ARM_OUTLINE_ATOMICS` to RTS configure It is just `AC_DEFINE` it belongs there instead. - - - - - 18de37e4 by John Ericson at 2023-09-23T11:41:03-04:00 Move mmap in the runtime linker check to the RTS configure `AC_DEFINE` should go there instead. - - - - - 74132c2b by Andrew Lelechenko at 2023-09-25T21:56:54-04:00 Elaborate comment on GHC_NO_UNICODE - - - - - de142aa2 by Ben Gamari at 2023-09-26T15:25:03-04:00 gitlab-ci: Mark T22012 as broken on CentOS 7 Due to #23979. - - - - - 6a896ce8 by Teo Camarasu at 2023-09-26T15:25:39-04:00 hadrian: better error for failing to find file's dependencies Resolves #24004 - - - - - d697a6c2 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers . map` This patch changes occurences of the idiom `partitionEithers (map f xs)` by the simpler form `partitionWith f xs` where `partitionWith` is the utility function defined in `GHC.Utils.Misc`. Resolves: #23953 - - - - - 8a2968b7 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Refactor uses of `partitionEithers <$> mapM f xs` This patch changes occurences of the idiom `partitionEithers <$> mapM f xs` by the simpler form `partitionWithM f xs` where `partitionWithM` is a utility function newly added to `GHC.Utils.Misc`. - - - - - 6a27eb97 by Stefan Holdermans at 2023-09-26T20:58:37+00:00 Mark `GHC.Utils.Misc.partitionWithM` as inlineable This patch adds an `INLINEABLE` pragma for `partitionWithM` to ensure that the right-hand side of the definition of this function remains available for specialisation at call sites. - - - - - f1e5245a by David Binder at 2023-09-27T01:19:00-04:00 Add RTS option to supress tix file - - - - - 1f43124f by David Binder at 2023-09-27T01:19:00-04:00 Add expected output to testsuite in test interface-stability/base-exports - - - - - b9d2c354 by David Binder at 2023-09-27T01:19:00-04:00 Expose HpcFlags and getHpcFlags from GHC.RTS.Flags - - - - - 345675c6 by David Binder at 2023-09-27T01:19:00-04:00 Fix expected output of interface-stability test - - - - - 146e1c39 by David Binder at 2023-09-27T01:19:00-04:00 Implement getHpcFlags - - - - - 61ba8e20 by David Binder at 2023-09-27T01:19:00-04:00 Add section in user guide - - - - - ea05f890 by David Binder at 2023-09-27T01:19:01-04:00 Rename --emit-tix-file to --write-tix-file - - - - - cabce2ce by David Binder at 2023-09-27T01:19:01-04:00 Update the golden files for interface stability - - - - - 1dbdb9d0 by Krzysztof Gogolewski at 2023-09-27T01:19:37-04:00 Refactor: introduce stgArgRep The function 'stgArgType' returns the type in STG. But this violates the abstraction: in STG we're supposed to operate on PrimReps. This introduces stgArgRep ty = typePrimRep (stgArgType ty) stgArgRep1 ty = typePrimRep1 (stgArgType ty) stgArgRep_maybe ty = typePrimRep_maybe (stgArgType ty) stgArgType is still directly used for unboxed tuples (should be fixable), FFI and in ticky. - - - - - b02f8042 by Mario Blažević at 2023-09-27T17:33:28-04:00 Fix TH pretty-printer's parenthesization This PR Fixes `Language.Haskell.TH.Ppr.pprint` so it correctly emits parentheses where needed. Fixes #23962, #23968, #23971, and #23986 - - - - - 79104334 by Krzysztof Gogolewski at 2023-09-27T17:34:04-04:00 Add a testcase for #17564 The code in the ticket relied on the behaviour of Derived constraints. Derived constraints were removed in GHC 9.4 and now the code works as expected. - - - - - d7a80143 by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add new modes of operation This commit adds two new modes of operation to the lint-codes utility: list - list all statically used diagnostic codes outdated - list all outdated diagnostic codes The previous behaviour is now: test - test consistency and coverage of diagnostic codes - - - - - 477d223c by sheaf at 2023-09-28T03:25:53-04:00 lint codes: avoid using git-grep We manually traverse through the filesystem to find the diagnostic codes embedded in .stdout and .stderr files, to avoid any issues with old versions of grep. Fixes #23843 - - - - - a38ae69a by sheaf at 2023-09-28T03:25:53-04:00 lint-codes: add Hadrian targets This commit adds new Hadrian targets: codes, codes:used - list all used diagnostic codes codes:outdated - list outdated diagnostic codes This allows users to easily query GHC for used and outdated diagnostic codes, e.g. hadrian/build -j --flavour=<..> codes will list all used diagnostic codes in the command line by running the lint-codes utility in the "list codes" mode of operation. The diagnostic code consistency and coverage test is still run as usual, through the testsuite: hadrian/build test --only="codes" - - - - - 9cdd629b by Ben Gamari at 2023-09-28T03:26:29-04:00 hadrian: Install LICENSE files in bindists Fixes #23548. - - - - - b8ebf876 by Matthew Craven at 2023-09-28T03:27:05-04:00 Fix visibility when eta-reducing a type lambda Fixes #24014. - - - - - d3874407 by Torsten Schmits at 2023-09-30T16:08:10-04:00 Fix several mistakes around free variables in iface breakpoints Fixes #23612 , #23607, #23998 and #23666. MR: !11026 The fingerprinting logic in `Iface.Recomp` failed lookups when processing decls containing breakpoints for two reasons: * IfaceBreakpoint created binders for free variables instead of expressions * When collecting free names for the dependency analysis for fingerprinting, breakpoint FVs were skipped - - - - - ef5342cd by Simon Peyton Jones at 2023-09-30T16:08:48-04:00 Refactor to combine HsLam and HsLamCase This MR is pure refactoring (#23916): * Combine `HsLam` and `HsLamCase` * Combine `HsCmdLam` and `HsCmdLamCase` This just arranges to treat uniformly \x -> e \case pi -> ei \cases pis -> ie In the exising code base the first is treated differently to the latter two. No change in behaviour. More specifics: * Combine `HsLam` and `HsLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsExpr`) into one data construtor covering * Lambda * `\case` * `\cases` * The new `HsLam` has an argument of type `HsLamVariant` to distinguish the three cases. * Similarly, combine `HsCmdLam` and `HsCmdLamCase` (constructors of `Language.Haskell.Syntax.Expr.HsCmd` ) into one. * Similarly, combine `mkHsLamPV` and `mkHsLamCasePV` (methods of class `DisambECP`) into one. (Thank you Alan Zimmerman.) * Similarly, combine `LambdaExpr` and `LamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsMatchContext`) into one: `LamAlt` with a `HsLamVariant` argument. * Similarly, combine `KappaExpr` and `ArrowLamCaseAlt` (constructors of `Language.Haskell.Syntax.Expr.HsArrowMatchContext`) into one: `ArrowLamAlt` with a `HsLamVariant` argument. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * Similarly, combine `PsErrLambdaInPat` and `PsErrLambdaCaseInPat` (constructors of `GHC.Parser.Errors.Ppr.PsError`) into one. * In the same `PsError` data type, combine `PsErrLambdaCmdInFunAppCmd` and `PsErrLambdaCaseCmdInFunAppCmd` into one. * In the same `PsError` data tpye, combine `PsErrLambdaInFunAppExpr` and `PsErrLambdaCaseInFunAppExpr` into one. p* Smilarly combine `ExpectedFunTyLam` and `ExpectedFunTyLamCase` (constructors of `GHC.Tc.Types.Origin.ExpectedFunTyOrigin`) into one. Phew! - - - - - b048bea0 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 Arm: Make ppr methods easier to use by not requiring NCGConfig - - - - - 2adc0508 by Andreas Klebinger at 2023-09-30T16:09:24-04:00 AArch64: Fix broken conditional jumps for offsets >= 1MB Rewrite conditional jump instructions with offsets >= 1MB to use unconditional jumps to avoid overflowing the immediate. Fixes #23746 - - - - - 1424f790 by Alan Zimmerman at 2023-09-30T16:10:00-04:00 EPA: Replace Monoid with NoAnn We currently use the Monoid class as a constraint on Exact Print Annotation functions, so we can use mempty. But this leads to requiring Semigroup instances too, which do not always make sense. Instead, introduce a class NoAnn, with a function noAnn analogous to mempty. Closes #20372 Updates haddock submodule - - - - - c1a3ecde by Ben Gamari at 2023-09-30T16:10:36-04:00 users-guide: Refactor handling of :base-ref: et al. - - - - - bc204783 by Richard Eisenberg at 2023-10-02T14:50:52+02:00 Simplify and correct nasty case in coercion opt This fixes #21062. No test case, because triggering this code seems challenging. - - - - - 9c9ca67e by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Bump bytestring submodule to 0.12.0.2 - - - - - 4e46dc2b by Andrew Lelechenko at 2023-10-04T05:42:28-04:00 Inline bucket_match - - - - - f6b2751f by Ben Gamari at 2023-10-04T05:43:05-04:00 configure: Fix #21712 again This is a bit of a shot in the dark to fix #24033, which appears to be another instance of #21712. For some reason the ld-override logic *still* appears to be active on Darwin targets (or at least one). Consequently, on misconfigured systems we may choose a non-`ld64` linker. It's a bit unclear exactly what happened in #24033 but ultimately the check added for #21712 was not quite right, checking for the `ghc_host_os` (the value of which depends upon the bootstrap compiler) instead of the target platform. Fix this. Fixes #24033. - - - - - 2f0a101d by Krzysztof Gogolewski at 2023-10-04T05:43:42-04:00 Add a regression test for #24029 - - - - - 8cee3fd7 by sheaf at 2023-10-04T05:44:22-04:00 Fix non-symbolic children lookup of fixity decl The fix for #23664 did not correctly account for non-symbolic names when looking up children of a given parent. This one-line fix changes that. Fixes #24037 - - - - - a4785b33 by Cheng Shao at 2023-10-04T05:44:59-04:00 rts: fix incorrect ticket reference - - - - - e037f459 by Ben Gamari at 2023-10-04T05:45:35-04:00 users-guide: Fix discussion of -Wpartial-fields * fix a few typos * add a new example showing when the warning fires * clarify the existing example * point out -Wincomplete-record-selects Fixes #24049. - - - - - 8ff3134e by Matthew Pickering at 2023-10-05T05:34:58-04:00 Revert "Pass preprocessor options to C compiler when building foreign C files (#16737)" This reverts commit 1c18d3b41f897f34a93669edaebe6069f319f9e2. `-optP` should pass options to the preprocessor, that might be a very different program to the C compiler, so passing the options to the C compiler is likely to result in `-optP` being useless. Fixes #17185 and #21291 - - - - - 8f6010b9 by Ben Gamari at 2023-10-05T05:35:36-04:00 rts/nonmoving: Fix on LLP64 platforms Previously `NONMOVING_SEGMENT_MASK` and friends were defined with the `UL` size suffix. However, this is wrong on LLP64 platforms like Windows, where `long` is 32-bits. Fixes #23003. Fixes #24042. - - - - - f20d02f8 by Andreas Klebinger at 2023-10-05T05:36:14-04:00 Fix isAArch64Bitmask for 32bit immediates. Fixes #23802 - - - - - 63afb701 by Bryan Richter at 2023-10-05T05:36:49-04:00 Work around perf note fetch failure Addresses #24055. - - - - - 242102f4 by Krzysztof Gogolewski at 2023-10-05T05:37:26-04:00 Add a test for #21348 - - - - - 7d390bce by Rewbert at 2023-10-05T05:38:08-04:00 Fixes #24046 - - - - - 69abb171 by Finley McIlwaine at 2023-10-06T14:06:28-07:00 Ensure unconstrained instance dictionaries get IPE info In the `StgRhsCon` case of `GHC.Stg.Debug.collectStgRhs`, we were not coming up with an initial source span based on the span of the binder, which was causing instance dictionaries without dynamic superclass constraints to not have source locations in their IPE info. Now they do. Resolves #24005 - - - - - 390443b7 by Andreas Klebinger at 2023-10-07T10:00:20-04:00 rts: Split up rts/include/stg/MachRegs.h by arch - - - - - 3685942f by Bryan Richter at 2023-10-07T10:00:56-04:00 Actually set hackage index state Or at least, use a version of the cabal command that *claims* to set the index state. Time will tell. - - - - - 46a0e5be by Bryan Richter at 2023-10-07T10:00:56-04:00 Update hackage index state - - - - - d4b037de by Bryan Richter at 2023-10-07T10:00:56-04:00 Ensure hadrian uses CI's hackage index state - - - - - e206be64 by Andrew Lelechenko at 2023-10-08T15:06:14-04:00 Do not use O_NONBLOCK on regular files or block devices CLC proposal https://github.com/haskell/core-libraries-committee/issues/166 - - - - - a06197c4 by David Binder at 2023-10-08T15:06:55-04:00 Update hpc-bin submodule to 0.69 - - - - - ed6785b6 by David Binder at 2023-10-08T15:06:55-04:00 Update Hadrian with correct path to happy file for hpc-bin - - - - - 94066d58 by Alan Zimmerman at 2023-10-09T21:35:53-04:00 EPA: Introduce HasAnnotation class The class is defined as class HasAnnotation e where noAnnSrcSpan :: SrcSpan -> e This generalises noAnnSrcSpan, and allows noLocA :: (HasAnnotation e) => a -> GenLocated e a noLocA = L (noAnnSrcSpan noSrcSpan) - - - - - 8792a1bc by Ben Gamari at 2023-10-09T21:36:29-04:00 Bump unix submodule to v2.8.3.0 - - - - - e96c51cb by Andreas Klebinger at 2023-10-10T16:44:27+01:00 Add a flag -fkeep-auto-rules to optionally keep auto-generated rules around. The motivation for the flag is given in #21917. - - - - - 3ed58cef by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Add ghcToolchain to tool args list This allows you to load ghc-toolchain and ghc-toolchain-bin into HLS. - - - - - 476c02d4 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Normalise triple via config.sub We were not normalising the target triple anymore like we did with the old make build system. Fixes #23856 - - - - - 303dd237 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add missing vendor normalisation This is copied from m4/ghc_convert_vendor.m4 Towards #23868 - - - - - 838026c9 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add loongarch64 to parseArch Towards #23868 - - - - - 1a5bc0b5 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Add same LD hack to ghc-toolchain In the ./configure script, if you pass the `LD` variable then this has the effect of stopping use searching for a linker and hence passing `-fuse-ld=...`. We want to emulate this logic in ghc-toolchain, if a use explicilty specifies `LD` variable then don't add `-fuse-ld=..` with the goal of making ./configure and ghc-toolchain agree on which flags to use when using the C compiler as a linker. This is quite unsavoury as we don't bake the choice of LD into the configuration anywhere but what's important for now is making ghc-toolchain and ./configure agree as much as possible. See #23857 for more discussion - - - - - 42d50b5a by Ben Gamari at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check for C99 support with -std=c99 Previously we failed to try enabling C99 support with `-std=c99`, as `autoconf` attempts. This broke on older compilers (e.g. CentOS 7) which don't enable C99 by default. Fixes #23879. - - - - - da2961af by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Add endianess check using __BYTE_ORDER__ macro In very old toolchains the BYTE_ORDER macro is not set but thankfully the __BYTE_ORDER__ macro can be used instead. - - - - - d8da73cd by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: AC_PATH_TARGET_TOOL for LD We want to make sure that LD is set to an absolute path in order to be consistent with the `LD=$(command -v ld)` call. The AC_PATH_TARGET_TOOL macro uses the absolute path rather than AC_CHECK_TARGET_TOOL which might use a relative path. - - - - - 171f93cc by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Check whether we need -std=gnu99 for CPP as well In ./configure the C99 flag is passed to the C compiler when used as a C preprocessor. So we also check the same thing in ghc-toolchain. - - - - - 89a0918d by Matthew Pickering at 2023-10-10T19:01:22-04:00 Check for --target linker flag separately to C compiler There are situations where the C compiler doesn't accept `--target` but when used as a linker it does (but doesn't do anything most likely) In particular with old gcc toolchains, the C compiler doesn't support --target but when used as a linker it does. - - - - - 37218329 by Matthew Pickering at 2023-10-10T19:01:22-04:00 Use Cc to compile test file in nopie check We were attempting to use the C compiler, as a linker, to compile a file in the nopie check, but that won't work in general as the flags we pass to the linker might not be compatible with the ones we pass when using the C compiler. - - - - - 9b2dfd21 by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Error when ghc-toolchain fails to compile This is a small QOL change as if you are working on ghc-toolchain and it fails to compile then configure will continue and can give you outdated results. - - - - - 1f0de49a by Matthew Pickering at 2023-10-10T19:01:22-04:00 configure: Check whether -no-pie works when the C compiler is used as a linker `-no-pie` is a flag we pass when using the C compiler as a linker (see pieCCLDOpts in GHC.Driver.Session) so we should test whether the C compiler used as a linker supports the flag, rather than just the C compiler. - - - - - 62cd2579 by Matthew Pickering at 2023-10-10T19:01:22-04:00 ghc-toolchain: Remove javascript special case for --target detection emcc when used as a linker seems to ignore the --target flag, and for consistency with configure which now tests for --target, we remove this special case. - - - - - 0720fde7 by Ben Gamari at 2023-10-10T19:01:22-04:00 toolchain: Don't pass --target to emscripten toolchain As noted in `Note [Don't pass --target to emscripten toolchain]`, emscripten's `emcc` is rather inconsistent with respect to its treatment of the `--target` flag. Avoid this by special-casing this toolchain in the `configure` script and `ghc-toolchain`. Fixes on aspect of #23744. - - - - - 6354e1da by Matthew Pickering at 2023-10-10T19:01:22-04:00 hadrian: Don't pass `--gcc-options` as a --configure-arg to cabal configure Stop passing -gcc-options which mixed together linker flags and non-linker flags. There's no guarantee the C compiler will accept both of these in each mode. - - - - - c00a4bd6 by Ben Gamari at 2023-10-10T19:01:22-04:00 configure: Probe stage0 link flags For consistency with later stages and CC. - - - - - 1f11e7c4 by Sebastian Graf at 2023-10-10T19:01:58-04:00 Stricter Binary.get in GHC.Types.Unit (#23964) I noticed some thunking while looking at Core. This change has very modest, but throughout positive ghc/alloc effect: ``` hard_hole_fits(normal) ghc/alloc 283,057,664 281,620,872 -0.5% geo. mean -0.1% minimum -0.5% maximum +0.0% ``` Fixes #23964. - - - - - a4f1a181 by Bryan Richter at 2023-10-10T19:02:37-04:00 rel_eng/upload.sh cleanups - - - - - 80705335 by doyougnu at 2023-10-10T19:03:18-04:00 ci: add javascript label rule This adds a rule which triggers the javascript job when the "javascript" label is assigned to an MR. - - - - - a2c0fff6 by Matthew Craven at 2023-10-10T19:03:54-04:00 Make 'wWarningFlagsDeps' include every WarningFlag Fixes #24071. - - - - - d055f099 by Jan Hrček at 2023-10-10T19:04:33-04:00 Fix pretty printing of overlap pragmas in TH splices (fixes #24074) - - - - - 0746b868 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch64 NCG: Use encoded immediates for literals. Try to generate instr x2, <imm> instead of mov x1, lit instr x2, x1 When possible. This get's rid if quite a few redundant mov instructions. I believe this causes a metric decrease for LargeRecords as we reduce register pressure. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 739f4e6f by Andreas Klebinger at 2023-10-10T19:05:09-04:00 AArch NCG: Refactor getRegister' Remove some special cases which can be handled just as well by the generic case. This increases code re-use while also fixing #23749. Since some of the special case wasn't upholding Note [Signed arithmetic on AArch64]. - - - - - 1b213d33 by Andreas Klebinger at 2023-10-10T19:05:09-04:00 Aarch ncg: Optimize immediate use for address calculations When the offset doesn't fit into the immediate we now just reuse the general getRegister' code path which is well optimized to compute the offset into a register instead of a special case for CmmRegOff. This means we generate a lot less code under certain conditions which is why performance metrics for these improve. ------------------------- Metric Decrease: T4801 T5321FD T5321Fun ------------------------- - - - - - b7df0732 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over mem management checks These are for heap allocation, a strictly RTS concern. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. The RTS configure one has a new ``` AC_CHECK_SIZEOF([void *]) ``` that the top-level configure version didn't have, so that `ac_cv_sizeof_void_p` is defined. Once more code is moved over in latter commits, that can go away. Progress towards #17191 - - - - - 41130a65 by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `__thread` check This used by (@bgamari thinks) the `GCThread` abstraction in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - cc5ec2bd by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over misc function checks These are for general use in the RTS. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 809e7c2d by John Ericson at 2023-10-11T16:02:11-04:00 RTS configure: Move over `eventfd` check This check is for the RTS part of the event manager and has a corresponding part in `base`. All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - 58f3babf by John Ericson at 2023-10-11T16:02:48-04:00 Split `FP_CHECK_PTHREADS` and move part to RTS configure `NEED_PTHREAD_LIB` is unused since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system), and so is no longer defined. Progress towards #17191 - - - - - e99cf237 by Moritz Angermann at 2023-10-11T16:03:24-04:00 nativeGen: section flags for .text$foo only Commit 3ece9856d157c85511d59f9f862ab351bbd9b38b, was supposed to fix #22834 in !9810. It does however add "xr" indiscriminatly to .text sections even if splitSections is disabled. This leads to the assembler saying: ghc_1.s:7849:0: error: Warning: Ignoring changed section attributes for .text | 7849 | .section .text,"xr" | ^ - - - - - f383a242 by Sylvain Henry at 2023-10-11T16:04:04-04:00 Modularity: pass TempDir instead of DynFlags (#17957) - - - - - 34fc28b0 by John Ericson at 2023-10-12T06:48:28-04:00 Test that functions from `mingwex` are available Ryan wrote these two minimizations, but they never got added to the test suite. See #23309, #23378 Co-Authored-By: Ben Gamari <bgamari.foss at gmail.com> Co-Authored-By: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - bdb54a0e by John Ericson at 2023-10-12T06:48:28-04:00 Do not check for the `mingwex` library in `/configure` See the recent discussion in !10360 --- Cabal will itself check for the library for the packages that need it, and while the autoconf check additionally does some other things like define a `HAS_LIBMINGWEX` C Preprocessor macro, those other things are also unused and unneeded. Progress towards #17191, which aims to get rid of `/configure` entirely. - - - - - 43e814e1 by Ben Gamari at 2023-10-12T06:49:40-04:00 base: Introduce move modules into src The only non-move changes here are whitespace changes to pass the `whitespace` test and a few testsuite adaptations. - - - - - df81536f by Moritz Angermann at 2023-10-12T06:50:16-04:00 [PEi386 linker] Bounds check and null-deref guard We should resonably be able to expect that we won't exceed the number of sections if we assume to be dealing with legal object files. We can however not guarantee that we get some negative values, and while we try to special case most, we should exclude negative indexing into the sections array. We also need to ensure that we do not try to derefences targetSection, if it is NULL, due to the switch statement. - - - - - c74c4f00 by John Ericson at 2023-10-12T10:31:13-04:00 Move apple compat check to RTS configure - - - - - c80778ea by John Ericson at 2023-10-12T10:31:13-04:00 Move clock/timer fun checks to RTS configure Actual library check (which will set the Cabal flag) is left in the top-level configure for now. Progress towards #17191 - - - - - 7f9f2686 by John Ericson at 2023-10-12T10:31:13-04:00 Move visibility and "musttail" annotation checks to the RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. Progress towards #17191 - - - - - ffb3efe6 by John Ericson at 2023-10-12T10:31:13-04:00 Move leading underscore checks to RTS configure `CabalLeadingUnderscore` is done via Hadrian already, so we can stop `AC_SUBST`ing it completely. - - - - - 25fa4b02 by John Ericson at 2023-10-12T10:31:13-04:00 Move alloca, fork, const, and big endian checks to RTS configure All of this should boil down to `AC_DEFINE` not `AC_SUBST`, so it belongs in the RTS configure and should be safe to move without modification. - - - - - 5170f42a by John Ericson at 2023-10-12T10:31:13-04:00 Move libdl check to RTS configure - - - - - ea7a1447 by John Ericson at 2023-10-12T10:31:13-04:00 Adjust `FP_FIND_LIBFFI` Just set vars, and `AC_SUBST` in top-level configure. Don't define `HAVE_SYSTEM_LIBFFI` because nothing is using it. It hasn't be in used since 3609340743c1b25fdfd0e18b1670dac54c8d8623 (part of the make build system). - - - - - f399812c by John Ericson at 2023-10-12T10:31:13-04:00 Split BFD support to RTS configure The flag is still in the top-level configure, but the other checks (which define various macros --- important) are in the RTS configure. - - - - - f64f44e9 by John Ericson at 2023-10-12T10:31:13-04:00 Split libm check between top level and RTS - - - - - dafc4709 by Moritz Angermann at 2023-10-12T10:31:49-04:00 CgUtils.fixStgRegStmt respect register width This change ensure that the reg + offset computation is always of the same size. Before this we could end up with a 64bit register, and then add a 32bit offset (on 32bit platforms). This not only would fail type sanity checking, but also incorrectly truncate 64bit values into 32bit values silently on 32bit architectures. - - - - - 9e6ef7ba by Matthew Pickering at 2023-10-12T20:35:00-04:00 hadrian: Decrease verbosity of cabal commands In Normal, most tools do not produce output to stdout unless there are error conditions. Reverts 7ed65f5a1bc8e040e318ccff395f53a9bbfd8217 - - - - - 08fc27af by John Ericson at 2023-10-12T20:35:36-04:00 Do not substitute `@...@` for stage-specific values in cabal files `rts` and `ghc-prim` now no longer have a `*.cabal.in` to set Cabal flag defaults; instead manual choices are passed to configure in the usual way. The old way was fundamentally broken, because it meant we were baking these Cabal files for a specific stage. Now we only do stage-agnostic @...@ substitution in cabal files (the GHC version), and so all stage-specific configuration is properly confined to `_build` and the right stage dir. Also `include-ghc-prim` is a flag that no longer exists for `ghc-prim` (it was removed in 835d8ddbbfb11796ea8a03d1806b7cee38ba17a6) so I got rid of it. Co-Authored-By: Matthew Pickering <matthewtpickering at gmail.com> - - - - - a0ac8785 by Sebastian Graf at 2023-10-14T19:17:12-04:00 Fix restarts in .ghcid Using the whole of `hadrian/` restarted in a loop for me. - - - - - fea9ecdb by Sebastian Graf at 2023-10-14T19:17:12-04:00 CorePrep: Refactor FloatingBind (#23442) A drastically improved architecture for local floating in CorePrep that decouples the decision of whether a float is going to be let- or case-bound from how far it can float (out of strict contexts, out of lazy contexts, to top-level). There are a couple of new Notes describing the effort: * `Note [Floating in CorePrep]` for the overview * `Note [BindInfo and FloatInfo]` for the new classification of floats * `Note [Floats and FloatDecision]` for how FloatInfo is used to inform floating decisions This is necessary ground work for proper treatment of Strict fields and unlifted values at top-level. Fixes #23442. NoFib results (omitted = 0.0%): ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- pretty 0.0% -1.6% scc 0.0% -1.7% -------------------------------------------------------------------------------- Min 0.0% -1.7% Max 0.0% -0.0% Geometric Mean -0.0% -0.0% ``` - - - - - 32523713 by Matthew Pickering at 2023-10-14T19:17:49-04:00 hadrian: Move ghcBinDeps into ghcLibDeps This completes a5227080b57cb51ac34d4c9de1accdf6360b818b, the `ghc-usage.txt` and `ghci-usage.txt` file are also used by the `ghc` library so need to make sure they are present in the libdir even if we are not going to build `ghc-bin`. This also fixes things for cross compilers because the stage2 cross-compiler requires the ghc-usage.txt file, but we are using the stage2 lib folder but not building stage3:exe:ghc-bin so ghc-usage.txt was not being generated. - - - - - ec3c4488 by sheaf at 2023-10-14T19:18:29-04:00 Combine GREs when combining in mkImportOccEnv In `GHC.Rename.Names.mkImportOccEnv`, we sometimes discard one import item in favour of another, as explained in Note [Dealing with imports] in `GHC.Rename.Names`. However, this can cause us to lose track of important parent information. Consider for example #24084: module M1 where { class C a where { type T a } } module M2 ( module M1 ) where { import M1 } module M3 where { import M2 ( C, T ); instance C () where T () = () } When processing the import list of `M3`, we start off (for reasons that are not relevant right now) with two `Avail`s attached to `T`, namely `C(C, T)` and `T(T)`. We combine them in the `combine` function of `mkImportOccEnv`; as described in Note [Dealing with imports] we discard `C(C, T)` in favour of `T(T)`. However, in doing so, we **must not** discard the information want that `C` is the parent of `T`. Indeed, losing track of this information can cause errors when importing, as we could get an error of the form ‘T’ is not a (visible) associated type of class ‘C’ We fix this by combining the two GREs for `T` using `plusGRE`. Fixes #24084 - - - - - 257c2807 by Ilias Tsitsimpis at 2023-10-14T19:19:07-04:00 hadrian: Pass -DNOSMP to C compiler when needed Hadrian passes the -DNOSMP flag to GHC when the target doesn't support SMP, but doesn't pass it to CC as well, leading to the following compilation error on mips64el: | Run Cc (FindCDependencies CDep) Stage1: rts/sm/NonMovingScav.c => _build/stage1/rts/build/c/sm/NonMovingScav.o.d Command line: /usr/bin/mips64el-linux-gnuabi64-gcc -E -MM -MG -MF _build/stage1/rts/build/c/hooks/FlagDefaults.thr_debug_p_o.d -MT _build/stage1/rts/build/c/hooks/FlagDefaults.o -Irts/include -I_build/stage1/rts/build -I_build/stage1/rts/build/include -Irts/include -x c rts/hooks/FlagDefaults.c -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Winline -Wpointer-arith -Wmissing-noreturn -Wnested-externs -Wredundant-decls -Wundef -fno-strict-aliasing -DTHREADED_RTS -DDEBUG -fomit-frame-pointer -O2 -g -Irts -I_build/stage1/rts/build -DDEBUG -fno-omit-frame-pointer -g3 -O0 ===> Command failed with error code: 1 In file included from rts/include/Stg.h:348, from rts/include/Rts.h:38, from rts/hooks/FlagDefaults.c:8: rts/include/stg/SMP.h:416:2: error: #error memory barriers unimplemented on this architecture 416 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:440:2: error: #error memory barriers unimplemented on this architecture 440 | #error memory barriers unimplemented on this architecture | ^~~~~ rts/include/stg/SMP.h:464:2: error: #error memory barriers unimplemented on this architecture 464 | #error memory barriers unimplemented on this architecture | ^~~~~ The old make system correctly passed this flag to both GHC and CC [1]. Fix this error by passing -DNOSMP to CC as well. [1] https://gitlab.haskell.org/ghc/ghc/-/blob/00920f176b0235d5bb52a8e054d89a664f8938fe/rts/ghc.mk#L407 Closes #24082 - - - - - 13d3c613 by John Ericson at 2023-10-14T19:19:42-04:00 Users Guide: Drop dead code for Haddock refs to `parallel` I noticed while working on !11451 that `@LIBRARY_parallel_UNIT_ID@` was not substituted. It is dead code -- there is no `parallel-ref` usages and it doesn't look like there ever was (going back to 3e5d0f188d6c8633e55e9ba6c8941c07e459fa4b), so let's delete it. - - - - - fe067577 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066) bigNatIndex# in the `where` clause wasn't guarded by "bigNatIsZero a". - - - - - cc1625b1 by Sylvain Henry at 2023-10-18T19:40:25-04:00 Bignum: fix right shift of negative BigNat with native backend - - - - - cbe4400d by Sylvain Henry at 2023-10-18T19:40:25-04:00 Rts: expose rtsOutOfBoundsAccess symbol - - - - - 72c7380c by Sylvain Henry at 2023-10-18T19:40:25-04:00 Hadrian: enable `-fcheck-prim-bounds` in validate flavour This allows T24066 to fail when the bug is present. Otherwise the out-of-bound access isn't detected as it happens in ghc-bignum which wasn't compiled with the bounds check. - - - - - f9436990 by John Ericson at 2023-10-18T19:41:01-04:00 Make Hadrian solely responsible for substituting `docs/users_guide/ghc_config.py.in` Fixes #24091 Progress on #23966 Issue #24091 reports that `@ProjectVersion@` is no longer being substituted in the GHC user's guide. I assume this is a recent issue, but I am not sure how it's worked since c1a3ecde720b3bddc2c8616daaa06ee324e602ab; it looks like both Hadrian and configure are trying to substitute the same `.in` file! Now only Hadrian does. That is better anyways; already something that issue #23966 requested. It seems like we were missing some dependencies in Hadrian. (I really, really hate that this is possible!) Hopefully it is fixed now. - - - - - b12df0bb by John Ericson at 2023-10-18T19:41:37-04:00 `ghcversion.h`: No need to cope with undefined `ProjectPatchLevel*` Since 4e6c80197f1cc46dfdef0300de46847c7cfbdcb0, these are guaranteed to be defined. (Guaranteed including a test in the testsuite.) - - - - - 0295375a by John Ericson at 2023-10-18T19:41:37-04:00 Generate `ghcversion.h` from a `.in` file Now that there are no conditional sections (see the previous commit), we can just a do simple substitution rather than pasting it together line by line. Progress on #23966 - - - - - 740a1b85 by Krzysztof Gogolewski at 2023-10-19T11:37:20-04:00 Add a regression test for #24064 - - - - - 921fbf2f by Hécate Moonlight at 2023-10-19T11:37:59-04:00 CLC Proposal #182: Export List from Data.List Proposal link: https://github.com/haskell/core-libraries-committee/issues/182 - - - - - 4f02d3c1 by Sylvain Henry at 2023-10-20T04:01:32-04:00 rts: fix small argument passing on big-endian arch (fix #23387) - - - - - b86243b4 by Sylvain Henry at 2023-10-20T04:02:13-04:00 Interpreter: fix literal alignment on big-endian architectures (fix #19261) Literals weren't correctly aligned on big-endian, despite what the comment said. - - - - - a4b2ec47 by Sylvain Henry at 2023-10-20T04:02:54-04:00 Testsuite: recomp011 and recomp015 are fixed on powerpc These tests have been fixed but not tested and re-enabled on big-endian powerpc (see comments in #11260 and #11323) - - - - - fded7dd4 by Sebastian Graf at 2023-10-20T04:03:30-04:00 CorePrep: Allow floating dictionary applications in -O0 into a Rec (#24102) - - - - - 02efc181 by John Ericson at 2023-10-22T02:48:55-04:00 Move function checks to RTS configure Some of these functions are used in `base` too, but we can copy the checks over to its configure if that's an issue. - - - - - 5f4bccab by John Ericson at 2023-10-22T02:48:55-04:00 Move over a number of C-style checks to RTS configure - - - - - 5cf04f58 by John Ericson at 2023-10-22T02:48:55-04:00 Move/Copy more `AC_DEFINE` to RTS config Only exception is the LLVM version macros, which are used for GHC itself. - - - - - b8ce5dfe by John Ericson at 2023-10-22T02:48:55-04:00 Define `TABLES_NEXT_TO_CODE` in the RTS configure We create a new cabal flag to facilitate this. - - - - - 4a40271e by John Ericson at 2023-10-22T02:48:55-04:00 Configure scripts: `checkOS`: Make a bit more robust `mingw64` and `mingw32` are now both accepted for `OSMinGW32`. This allows us to cope with configs/triples that we haven't normalized extra being what GNU `config.sub` does. - - - - - 16bec0a0 by John Ericson at 2023-10-22T02:48:55-04:00 Generate `ghcplatform.h` from RTS configure We create a new cabal flag to facilitate this. - - - - - 7dfcab2f by John Ericson at 2023-10-22T02:48:55-04:00 Get rid of all mention of `mk/config.h` The RTS configure script is now solely responsible for managing its headers; the top level configure script does not help. - - - - - c1e3719c by Cheng Shao at 2023-10-22T02:49:33-04:00 rts: drop stale mentions of MIN_UPD_SIZE We used to have MIN_UPD_SIZE macro that describes the minimum reserved size for thunks, so that the thunk can be overwritten in place as indirections or blackholes. However, this macro has not been actually defined or used anywhere since a long time ago; StgThunkHeader already reserves a padding word for this purpose. Hence this patch which drops stale mentions of MIN_UPD_SIZE. - - - - - d24b0d85 by Andrew Lelechenko at 2023-10-22T02:50:11-04:00 base changelog: move non-backported entries from 4.19 section to 4.20 Neither !10933 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Text.Read.Lex.html#numberToRangedRational) nor !10189 (check https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.List.NonEmpty.html#unzip) were backported to `base-4.19.0.0`. Moving them to `base-4.20.0.0` section. Also minor stylistic changes to other entries, bringing them to a uniform form. - - - - - de78b32a by Alan Zimmerman at 2023-10-23T09:09:41-04:00 EPA Some tweaks to annotations - Fix span for GRHS - Move TrailingAnns from last match to FunBind - Fix GADT 'where' clause span - Capture full range for a CaseAlt Match - - - - - d5a8780d by Simon Hengel at 2023-10-23T09:10:23-04:00 Update primitives.rst - - - - - 4d075924 by Josh Meredith at 2023-10-24T23:04:12+11:00 JS/userguide: add explanation of writing jsbits - - - - - 07ab5cc1 by Cheng Shao at 2023-10-24T15:40:32-04:00 testsuite: increase timeout of ghc-api tests for wasm32 ghc-api tests for wasm32 are more likely to timeout due to the large wasm module sizes, especially when testing with wasm native tail calls, given wasmtime's handling of tail call opcodes are suboptimal at the moment. It makes sense to increase timeout specifically for these tests on wasm32. This doesn't affect other targets, and for wasm32 we don't increase timeout for all tests, so not to risk letting major performance regressions slip through the testsuite. - - - - - 0d6acca5 by Greg Steuck at 2023-10-26T08:44:23-04:00 Explicitly require RLIMIT_AS before use in OSMem.c This is done elsewhere in the source tree. It also suddenly is required on OpenBSD. - - - - - 9408b086 by Sylvain Henry at 2023-10-26T08:45:03-04:00 Modularity: modularize external linker Decouple runLink from DynFlags to allow calling runLink more easily. This is preliminary work for calling Emscripten's linker (emcc) from our JavaScript linker. - - - - - e0f35030 by doyougnu at 2023-10-27T08:41:12-04:00 js: add JStg IR, remove unsaturated constructor - Major step towards #22736 and adding the optimizer in #22261 - - - - - 35587eba by Simon Peyton Jones at 2023-10-27T08:41:48-04:00 Fix a bug in tail calls with ticks See #24078 for the diagnosis. The change affects only the Tick case of occurrence analysis. It's a bit hard to test, so no regression test (yet anyway). - - - - - 9bc5cb92 by Matthew Craven at 2023-10-28T07:06:17-04:00 Teach tag-inference about SeqOp/seq# Fixes the STG/tag-inference analogue of #15226. Co-Authored-By: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 34f06334 by Moritz Angermann at 2023-10-28T07:06:53-04:00 [PEi386] Mask SYM_TYPE_DUP_DISCARD in makeSymbolExtra 48e391952c17ff7eab10b0b1456e3f2a2af28a9b introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. - - - - - 5b51b2a2 by Mario Blažević at 2023-10-28T07:07:33-04:00 Fix and test for issue #24111, TH.Ppr output of pattern synonyms - - - - - 723bc352 by Alan Zimmerman at 2023-10-30T20:36:41-04:00 EPA: print doc comments as normal comments And ignore the ones allocated in haddock processing. It does not guarantee that every original haddock-like comment appears in the output, as it discards ones that have no legal attachment point. closes #23459 - - - - - 21b76843 by Simon Peyton Jones at 2023-10-30T20:37:17-04:00 Fix non-termination bug in equality solver constraint left-to-right then right to left, forever. Easily fixed. - - - - - 270867ac by Sebastian Graf at 2023-10-30T20:37:52-04:00 ghc-toolchain: build with `-package-env=-` (#24131) Otherwise globally installed libraries (via `cabal install --lib`) break the build. Fixes #24131. - - - - - 7a90020f by Krzysztof Gogolewski at 2023-10-31T20:03:37-04:00 docs: fix ScopedTypeVariables example (#24101) The previous example didn't compile. Furthermore, it wasn't demonstrating the point properly. I have changed it to an example which shows that 'a' in the signature must be the same 'a' as in the instance head. - - - - - 49f69f50 by Krzysztof Gogolewski at 2023-10-31T20:04:13-04:00 Fix pretty-printing of type family dependencies "where" should be after the injectivity annotation. - - - - - 73c191c0 by Ben Gamari at 2023-10-31T20:04:49-04:00 gitlab-ci: Bump LLVM bootstrap jobs to Debian 12 As the Debian 10 images have too old an LLVM. Addresses #24056. - - - - - 5b0392e0 by Matthew Pickering at 2023-10-31T20:04:49-04:00 ci: Run aarch64 llvm backend job with "LLVM backend" label This brings it into line with the x86 LLVM backend job. - - - - - 9f9c9227 by Ryan Scott at 2023-11-01T09:19:12-04:00 More robust checking for DataKinds As observed in #22141, GHC was not doing its due diligence in catching code that should require `DataKinds` in order to use. Most notably, it was allowing the use of arbitrary data types in kind contexts without `DataKinds`, e.g., ```hs data Vector :: Nat -> Type -> Type where ``` This patch revamps how GHC tracks `DataKinds`. The full specification is written out in the `DataKinds` section of the GHC User's Guide, and the implementation thereof is described in `Note [Checking for DataKinds]` in `GHC.Tc.Validity`. In brief: * We catch _type_-level `DataKinds` violations in the renamer. See `checkDataKinds` in `GHC.Rename.HsType` and `check_data_kinds` in `GHC.Rename.Pat`. * We catch _kind_-level `DataKinds` violations in the typechecker, as this allows us to catch things that appear beneath type synonyms. (We do *not* want to do this in type-level contexts, as it is perfectly fine for a type synonym to mention something that requires DataKinds while still using the type synonym in a module that doesn't enable DataKinds.) See `checkValidType` in `GHC.Tc.Validity`. * There is now a single `TcRnDataKindsError` that classifies all manner of `DataKinds` violations, both in the renamer and the typechecker. The `NoDataKindsDC` error has been removed, as it has been subsumed by `TcRnDataKindsError`. * I have added `CONSTRAINT` is `isKindTyCon`, which is what checks for illicit uses of data types at the kind level without `DataKinds`. Previously, `isKindTyCon` checked for `Constraint` but not `CONSTRAINT`. This is inconsistent, given that both `Type` and `TYPE` were checked by `isKindTyCon`. Moreover, it thwarted the implementation of the `DataKinds` check in `checkValidType`, since we would expand `Constraint` (which was OK without `DataKinds`) to `CONSTRAINT` (which was _not_ OK without `DataKinds`) and reject it. Now both are allowed. * I have added a flurry of additional test cases that test various corners of `DataKinds` checking. Fixes #22141. - - - - - 575d7690 by Sylvain Henry at 2023-11-01T09:19:53-04:00 JS: fix FFI "wrapper" and "dynamic" Fix codegen and helper functions for "wrapper" and "dynamic" foreign imports. Fix tests: - ffi006 - ffi011 - T2469 - T4038 Related to #22363 - - - - - 81fb8885 by Alan Zimmerman at 2023-11-01T22:23:56-04:00 EPA: Use full range for Anchor This change requires a series of related changes, which must all land at the same time, otherwise all the EPA tests break. * Use the current Anchor end as prior end Use the original anchor location end as the source of truth for calculating print deltas. This allows original spacing to apply in most cases, only changed AST items need initial delta positions. * Add DArrow to TrailingAnn * EPA Introduce HasTrailing in ExactPrint Use [TrailingAnn] in enterAnn and remove it from ExactPrint (LocatedN RdrName) * In HsDo, put TrailingAnns at top of LastStmt * EPA: do not convert comments to deltas when balancing. * EPA: deal with fallout from getMonoBind * EPA fix captureLineSpacing * EPA print any comments in the span before exiting it * EPA: Add comments to AnchorOperation * EPA: remove AnnEofComment, it is no longer used Updates Haddock submodule - - - - - 03e82511 by Rodrigo Mesquita at 2023-11-01T22:24:32-04:00 Fix in docs regarding SSymbol, SNat, SChar (#24119) - - - - - 362cc693 by Matthew Pickering at 2023-11-01T22:25:08-04:00 hadrian: Update bootstrap plans (9.4.6, 9.4.7, 9.6.2, 9.6.3, 9.8.1) Updating the bootstrap plans with more recent GHC versions. - - - - - 00b9b8d3 by Matthew Pickering at 2023-11-01T22:25:08-04:00 ci: Add 9.8.1 bootstrap testing job - - - - - ef3d20f8 by Matthew Pickering at 2023-11-01T22:25:08-04:00 Compatibility with 9.8.1 as boot compiler This fixes several compatability issues when using 9.8.1 as the boot compiler. * An incorrect version guard on the stack decoding logic in ghc-heap * Some ghc-prim bounds need relaxing * ghc is no longer wired in, so we have to remove the -this-unit-id ghc call. Fixes #24077 - - - - - 6755d833 by Jaro Reinders at 2023-11-03T10:54:42+01:00 Add NCG support for common 64bit operations to the x86 backend. These used to be implemented via C calls which was obviously quite bad for performance for operations like simple addition. Co-authored-by: Andreas Klebinger - - - - - 0dfb1fa7 by Vladislav Zavialov at 2023-11-03T14:08:41-04:00 T2T in Expressions (#23738) This patch implements the T2T (term-to-type) transformation in expressions. Given a function with a required type argument vfun :: forall a -> ... the user can now call it as vfun (Maybe Int) instead of vfun (type (Maybe Int)) The Maybe Int argument is parsed and renamed as a term (HsExpr), but then undergoes a conversion to a type (HsType). See the new function expr_to_type in compiler/GHC/Tc/Gen/App.hs and Note [RequiredTypeArguments and the T2T mapping] Left as future work: checking for puns. - - - - - cc1c7c54 by Duncan Coutts at 2023-11-05T00:23:44-04:00 Add a test for I/O managers It tries to cover the cases of multiple threads waiting on the same fd for reading and multiple threads waiting for writing, including wait cancellation by async exceptions. It should work for any I/O manager, in-RTS or in-Haskell. Unfortunately it will not currently work for Windows because it relies on anonymous unix sockets. It could in principle be ported to use Windows named pipes. - - - - - 2e448f98 by Cheng Shao at 2023-11-05T00:23:44-04:00 Skip the IOManager test on wasm32 arch. The test relies on the sockets API which are not (yet) available. - - - - - fe50eb35 by Cheng Shao at 2023-11-05T00:24:20-04:00 compiler: fix eager blackhole symbol in wasm32 NCG - - - - - af771148 by Cheng Shao at 2023-11-05T00:24:20-04:00 testsuite: fix optasm tests for wasm32 - - - - - 1b90735c by Matthew Pickering at 2023-11-05T00:24:20-04:00 testsuite: Add wasm32 to testsuite arches with NCG The compiler --info reports that wasm32 compilers have a NCG, so we should agree with that here. - - - - - db9a6496 by Alan Zimmerman at 2023-11-05T00:24:55-04:00 EPA: make locA a function, not a field name And use it to generalise reLoc The following for the windows pipeline one. 5.5% Metric Increase: T5205 - - - - - 833e250c by Simon Peyton Jones at 2023-11-05T00:25:31-04:00 Update the unification count in wrapUnifierX Omitting this caused type inference to fail in #24146. This was an accidental omision in my refactoring of the equality solver. - - - - - e451139f by Andreas Klebinger at 2023-11-05T00:26:07-04:00 Remove an accidental git conflict marker from a comment. - - - - - 30baac7a by Tobias Haslop at 2023-11-06T10:50:32+00:00 Add laws relating between Foldable/Traversable with their Bi- superclasses See https://github.com/haskell/core-libraries-committee/issues/205 for discussion. This commit also documents that the tuple instances only satisfy the laws up to lazyness, similar to the documentation added in !9512. - - - - - df626f00 by Tobias Haslop at 2023-11-07T02:20:37-05:00 Elaborate on the quantified superclass of Bifunctor This was requested in the comment https://github.com/haskell/core-libraries-committee/issues/93#issuecomment-1597271700 for when Traversable becomes a superclass of Bitraversable, but similarly applies to Functor/Bifunctor, which already are in a superclass relationship. - - - - - 8217acb8 by Alan Zimmerman at 2023-11-07T02:21:12-05:00 EPA: get rid of l2l and friends Replace them with l2l to convert the location la2la to convert a GenLocated thing Updates haddock submodule - - - - - dd88a260 by Luite Stegeman at 2023-11-07T02:21:53-05:00 JS: remove broken newIdents from JStg Monad GHC.JS.JStg.Monad.newIdents was broken, resulting in duplicate identifiers being generated in h$c1, h$c2, ... . This change removes the broken newIdents. - - - - - 455524a2 by Matthew Craven at 2023-11-09T08:41:59-05:00 Create specially-solved DataToTag class Closes #20532. This implements CLC proposal 104: https://github.com/haskell/core-libraries-committee/issues/104 The design is explained in Note [DataToTag overview] in GHC.Tc.Instance.Class. This replaces the existing `dataToTag#` primop. These metric changes are not "real"; they represent Unique-related flukes triggering on a different set of jobs than they did previously. See also #19414. Metric Decrease: T13386 T8095 Metric Increase: T13386 T8095 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - a05f4554 by Alan Zimmerman at 2023-11-09T08:42:35-05:00 EPA: get rid of glRR and friends in GHC/Parser.y With the HasLoc and HasAnnotation classes, we can replace a number of type-specific helper functions in the parser with polymorphic ones instead Metric Decrease: MultiLayerModulesTH_Make - - - - - 18498538 by Cheng Shao at 2023-11-09T16:58:12+00:00 ci: bump ci-images for wasi-sdk upgrade - - - - - 52c0fc69 by PHO at 2023-11-09T19:16:22-05:00 Don't assume the current locale is *.UTF-8, set the encoding explicitly primops.txt contains Unicode characters: > LC_ALL=C ./genprimopcode --data-decl < ./primops.txt > genprimopcode: <stdin>: hGetContents: invalid argument (cannot decode byte sequence starting from 226) Hadrian must also avoid using readFile' to read primops.txt because it tries to decode the file with a locale-specific encoding. - - - - - 7233b3b1 by PHO at 2023-11-09T19:17:01-05:00 Use '[' instead of '[[' because the latter is a Bash-ism It doesn't work on platforms where /bin/sh is something other than Bash. - - - - - 6dbab180 by Simon Peyton Jones at 2023-11-09T19:17:36-05:00 Add an extra check in kcCheckDeclHeader_sig Fix #24083 by checking for a implicitly-scoped type variable that is not actually bound. See Note [Disconnected type variables] in GHC.Tc.Gen.HsType For some reason, on aarch64-darwin we saw a 2.8% decrease in compiler allocations for MultiLayerModulesTH_Make; but 0.0% on other architectures. Metric Decrease: MultiLayerModulesTH_Make - - - - - 22551364 by Sven Tennie at 2023-11-11T06:35:22-05:00 AArch64: Delete unused LDATA pseudo-instruction Though there were consuming functions for LDATA, there were no producers. Thus, the removed code was "dead". - - - - - 2a0ec8eb by Alan Zimmerman at 2023-11-11T06:35:59-05:00 EPA: harmonise acsa and acsA in GHC/Parser.y With the HasLoc class, we can remove the acsa helper function, using acsA instead. - - - - - 7ae517a0 by Teo Camarasu at 2023-11-12T08:04:12-05:00 nofib: bump submodule This includes changes that: - fix building a benchmark with HEAD - remove a Makefile-ism that causes errors in bash scripts Resolves #24178 - - - - - 3f0036ec by Alan Zimmerman at 2023-11-12T08:04:47-05:00 EPA: Replace Anchor with EpaLocation An Anchor has a location and an operation, which is either that it is unchanged or that it has moved with a DeltaPos data Anchor = Anchor { anchor :: RealSrcSpan , anchor_op :: AnchorOperation } An EpaLocation also has either a location or a DeltaPos data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | EpaDelta !DeltaPos ![LEpaComment] Now that we do not care about always having a location in the anchor, we remove Anchor and replace it with EpaLocation We do this with a type alias initially, to ease the transition. The alias will be removed in time. We also have helpers to reconstruct the AnchorOperation from an EpaLocation. This is also temporary. Updates Haddock submodule - - - - - a7492048 by Alan Zimmerman at 2023-11-12T13:43:07+00:00 EPA: get rid of AnchorOperation Now that the Anchor type is an alias for EpaLocation, remove AnchorOperation. Updates haddock submodule - - - - - 0745c34d by Andrew Lelechenko at 2023-11-13T16:25:07-05:00 Add since annotation for showHFloat - - - - - e98051a5 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 Suppress duplicate librares linker warning of new macOS linker Fixes #24167 XCode 15 introduced a new linker which warns on duplicate libraries being linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as suggested by Brad King in CMake issue #25297. This flag isn't necessarily available to other linkers on darwin, so we must only configure it into the CC linker arguments if valid. - - - - - c411c431 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Encoding test witnesses recent iconv bug is fragile A regression in the new iconv() distributed with XCode 15 and MacOS Sonoma causes the test 'encoding004' to fail in the CP936 roundrip. We mark this test as fragile until this is fixed upstream (rather than broken, since previous versions of iconv pass the test) See #24161 - - - - - ce7fe5a9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Update to LC_ALL=C no longer being ignored in darwin MacOS seems to have fixed an issue where it used to ignore the variable `LC_ALL` in program invocations and default to using Unicode. Since the behaviour seems to be fixed to account for the locale variable, we mark tests that were previously broken in spite of it as fragile (since they now pass in recent macOS distributions) See #24161 - - - - - e6c803f7 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 darwin: Fix single_module is obsolete warning In XCode 15's linker, -single_module is the default and otherwise passing it as a flag results in a warning being raised: ld: warning: -single_module is obsolete This patch fixes this warning by, at configure time, determining whether the linker supports -single_module (which is likely false for all non-darwin linkers, and true for darwin linkers in previous versions of macOS), and using that information at runtime to decide to pass or not the flag in the invocation. Fixes #24168 - - - - - 929ba2f9 by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) - - - - - af261ccd by Rodrigo Mesquita at 2023-11-15T13:18:58-05:00 configure: check target (not build) understands -no_compact_unwind Previously, we were branching on whether the build system was darwin to shortcut this check, but we really want to branch on whether the target system (which is what we are configuring ld_prog for) is darwin. - - - - - 2125c176 by Luite Stegeman at 2023-11-15T13:19:38-05:00 JS: Fix missing variable declarations The JStg IR update was missing some local variable declarations that were present earlier, causing global variables to be used implicitly (or an error in JavaScript strict mode). This adds the local variable declarations again. - - - - - 99ced73b by Krzysztof Gogolewski at 2023-11-15T13:20:14-05:00 Remove loopy superclass solve mechanism Programs with a -Wloopy-superclass-solve warning will now fail with an error. Fixes #23017 - - - - - 2aff2361 by Zubin Duggal at 2023-11-15T13:20:50-05:00 users-guide: Fix links to libraries from the users-guide. The unit-ids generated in c1a3ecde720b3bddc2c8616daaa06ee324e602ab include the package name, so we don't need to explicitly add it to the links. Fixes #24151 - - - - - 27981fac by Alan Zimmerman at 2023-11-15T13:21:25-05:00 EPA: splitLHsForAllTyInvis does not return ann We did not use the annotations returned from splitLHsForAllTyInvis, so do not return them. - - - - - a6467834 by Krzysztof Gogolewski at 2023-11-15T22:22:59-05:00 Document defaulting of RuntimeReps Fixes #24099 - - - - - 2776920e by Simon Peyton Jones at 2023-11-15T22:23:35-05:00 Second fix to #24083 My earlier fix turns out to be too aggressive for data/type families See wrinkle (DTV1) in Note [Disconnected type variables] - - - - - cee81370 by Sylvain Henry at 2023-11-16T09:57:46-05:00 Fix unusable units and module reexport interaction (#21097) This commit fixes an issue with ModUnusable introduced in df0f148feae. In mkUnusableModuleNameProvidersMap we traverse the list of unusable units and generate ModUnusable origin for all the modules they contain: exposed modules, hidden modules, and also re-exported modules. To do this we have a two-level map: ModuleName -> Unit:ModuleName (aka Module) -> ModuleOrigin So for each module name "M" in broken unit "u" we have: "M" -> u:M -> ModUnusable reason However in the case of module reexports we were using the *target* module as a key. E.g. if "u:M" is a reexport for "X" from unit "o": "M" -> o:X -> ModUnusable reason Case 1: suppose a reexport without module renaming (u:M -> o:M) from unusable unit u: "M" -> o:M -> ModUnusable reason Here it's claiming that the import of M is unusable because a reexport from u is unusable. But if unit o isn't unusable we could also have in the map: "M" -> o:M -> ModOrigin ... Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModOrigin) Case 2: similarly we could have 2 unusable units reexporting the same module without renaming, say (u:M -> o:M) and (v:M -> o:M) with u and v unusable. It gives: "M" -> o:M -> ModUnusable ... (for u) "M" -> o:M -> ModUnusable ... (for v) Issue: the Semigroup instance of ModuleOrigin doesn't handle the case (ModUnusable <> ModUnusable). This led to #21097, #16996, #11050. To fix this, in this commit we make ModUnusable track whether the module used as key is a reexport or not (for better error messages) and we use the re-export module as key. E.g. if "u:M" is a reexport for "o:X" and u is unusable, we now record: "M" -> u:M -> ModUnusable reason reexported=True So now, we have two cases for a reexport u:M -> o:X: - u unusable: "M" -> u:M -> ModUnusable ... reexported=True - u usable: "M" -> o:X -> ModOrigin ... reexportedFrom=u:M The second case is indexed with o:X because in this case the Semigroup instance of ModOrigin is used to combine valid expositions of a module (directly or via reexports). Note that module lookup functions select usable modules first (those who have a ModOrigin value), so it doesn't matter if we add new ModUnusable entries in the map like this: "M" -> { u:M -> ModUnusable ... reexported=True o:M -> ModOrigin ... } The ModOrigin one will be used. Only if there is no ModOrigin or ModHidden entry will the ModUnusable error be printed. See T21097 for an example printing several reasons why an import is unusable. - - - - - 3e606230 by Krzysztof Gogolewski at 2023-11-16T09:58:22-05:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe - - - - - 49f5264b by Andreas Klebinger at 2023-11-16T20:52:11-05:00 Properly compute unpacked sizes for -funpack-small-strict-fields. Use rep size rather than rep count to compute the size. Fixes #22309 - - - - - b4f84e4b by James Henri Haydon at 2023-11-16T20:52:53-05:00 Explicit methods for Alternative Compose Explicitly define some and many in Alternative instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/181 - - - - - 9bc0dd1f by Ignat Insarov at 2023-11-16T20:53:34-05:00 Add permutations for non-empty lists. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 5643ecf9 by Andrew Lelechenko at 2023-11-16T20:53:34-05:00 Update changelog and since annotations for Data.List.NonEmpty.permutations Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/68#issuecomment-1221409837 - - - - - 94ff2134 by Oleg Alexander at 2023-11-16T20:54:15-05:00 Update doc string for traceShow Updated doc string for traceShow. - - - - - faff671a by Luite Stegeman at 2023-11-17T14:12:51+01:00 JS: clean up some foreign imports - - - - - 856e0a4e by Sven Tennie at 2023-11-18T06:54:11-05:00 AArch64: Remove unused instructions As these aren't ever emitted, we don't even know if they work or will ever be used. If one of them is needed in future, we may easily re-add it. Deleted instructions are: - CMN - ANDS - BIC - BICS - EON - ORN - ROR - TST - STP - LDP - DMBSY - - - - - 615441ef by Alan Zimmerman at 2023-11-18T06:54:46-05:00 EPA: Replace Monoid with NoAnn Remove the final Monoid instances in the exact print infrastructure. For Windows CI Metric Decrease: T5205 - - - - - 5a6c49d4 by David Feuer at 2023-11-20T18:53:18-05:00 Speed up stimes in instance Semigroup Endo As discussed at https://github.com/haskell/core-libraries-committee/issues/4 - - - - - cf9da4b3 by Andrew Lelechenko at 2023-11-20T18:53:18-05:00 base: reflect latest changes in the changelog - - - - - 48bf364e by Alan Zimmerman at 2023-11-20T18:53:54-05:00 EPA: Use SrcSpan in EpaSpan This is more natural, since we already need to deal with invalid RealSrcSpans, and that is exactly what SrcSpan.UnhelpfulSpan is for. Updates haddock submodule. - - - - - 97ec37cc by Sebastian Graf at 2023-11-20T18:54:31-05:00 Add regression test for #6070 Fixes #6070. - - - - - e9d5ae41 by Owen Shepherd at 2023-11-21T18:32:23-05:00 chore: Correct typo in the gitlab MR template [skip ci] - - - - - f158a8d0 by Rodrigo Mesquita at 2023-11-21T18:32:59-05:00 Improve error message when reading invalid `.target` files A `.target` file generated by ghc-toolchain or by configure can become invalid if the target representation (`Toolchain.Target`) is changed while the files are not re-generated by calling `./configure` or `ghc-toolchain` again. There is also the issue of hadrian caching the dependencies on `.target` files, which makes parsing fail when reading reading the cached value if the representation has been updated. This patch provides a better error message in both situations, moving away from a terrible `Prelude.read: no parse` error that you would get otherwise. Fixes #24199 - - - - - 955520c6 by Ben Gamari at 2023-11-21T18:33:34-05:00 users guide: Note that QuantifiedConstraints implies ExplicitForAll Fixes #24025. - - - - - 17ec3e97 by Owen Shepherd at 2023-11-22T09:37:28+01:00 fix: Change type signatures in NonEmpty export comments to reflect reality This fixes several typos in the comments of Data.List.NonEmpty export list items. - - - - - 2fd78f9f by Samuel Thibault at 2023-11-22T11:49:13-05:00 Fix the platform string for GNU/Hurd As commited in Cargo https://github.com/haskell/cabal/pull/9434 there is confusion between "gnu" and "hurd". This got fixed in Cargo, we need the converse in Hadrian. Fixes #24180 - - - - - a79960fe by Alan Zimmerman at 2023-11-22T11:49:48-05:00 EPA: Tuple Present no longer has annotation The Present constructor for a Tuple argument will never have an exact print annotation. So make this impossible. - - - - - 121c9ab7 by David Binder at 2023-11-22T21:12:29-05:00 Unify the hpc testsuites The hpc testsuite was split between testsuite/tests/hpc and the submodule libraries/hpc/test. This commit unifies the two testsuites in the GHC repository in the directory testsuite/tests/hpc. - - - - - d2733a05 by Alan Zimmerman at 2023-11-22T21:13:05-05:00 EPA: empty tup_tail has noAnn In Parser.y, the tup_tail rule had the following option | {- empty -} %shift { return [Left noAnn] } Once this works through PostProcess.hs, it means we add an extra Missing constructor if the last item was a comma. Change the annotation type to a Bool to indicate this, and use the EpAnn Anchor for the print location for the others. - - - - - fa576eb8 by Andreas Klebinger at 2023-11-24T08:29:13-05:00 Fix FMA primops generating broken assembly on x86. `genFMA3Code` assumed that we had to take extra precations to avoid overwriting the result of `getNonClobberedReg`. One of these special cases caused a bug resulting in broken assembly. I believe we don't need to hadle these cases specially at all, which means this MR simply deletes the special cases to fix the bug. Fixes #24160 - - - - - 34d86315 by Alan Zimmerman at 2023-11-24T08:29:49-05:00 EPA: Remove parenthesizeHsType This is called from PostProcess.hs, and adds spurious parens. With the looser version of exact printing we had before we could tolerate this, as they would be swallowed by the original at the same place. But with the next change (remove EpAnnNotUsed) they result in duplicates in the output. For Darwin build: Metric Increase: MultiLayerModulesTH_OneShot - - - - - 3ede659d by Vladislav Zavialov at 2023-11-26T06:43:32-05:00 Add name for -Wdeprecated-type-abstractions (#24154) This warning had no name or flag and was triggered unconditionally. Now it is part of -Wcompat. - - - - - 7902ebf8 by Alan Zimmerman at 2023-11-26T06:44:08-05:00 EPA: Remove EpAnnNotUsed We no longer need the EpAnnNotUsed constructor for EpAnn, as we can represent an unused annotation with an anchor having a EpaDelta of zero, and empty comments and annotations. This simplifies code handling annotations considerably. Updates haddock submodule Metric Increase: parsing001 - - - - - 471b2672 by Mario Blažević at 2023-11-26T06:44:48-05:00 Bumped the upper bound of text to <2.2 - - - - - d1bf25c7 by Vladislav Zavialov at 2023-11-26T11:45:49-05:00 Term variable capture (#23740) This patch changes type variable lookup rules (lookupTypeOccRn) and implicit quantification rules (filterInScope) so that variables bound in the term namespace can be captured at the type level {-# LANGUAGE RequiredTypeArguments #-} f1 x = g1 @x -- `x` used in a type application f2 x = g2 (undefined :: x) -- `x` used in a type annotation f3 x = g3 (type x) -- `x` used in an embedded type f4 x = ... where g4 :: x -> x -- `x` used in a type signature g4 = ... This change alone does not allow us to accept examples shown above, but at least it gets them past the renamer. - - - - - da863d15 by Vladislav Zavialov at 2023-11-26T11:46:26-05:00 Update Note [hsScopedTvs and visible foralls] The Note was written before GHC gained support for visible forall in types of terms. Rewrite a few sentences and use a better example. - - - - - b5213542 by Matthew Pickering at 2023-11-27T12:53:59-05:00 testsuite: Add mechanism to collect generic metrics * Generalise the metric logic by adding an additional field which allows you to specify how to query for the actual value. Previously the method of querying the baseline value was abstracted (but always set to the same thing). * This requires rejigging how the stat collection works slightly but now it's more uniform and hopefully simpler. * Introduce some new "generic" helper functions for writing generic stats tests. - collect_size ( deviation, path ) Record the size of the file as a metric - stat_from_file ( metric, deviation, path ) Read a value from the given path, and store that as a metric - collect_generic_stat ( metric, deviation, get_stat) Provide your own `get_stat` function, `lambda way: <Int>`, which can be used to establish the current value of the metric. - collect_generic_stats ( metric_info ): Like collect_generic_stat but provide the whole dictionary of metric definitions. { metric: { deviation: <Int> current: lambda way: <Int> } } * Introduce two new "size" metrics for keeping track of build products. - `size_hello_obj` - The size of `hello.o` from compiling hello.hs - `libdir` - The total size of the `libdir` folder. * Track the number of modules in the AST tests - CountDepsAst - CountDepsParser This lays the infrastructure for #24191 #22256 #17129 - - - - - 7d9a2e44 by ARATA Mizuki at 2023-11-27T12:54:39-05:00 x86: Don't require -mavx2 when using 256-bit floating-point SIMD primitives Fixes #24222 - - - - - 4e5ff6a4 by Alan Zimmerman at 2023-11-27T12:55:15-05:00 EPA: Remove SrcSpanAnn Now that we only have a single constructor for EpAnn, And it uses a SrcSpan for its location, we can do away with SrcSpanAnn completely. It only existed to wrap the original SrcSpan in a location, and provide a place for the exact print annotation. For darwin only: Metric Increase: MultiLayerModulesTH_OneShot Updates haddock submodule - - - - - e05bca39 by Krzysztof Gogolewski at 2023-11-28T08:00:55-05:00 testsuite: don't initialize testdir to '.' The test directory is removed during cleanup, if there's an interrupt that could remove the entire repository. Fixes #24219 - - - - - af881674 by Alan Zimmerman at 2023-11-28T08:01:30-05:00 EPA: Clean up mkScope in Ast.hs Now that we have HasLoc we can get rid of all the custom variants of mkScope For deb10-numa Metric Increase: libdir - - - - - 292983c8 by Ben Gamari at 2023-11-28T22:44:28-05:00 distrib: Rediscover otool and install_name_tool on Darwin In the bindist configure script we must rediscover the `otool` and `install_name_tool`s since they may be different from the build environment. Fixes #24211. - - - - - dfe1c354 by Stefan Schulze Frielinghaus at 2023-11-28T22:45:04-05:00 llvmGen: Align objects in the data section Objects in the data section may be referenced via tagged pointers. Thus, align those objects to a 4- or 8-byte boundary for 32- or 64-bit platforms, respectively. Note, this may need to be reconsidered if objects with a greater natural alignment requirement are emitted as e.g. 128-bit atomics. Fixes #24163. - - - - - f6c486c3 by Matthew Pickering at 2023-11-29T11:08:13-05:00 metrics: Widen libdir and size_hello_obj acceptance window af8816740d9b8759be1a22af8adcb5f13edeb61d shows that the libdir size can fluctuate quite significantly even when the change is quite small. Therefore we widen the acceptance window to 10%. - - - - - 99a6a49c by Alan Zimmerman at 2023-11-29T11:08:49-05:00 EPA: Clean up TC Monad Utils We no longer need the alternative variant of addLocM (addLocMA) nor wrapLocAM, wrapLocSndMA. aarch64-darwin Metric Increase: MultiLayerModulesTH_OneShot deb10-numa-slow Metric Decrease: libdir - - - - - cbc03fa0 by Sebastian Graf at 2023-11-30T12:37:21-05:00 perf tests: Move comments into new `Note [Sensitivity to unique increment]` (#19414) And additionally to T12545, link from T8095, T13386 to this new Note. - - - - - c7623b22 by Alan Zimmerman at 2023-11-30T12:37:56-05:00 EPA: EpaDelta for comment has no comments EpaLocation is used to position things. It has two constructors, EpaSpan holding a SrcSpan, and EpaDelta with a delta position and a possible list of comments. The comment list is needed because the location in EpaDelta has no absolute information to decide which comments should be emitted before them when printing. But it is also used for specifying the position of a comment. To prevent the absurdity of a comment position having a list of comments in it, we make EpaLocation parameterisable, using comments for the normal case and a constant for within comments. Updates haddock submodule. aarch64-darwin Metric Decrease: MultiLayerModulesTH_OneShot - - - - - bd8acc0c by Krzysztof Gogolewski at 2023-11-30T12:38:32-05:00 Kind-check body of a required forall We now require that in 'forall a -> ty', ty has kind TYPE r for some r. Fixes #24176 - - - - - 010fb784 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove incorrect haddock link quotes in code block - - - - - cda9c12d by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Remove cycle from group haddock example - - - - - 495265b9 by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use repl haddock syntax in group docs - - - - - d134d1de by Owen Shepherd at 2023-12-03T00:10:09-05:00 docs(NonEmpty/group): Use list [] notation in group haddock - - - - - dfcf629c by Owen Shepherd at 2023-12-03T00:10:10-05:00 docs(NonEmpty/group): Specify final property of group function in haddock - - - - - cad3b734 by Owen Shepherd at 2023-12-03T00:10:10-05:00 fix: Add missing property of List.group - - - - - bad37656 by Matthew Pickering at 2023-12-03T00:10:46-05:00 testsuite: Fix T21097b test with make 4.1 (deb9) cee81370cd6ef256f66035e3116878d4cb82e28b recently added a test which failed on deb9 because the version of make was emitting the recipe failure to stdout rather than stderr. One way to fix this is to be more precise in the test about which part of the output we care about inspecting. - - - - - 5efdf421 by Matthew Pickering at 2023-12-03T00:11:21-05:00 testsuite: Track size of libdir in bytes For consistency it's better if we track all size metrics in bytes. Metric Increase: libdir - - - - - f5eb0f29 by Matthew Pickering at 2023-12-03T00:11:22-05:00 testsuite: Remove rogue trace in testsuite I accidentally left a trace in the generics metric patch. - - - - - d5610737 by Claudio Bley at 2023-12-06T16:13:33-05:00 Only exit ghci in -e mode when :add command fails Previously, when running `ghci -e ':add Sample.hs'` the process would exit with exit code 1 if the file exists and could be loaded. Fixes #24115 - - - - - 0f0c53a5 by Vladislav Zavialov at 2023-12-06T16:14:09-05:00 T2T in Patterns (#23739) This patch implements the T2T (term-to-type) transformation in patterns. Patterns that are checked against a visible forall can now be written without the `type` keyword: \(type t) (x :: t) -> ... -- old \t (x :: t) -> ... -- new The `t` binder is parsed and renamed as a term pattern (Pat), but then undergoes a conversion to a type pattern (HsTyPat). See the new function pat_to_type_pat in compiler/GHC/Tc/Gen/Pat.hs - - - - - 10a1a6c6 by Sebastian Graf at 2023-12-06T16:14:45-05:00 Pmc: Fix SrcLoc and warning for incomplete irrefutable pats (#24234) Before, the source location would point at the surrounding function definition, causing the confusion in #24234. I also took the opportunity to introduce a new `LazyPatCtx :: HsMatchContext _` to make the warning message say "irrefutable pattern" instead of "pattern binding". - - - - - 36b9a38c by Matthew Pickering at 2023-12-06T16:15:21-05:00 libraries: Bump filepath to 1.4.200.1 and unix to 2.8.4.0 Updates filepath submodule Updates unix submodule Fixes #24240 - - - - - 91ff0971 by Matthew Pickering at 2023-12-06T16:15:21-05:00 Submodule linter: Allow references to tags We modify the submodule linter so that if the bumped commit is a specific tag then the commit is accepted. Fixes #24241 - - - - - 86f652dc by Zubin Duggal at 2023-12-06T16:15:21-05:00 hadrian: set -Wno-deprecations for directory and Win32 The filepath bump to 1.4.200.1 introduces a deprecation warning. See https://gitlab.haskell.org/ghc/ghc/-/issues/24240 https://github.com/haskell/filepath/pull/206 - - - - - 7ac6006e by Sylvain Henry at 2023-12-06T16:16:02-05:00 Zap OccInfo on case binders during StgCse #14895 #24233 StgCse can revive dead binders: case foo of dead { Foo x y -> Foo x y; ... } ===> case foo of dead { Foo x y -> dead; ... } -- dead is no longer dead So we must zap occurrence information on case binders. Fix #14895 and #24233 - - - - - 57c391c4 by Sebastian Graf at 2023-12-06T16:16:37-05:00 Cpr: Turn an assertion into a check to deal with some dead code (#23862) See the new `Note [Dead code may contain type confusions]`. Fixes #23862. - - - - - c1c8abf8 by Zubin Duggal at 2023-12-08T02:25:07-05:00 testsuite: add test for #23944 - - - - - 6329d308 by Zubin Duggal at 2023-12-08T02:25:07-05:00 driver: Only run a dynamic-too pipeline if object files are going to be generated Otherwise we run into a panic in hscMaybeWriteIface: "Unexpected DT_Dyn state when writing simple interface" when dynamic-too is enabled We could remove the panic and just write the interface even if the state is `DT_Dyn`, but it seems pointless to run the pipeline twice when `hscMaybeWriteIface` is already designed to write both `hi` and `dyn_hi` files if dynamic-too is enabled. Fixes #23944. - - - - - 28811f88 by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Improve duplicate elimination in SpecConstr This partially fixes #24229. See the new Note [Pattern duplicate elimination] in SpecConstr - - - - - fec7894f by Simon Peyton Jones at 2023-12-08T05:47:18-05:00 Make SpecConstr deal with casts better This patch does two things, to fix #23209: * It improves SpecConstr so that it no longer quantifies over coercion variables. See Note [SpecConstr and casts] * It improves the rule matcher to deal nicely with the case where the rule does not quantify over coercion variables, but the the template has a cast in it. See Note [Casts in the template] - - - - - 8db8d2fd by Zubin Duggal at 2023-12-08T05:47:54-05:00 driver: Don't lose track of nodes when we fail to resolve cycles The nodes that take part in a cycle should include both hs-boot and hs files, but when we fail to resolve a cycle, we were only counting the nodes from the graph without boot files. Fixes #24196 - - - - - c5b4efd3 by Zubin Duggal at 2023-12-08T05:48:30-05:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 - - - - - fae472a9 by Wendao Lee at 2023-12-08T05:49:12-05:00 docs(Data.Char):Add more detailed descriptions for some functions Related changed function's docs: -GHC.Unicode.isAlpha -GHC.Unicode.isPrint -GHC.Unicode.isAlphaNum Add more details for what the function will return. Co-authored-by: Bodigrim <andrew.lelechenko at gmail.com> - - - - - ca7510e4 by Malik Ammar Faisal at 2023-12-08T05:49:55-05:00 Fix float parsing in GHC Cmm Lexer Add test case for bug #24224 - - - - - d8baa1bd by Simon Peyton Jones at 2023-12-08T15:40:37+00:00 Take care when simplifying unfoldings This MR fixes a very subtle bug exposed by #24242. See Note [Environment for simplLetUnfolding]. I also updated a bunch of Notes on shadowing - - - - - 03ca551d by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in FloatIn Relevant to #3458 - - - - - 50c78779 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Comments only in SpecConstr - - - - - 9431e195 by Simon Peyton Jones at 2023-12-08T15:54:50-05:00 Add test for #22238 - - - - - d9e4c597 by Vladislav Zavialov at 2023-12-11T04:19:34-05:00 Make forall a keyword (#23719) Before this change, GHC used to accept `forall` as a term-level identifier: -- from constraints-0.13 forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p) forall d = ... Now it is a parse error. The -Wforall-identifier warning has served its purpose and is now a deprecated no-op. - - - - - 58d56644 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we actually clear the interactive context before reloading Previously we called discardIC, but immediately after set the session back to an old HscEnv that still contained the IC Partially addresses #24107 Fixes #23405 - - - - - 8e5745a0 by Zubin Duggal at 2023-12-11T04:20:10-05:00 driver: Ensure we force the lookup of old build artifacts before returning the build plan This prevents us from retaining all previous build artifacts in memory until a recompile finishes, instead only retaining the exact artifacts we need. Fixes #24118 - - - - - 105c370c by Zubin Duggal at 2023-12-11T04:20:10-05:00 testsuite: add test for #24118 and #24107 MultiLayerModulesDefsGhci was not able to catch the leak because it uses :l which discards the previous environment. Using :r catches both of these leaks - - - - - e822ff88 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Add some strictness annotations to ImportSpec and related constructors This prevents us from retaining entire HscEnvs. Force these ImportSpecs when forcing the GlobalRdrEltX Adds an NFData instance for Bag Fixes #24107 - - - - - 522c12a4 by Zubin Duggal at 2023-12-11T04:20:10-05:00 compiler: Force IfGlobalRdrEnv in NFData instance. - - - - - 188b280d by Arnaud Spiwack at 2023-12-11T15:33:31+01:00 LinearTypes => MonoLocalBinds - - - - - 8e0446df by Arnaud Spiwack at 2023-12-11T15:44:28+01:00 Linear let and where bindings For expediency, the initial implementation of linear types in GHC made it so that let and where binders would always be considered unrestricted. This was rather unpleasant, and probably a big obstacle to adoption. At any rate, this was not how the proposal was designed. This patch fixes this infelicity. It was surprisingly difficult to build, which explains, in part, why it took so long to materialise. As of this patch, let or where bindings marked with %1 will be linear (respectively %p for an arbitrary multiplicity p). Unmarked let will infer their multiplicity. Here is a prototypical example of program that used to be rejected and is accepted with this patch: ```haskell f :: A %1 -> B g :: B %1 -> C h :: A %1 -> C h x = g y where y = f x ``` Exceptions: - Recursive let are unrestricted, as there isn't a clear semantics of what a linear recursive binding would be. - Destructive lets with lazy bindings are unrestricted, as their desugaring isn't linear (see also #23461). - (Strict) destructive lets with inferred polymorphic type are unrestricted. Because the desugaring isn't linear (See #18461 down-thread). Closes #18461 and #18739 Co-authored-by: @jackohughes - - - - - effa7e2d by Matthew Craven at 2023-12-12T04:37:20-05:00 Introduce `dataToTagSmall#` primop (closes #21710) ...and use it to generate slightly better code when dataToTag# is used at a "small data type" where there is no need to mess with "is_too_big_tag" or potentially look at an info table. Metric Decrease: T18304 - - - - - 35c7aef6 by Matthew Craven at 2023-12-12T04:37:20-05:00 Fix formatting of Note [alg-alt heap check] - - - - - 7397c784 by Oleg Grenrus at 2023-12-12T04:37:56-05:00 Allow untyped brackets in typed splices and vice versa. Resolves #24190 Apparently the check was essentially always (as far as I can trace back: d0d47ba76f8f0501cf3c4966bc83966ab38cac27), and while it does catch some mismatches, the type-checker will catch them too. OTOH, it prevents writing completely reasonable programs. - - - - - a3ee3b99 by Moritz Angermann at 2023-12-12T19:50:58-05:00 Drop hard Xcode dependency XCODE_VERSION calls out to `xcodebuild`, which is only available when having `Xcode` installed. The CommandLineTools are not sufficient. To install Xcode, you must have an apple id to download the Xcode.xip from apple. We do not use xcodebuild anywhere in our build explicilty. At best it appears to be a proxy for checking the linker or the compiler. These should rather be done with ``` xcrun ld -version ``` or similar, and not by proxy through Xcode. The CLR should be sufficient for building software on macOS. - - - - - 1c9496e0 by Vladislav Zavialov at 2023-12-12T19:51:34-05:00 docs: update information on RequiredTypeArguments Update the User's Guide and Release Notes to account for the recent progress in the implementation of RequiredTypeArguments. - - - - - d0b17576 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Fix off-by-one in assertion Previously we failed to account for the NULL terminator `postString` asserted that there is enough room in the buffer for the string. - - - - - a10f9b9b by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Honor result of ensureRoomForVariableEvent is Previously we would keep plugging along, even if isn't enough room for the event. - - - - - 0e0f41c0 by Ben Gamari at 2023-12-13T06:33:37-05:00 rts/eventlog: Avoid truncating event sizes Previously ensureRoomForVariableEvent would truncate the desired size to 16-bits, resulting in #24197. Fixes #24197. - - - - - 64e724c8 by Artin Ghasivand at 2023-12-13T06:34:20-05:00 Remove the "Derived Constraint" argument of TcPluginSolver, docs - - - - - fe6d97dd by Vladislav Zavialov at 2023-12-13T06:34:56-05:00 EPA: Move tokens into GhcPs extension fields (#23447) Summary of changes * Remove Language.Haskell.Syntax.Concrete * Move all tokens into GhcPs extension fields (LHsToken -> EpToken) * Create new TTG extension fields as needed * Drop the MultAnn wrapper Updates the haddock submodule. Co-authored-by: Alan Zimmerman <alan.zimm at gmail.com> - - - - - 8106e695 by Zubin Duggal at 2023-12-13T06:35:34-05:00 testsuite: use copy_files in T23405 This prevents the tree from being dirtied when the file is modified. - - - - - ed0e4099 by Bryan Richter at 2023-12-14T04:30:53-05:00 Document ghc package's PVP-noncompliance This changes nothing, it just makes the status quo explicit. - - - - - 8bef8d9f by Luite Stegeman at 2023-12-14T04:31:33-05:00 JS: Mark spurious CI failures js_fragile(24259) This marks the spurious test failures on the JS platform as js_fragile(24259), so we don't hold up merge requests while fixing the underlying issues. See #24259 - - - - - 1c79526a by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Late plugins - - - - - 000c3302 by Finley McIlwaine at 2023-12-15T12:24:40-08:00 withTiming on LateCCs and late plugins - - - - - be4551ac by Finley McIlwaine at 2023-12-15T12:24:40-08:00 add test for late plugins - - - - - 7c29da9f by Finley McIlwaine at 2023-12-15T12:24:40-08:00 Document late plugins - - - - - 9a52ae46 by Ben Gamari at 2023-12-20T07:07:26-05:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - f4b53538 by Vladislav Zavialov at 2023-12-20T07:08:02-05:00 docs: Fix link to 051-ghc-base-libraries.rst The proposal is no longer available at the previous URL. - - - - - f7e21fab by Matthew Pickering at 2023-12-21T14:57:40+00:00 hadrian: Build all executables in bin/ folder In the end the bindist creation logic copies them all into the bin folder. There is no benefit to building a specific few binaries in the lib/bin folder anymore. This also removes the ad-hoc logic to copy the touchy and unlit executables from stage0 into stage1. It takes <1s to build so we might as well just build it. - - - - - 0038d052 by Zubin Duggal at 2023-12-22T23:28:00-05:00 testsuite: mark jspace as fragile on i386. This test has been flaky for some time and has been failing consistently on i386-linux since 8e0446df landed. See #24261 - - - - - dfd670a0 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 609e6225 by Ben Bellick at 2023-12-24T10:10:31-05:00 Deprecate -ddump-json and introduce -fdiagnostics-as-json Addresses #19278 This commit deprecates the underspecified -ddump-json flag and introduces a newer, well-specified flag -fdiagnostics-as-json. Also included is a JSON schema as part of the documentation. The -ddump-json flag will be slated for removal shortly after this merge. - - - - - 865513b2 by Ömer Sinan Ağacan at 2023-12-24T10:11:13-05:00 Fix BNF in user manual 6.6.8.2: formal syntax for instance declarations - - - - - c247b6be by Zubin Duggal at 2023-12-25T16:01:23-05:00 docs: document permissibility of -XOverloadedLabels (#24249) Document the permissibility introduced by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - e5b7eb59 by Ömer Sinan Ağacan at 2023-12-25T16:02:03-05:00 Fix a code block syntax in user manual sec. 6.8.8.6 - - - - - 2db11c08 by Ben Gamari at 2023-12-29T15:35:48-05:00 genSym: Reimplement via CAS on 32-bit platforms Previously the remaining use of the C implementation on 32-bit platforms resulted in a subtle bug, #24261. This was due to the C object (which used the RTS's `atomic_inc64` macro) being compiled without `-threaded` yet later being used in a threaded compiler. Side-step this issue by using the pure Haskell `genSym` implementation on all platforms. This required implementing `fetchAddWord64Addr#` in terms of CAS on 64-bit platforms. - - - - - 19328a8c by Xiaoyan Ren at 2023-12-29T15:36:30-05:00 Do not color the diagnostic code in error messages (#24172) - - - - - 685b467c by Krzysztof Gogolewski at 2023-12-29T15:37:06-05:00 Enforce that bindings of implicit parameters are lifted Fixes #24298 - - - - - bc4d67b7 by Matthew Craven at 2023-12-31T06:15:42-05:00 StgToCmm: Detect some no-op case-continuations ...and generate no code for them. Fixes #24264. - - - - - 5b603139 by Krzysztof Gogolewski at 2023-12-31T06:16:18-05:00 Revert "testsuite: mark jspace as fragile on i386." This reverts commit 0038d052c8c80b4b430bb2aa1c66d5280be1aa95. The atomicity bug should be fixed by !11802. - - - - - d55216ad by Krzysztof Gogolewski at 2024-01-01T12:05:49-05:00 Refactor: store [[PrimRep]] rather than [Type] in STG StgConApp stored a list of types. This list was used exclusively during unarisation of unboxed sums (mkUbxSum). However, this is at a wrong level of abstraction: STG shouldn't be concerned with Haskell types, only PrimReps. Update the code to store a [[PrimRep]]. Also, there's no point in storing this list when we're not dealing with an unboxed sum. - - - - - 8b340bc7 by Ömer Sinan Ağacan at 2024-01-01T12:06:29-05:00 Kind signatures docs: mention that they're allowed in newtypes - - - - - 989bf8e5 by Zubin Duggal at 2024-01-03T20:08:47-05:00 ci: Ensure we use the correct bindist name for the test artifact when generating release ghcup metadata Fixes #24268 - - - - - 89299a89 by Krzysztof Gogolewski at 2024-01-03T20:09:23-05:00 Refactor: remove calls to typePrimRepArgs The function typePrimRepArgs is just a thin wrapper around typePrimRep, adding a VoidRep if the list is empty. However, in StgToByteCode, we were discarding that VoidRep anyway, so there's no point in calling it. - - - - - c7be0c68 by mmzk1526 at 2024-01-03T20:10:07-05:00 Use "-V" for alex version check for better backward compatibility Fixes #24302. In recent versions of alex, "-v" is used for "--verbose" instead of "-version". - - - - - 67dbcc0a by Krzysztof Gogolewski at 2024-01-05T02:07:18-05:00 Fix VoidRep handling in ghci debugger 'go' inside extractSubTerms was giving a bad result given a VoidRep, attempting to round towards the next multiple of 0. I don't understand much about the debugger but the code should be better than it was. Fixes #24306 - - - - - 90ea574e by Krzysztof Gogolewski at 2024-01-05T02:07:54-05:00 VoidRep-related refactor * In GHC.StgToByteCode, replace bcIdPrimId with idPrimRep, bcIdArgRep with idArgRep, atomPrimRep with stgArgRep1. All of them were duplicates. * In GHC.Stg.Unarise, we were converting a PrimRep to a Type and back to PrimRep. Remove the calls to primRepToType and typePrimRep1 which cancel out. * In GHC.STG.Lint, GHC.StgToCmm, GHC.Types.RepType we were filtering out VoidRep from the result of typePrimRep. But typePrimRep never returns VoidRep - remove the filtering. - - - - - eaf72479 by brian at 2024-01-06T23:03:09-05:00 Add unaligned Addr# primops Implements CLC proposal #154: https://github.com/haskell/core-libraries-committee/issues/154 * add unaligned addr primops * add tests * accept tests * add documentation * fix js primops * uncomment in access ops * use Word64 in tests * apply suggestions * remove extra file * move docs * remove random options * use setByteArray# primop * better naming * update base-exports test * add base-exports for other architectures - - - - - d471d445 by Krzysztof Gogolewski at 2024-01-06T23:03:47-05:00 Remove VoidRep from PrimRep, introduce PrimOrVoidRep This introduces data PrimOrVoidRep = VoidRep | NVRep PrimRep changes typePrimRep1 to return PrimOrVoidRep, and adds a new function typePrimRepU to be used when the argument is definitely non-void. Details in Note [VoidRep] in GHC.Types.RepType. Fixes #19520 - - - - - 48720a07 by Matthew Craven at 2024-01-08T18:57:36-05:00 Apply Note [Sensitivity to unique increment] to LargeRecord - - - - - 9e2e180f by Sebastian Graf at 2024-01-08T18:58:13-05:00 Debugging: Add diffUFM for convenient diffing between UniqFMs - - - - - 948f3e35 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Rename Opt_D_dump_stranal to Opt_D_dump_dmdanal ... and Opt_D_dump_str_signatures to Opt_D_dump_dmd_signatures - - - - - 4e217e3e by Sebastian Graf at 2024-01-08T18:58:13-05:00 Deprecate -ddump-stranal and -ddump-str-signatures ... and suggest -ddump-dmdanal and -ddump-dmd-signatures instead - - - - - 6c613c90 by Sebastian Graf at 2024-01-08T18:58:13-05:00 Move testsuite/tests/stranal to testsuite/tests/dmdanal A separate commit so that the rename is obvious to Git(Lab) - - - - - c929f02b by Sebastian Graf at 2024-01-08T18:58:13-05:00 CoreSubst: Stricten `substBndr` and `cloneBndr` Doing so reduced allocations of `cloneBndr` by about 25%. ``` T9233(normal) ghc/alloc 672,488,656 663,083,216 -1.4% GOOD T9675(optasm) ghc/alloc 423,029,256 415,812,200 -1.7% geo. mean -0.1% minimum -1.7% maximum +0.1% ``` Metric Decrease: T9233 - - - - - e3ca78f3 by Krzysztof Gogolewski at 2024-01-10T17:35:59-05:00 Deprecate -Wsemigroup This warning was used to prepare for Semigroup becoming a superclass of Monoid, and for (<>) being exported from Prelude. This happened in GHC 8.4 in 8ae263ceb3566 and feac0a3bc69fd3. The leftover logic for (<>) has been removed in GHC 9.8, 4d29ecdfcc79. Now the warning does nothing at all and can be deprecated. - - - - - 08d14925 by amesgen at 2024-01-10T17:36:42-05:00 WASM metadata: use correct GHC version - - - - - 7a808419 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Allow SCC declarations in TH (#24081) - - - - - 28827c51 by Xiaoyan Ren at 2024-01-10T17:37:24-05:00 Fix prettyprinting of SCC pragmas - - - - - ae9cc1a8 by Matthew Craven at 2024-01-10T17:38:01-05:00 Fix loopification in the presence of void arguments This also removes Note [Void arguments in self-recursive tail calls], which was just misleading. It's important to count void args both in the function's arity and at the call site. Fixes #24295. - - - - - b718b145 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: Teach testsuite driver about c++ sources - - - - - 09cb57ad by Zubin Duggal at 2024-01-10T17:38:36-05:00 driver: Set -DPROFILING when compiling C++ sources with profiling Earlier, we used to pass all preprocessor flags to the c++ compiler. This meant that -DPROFILING was passed to the c++ compiler because it was a part of C++ flags However, this was incorrect and the behaviour was changed in 8ff3134ed4aa323b0199ad683f72165e51a59ab6. See #21291. But that commit exposed this bug where -DPROFILING was no longer being passed when compiling c++ sources. The fix is to explicitly include -DPROFILING in `opt_cxx` when profiling is enabled to ensure we pass the correct options for the way to both C and C++ compilers Fixes #24286 - - - - - 2cf9dd96 by Zubin Duggal at 2024-01-10T17:38:36-05:00 testsuite: rename objcpp -> objcxx To avoid confusion with C Pre Processsor - - - - - af6932d6 by Simon Peyton Jones at 2024-01-10T17:39:12-05:00 Make TYPE and CONSTRAINT not-apart Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty which is supposed to make TYPE and CONSTRAINT be not-apart. Easily fixed. - - - - - 4a39b5ff by Zubin Duggal at 2024-01-10T17:39:48-05:00 ci: Fix typo in mk_ghcup_metadata.py There was a missing colon in the fix to #24268 in 989bf8e53c08eb22de716901b914b3607bc8dd08 - - - - - 13503451 by Zubin Duggal at 2024-01-10T17:40:24-05:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. - - - - - afca46a4 by Sebastian Graf at 2024-01-10T17:41:00-05:00 Parser: Add a Note detailing why we need happy's `error` to implement layout - - - - - eaf8a06d by Krzysztof Gogolewski at 2024-01-11T00:43:17+01:00 Turn -Wtype-equality-out-of-scope on by default Also remove -Wnoncanonical-{monoid,monad}-instances from -Wcompat, since they are enabled by default. Refresh wcompat-warnings/ test with new -Wcompat warnings. Part of #24267 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 42bee5aa by Sebastian Graf at 2024-01-12T21:16:21-05:00 Arity: Require called *exactly once* for eta exp with -fpedantic-bottoms (#24296) In #24296, we had a program in which we eta expanded away an error despite the presence of `-fpedantic-bottoms`. This was caused by turning called *at least once* lambdas into one-shot lambdas, while with `-fpedantic-bottoms` it is only sound to eta expand over lambdas that are called *exactly* once. An example can be found in `Note [Combining arity type with demand info]`. Fixes #24296. - - - - - 7e95f738 by Andreas Klebinger at 2024-01-12T21:16:57-05:00 Aarch64: Enable -mfma by default. Fixes #24311 - - - - - e43788d0 by Jason Shipman at 2024-01-14T12:47:38-05:00 Add more instances for Compose: Fractional, RealFrac, Floating, RealFloat CLC proposal #226 https://github.com/haskell/core-libraries-committee/issues/226 - - - - - ae6d8cd2 by Sebastian Graf at 2024-01-14T12:48:15-05:00 Pmc: COMPLETE pragmas associated with Family TyCons should apply to representation TyCons as well (#24326) Fixes #24326. - - - - - c5fc7304 by sheaf at 2024-01-15T14:15:29-05:00 Use lookupOccRn_maybe in TH.lookupName When looking up a value, we want to be able to find both variables and record fields. So we should not use the lookupSameOccRn_maybe function, as we can't know ahead of time which record field namespace a record field with the given textual name will belong to. Fixes #24293 - - - - - da908790 by Krzysztof Gogolewski at 2024-01-15T14:16:05-05:00 Make the build more strict on documentation errors * Detect undefined labels. This can be tested by adding :ref:`nonexistent` to a documentation rst file; attempting to build docs will fail. Fixed the undefined label in `9.8.1-notes.rst`. * Detect errors. While we have plenty of warnings, we can at least enforce that Sphinx does not report errors. Fixed the error in `required_type_arguments.rst`. Unrelated change: I have documented that the `-dlint` enables `-fcatch-nonexhaustive-cases`, as can be verified by checking `enableDLint`. - - - - - 5077416e by Javier Sagredo at 2024-01-16T15:40:06-05:00 Profiling: Adds an option to not start time profiling at startup Using the functionality provided by d89deeba47ce04a5198a71fa4cbc203fe2c90794, this patch creates a new rts flag `--no-automatic-time-samples` which disables the time profiling when starting a program. It is then expected that the user starts it whenever it is needed. Fixes #24337 - - - - - 5776008c by Matthew Pickering at 2024-01-16T15:40:42-05:00 eventlog: Fix off-by-one error in postIPE We were missing the extra_comma from the calculation of the size of the payload of postIPE. This was causing assertion failures when the event would overflow the buffer by one byte, as ensureRoomForVariable event would report there was enough space for `n` bytes but then we would write `n + 1` bytes into the buffer. Fixes #24287 - - - - - 66dc09b1 by Simon Peyton Jones at 2024-01-16T15:41:18-05:00 Improve SpecConstr (esp nofib/spectral/ansi) This MR makes three improvements to SpecConstr: see #24282 * It fixes an outright (and recently-introduced) bug in `betterPat`, which was wrongly forgetting to compare the lengths of the argument lists. * It enhances ConVal to inclue a boolean for work-free-ness, so that the envt can contain non-work-free constructor applications, so that we can do more: see Note [ConVal work-free-ness] * It rejigs `subsumePats` so that it doesn't reverse the list. This can make a difference because, when patterns overlap, we arbitrarily pick the first. There is no "right" way, but this retains the old pre-subsumePats behaviour, thereby "fixing" the regression in #24282. Nofib results +======================================== | spectral/ansi -21.14% | spectral/hartel/comp_lab_zift -0.12% | spectral/hartel/parstof +0.09% | spectral/last-piece -2.32% | spectral/multiplier +6.03% | spectral/para +0.60% | spectral/simple -0.26% +======================================== | geom mean -0.18% +---------------------------------------- The regression in `multiplier` is sad, but it simply replicates GHC's previous behaviour (e.g. GHC 9.6). - - - - - 65da79b3 by Matthew Pickering at 2024-01-16T15:41:54-05:00 hadrian: Reduce Cabal verbosity The comment claims that `simpleUserHooks` decrease verbosity, and it does, but only for the `postConf` phase. The other phases are too verbose with `-V`. At the moment > 5000 lines of the build log are devoted to output from `cabal copy`. So I take the simple approach and just decrease the verbosity level again. If the output of `postConf` is essential then it would be better to implement our own `UserHooks` which doesn't decrease the verbosity for `postConf`. Fixes #24338 - - - - - 16414d7d by Matthew Pickering at 2024-01-17T10:54:59-05:00 Stop retaining old ModGuts throughout subsequent simplifier phases Each phase of the simplifier typically rewrites the majority of ModGuts, so we want to be able to release the old ModGuts as soon as possible. `name_ppr_ctxt` lives throught the whole optimiser phase and it was retaining a reference to `ModGuts`, so we were failing to release the old `ModGuts` until the end of the phase (potentially doubling peak memory usage for that particular phase). This was discovered using eras profiling (#24332) Fixes #24328 - - - - - 7f0879e1 by Matthew Pickering at 2024-01-17T10:55:35-05:00 Update nofib submodule - - - - - 320454d3 by Cheng Shao at 2024-01-17T23:02:40+00:00 ci: bump ci-images for updated wasm image - - - - - 2eca52b4 by Cheng Shao at 2024-01-17T23:06:44+00:00 base: treat all FDs as "nonblocking" on wasm On posix platforms, when performing read/write on FDs, we check the nonblocking flag first. For FDs without this flag (e.g. stdout), we call fdReady() first, which in turn calls poll() to wait for I/O to be available on that FD. This is problematic for wasm32-wasi: although select()/poll() is supported via the poll_oneoff() wasi syscall, that syscall is rather heavyweight and runtime behavior differs in different wasi implementations. The issue is even worse when targeting browsers, given there's no satisfactory way to implement async I/O as a synchronous syscall, so existing JS polyfills for wasi often give up and simply return ENOSYS. Before we have a proper I/O manager that avoids poll_oneoff() for async I/O on wasm, this patch improves the status quo a lot by merely pretending all FDs are "nonblocking". Read/write on FDs will directly invoke read()/write(), which are much more reliably handled in existing wasi implementations, especially those in browsers. Fixes #23275 and the following test cases: T7773 isEOF001 openFile009 T4808 cgrun025 Approved by CLC proposal #234: https://github.com/haskell/core-libraries-committee/issues/234 - - - - - 83c6c710 by Andrew Lelechenko at 2024-01-18T05:21:49-05:00 base: clarify how to disable warnings about partiality of Data.List.{head,tail} - - - - - c4078f2f by Simon Peyton Jones at 2024-01-18T05:22:25-05:00 Fix four bug in handling of (forall cv. body_ty) These bugs are all described in #24335 It's not easy to provoke the bug, hence no test case. - - - - - 119586ea by Alexis King at 2024-01-19T00:08:00-05:00 Always refresh profiling CCSes after running pending initializers Fixes #24171. - - - - - 9718d970 by Oleg Grenrus at 2024-01-19T00:08:36-05:00 Set default-language: GHC2021 in ghc library Go through compiler/ sources, and remove all BangPatterns (and other GHC2021 enabled extensions in these files). - - - - - 3ef71669 by Matthew Pickering at 2024-01-19T21:55:16-05:00 testsuite: Remove unused have_library function Also remove the hence unused testsuite option `--test-package-db`. Fixes #24342 - - - - - 5b7fa20c by Jade at 2024-01-19T21:55:53-05:00 Fix Spelling in the compiler Tracking: #16591 - - - - - 09875f48 by Matthew Pickering at 2024-01-20T12:20:44-05:00 testsuite: Implement `isInTreeCompiler` in a more robust way Just a small refactoring to avoid redundantly specifying the same strings in two different places. - - - - - 0d12b987 by Jade at 2024-01-20T12:21:20-05:00 Change maintainer email from cvs-ghc at haskell.org to ghc-devs at haskell.org. Fixes #22142 - - - - - 1fa1c00c by Jade at 2024-01-23T19:17:03-05:00 Enhance Documentation of functions exported by Data.Function This patch aims to improve the documentation of functions exported in Data.Function Tracking: #17929 Fixes: #10065 - - - - - ab47a43d by Jade at 2024-01-23T19:17:39-05:00 Improve documentation of hGetLine. - Add explanation for whether a newline is returned - Add examples Fixes #14804 - - - - - dd4af0e5 by Cheng Shao at 2024-01-23T19:18:17-05:00 Fix genapply for cross-compilation by nuking fragile CPP logic This commit fixes incorrectly built genapply when cross compiling (#24347) by nuking all fragile CPP logic in it from the orbit. All target-specific info are now read from DerivedConstants.h at runtime, see added note for details. Also removes a legacy Makefile and adds haskell language server support for genapply. - - - - - 0cda2b8b by Cheng Shao at 2024-01-23T19:18:17-05:00 rts: enable wasm32 register mapping The wasm backend didn't properly make use of all Cmm global registers due to #24347. Now that it is fixed, this patch re-enables full register mapping for wasm32, and we can now generate smaller & faster wasm modules that doesn't always spill arguments onto the stack. Fixes #22460 #24152. - - - - - 0325a6e5 by Greg Steuck at 2024-01-24T01:29:44-05:00 Avoid utf8 in primops.txt.pp comments They don't make it through readFile' without explicitly setting the encoding. See https://gitlab.haskell.org/ghc/ghc/-/issues/17755 - - - - - 1aaf0bd8 by David Binder at 2024-01-24T01:30:20-05:00 Bump hpc and hpc-bin submodule Bump hpc to 0.7.0.1 Bump hpc-bin to commit d1780eb2 - - - - - e693a4e8 by Ben Gamari at 2024-01-24T01:30:56-05:00 testsuite: Ignore stderr in T8089 Otherwise spurious "Killed: 9" messages to stderr may cause the test to fail. Fixes #24361. - - - - - a40f4ab2 by sheaf at 2024-01-24T14:04:33-05:00 Fix FMA instruction on LLVM We were emitting the wrong instructions for fused multiply-add operations on LLVM: - the instruction name is "llvm.fma.f32" or "llvm.fma.f64", not "fmadd" - LLVM does not support other instructions such as "fmsub"; instead we implement these by flipping signs of some arguments - the instruction is an LLVM intrinsic, which requires handling it like a normal function call instead of a machine instruction Fixes #24223 - - - - - 69abc786 by Andrei Borzenkov at 2024-01-24T14:05:09-05:00 Add changelog entry for renaming tuples from (,,...,,) to Tuple<n> (24291) - - - - - 0ac8f385 by Cheng Shao at 2024-01-25T00:27:48-05:00 compiler: remove unused GHC.Linker module The GHC.Linker module is empty and unused, other than as a hack for the make build system. We can remove it now that make is long gone; the note is moved to GHC.Linker.Loader instead. - - - - - 699da01b by Hécate Moonlight at 2024-01-25T00:28:27-05:00 Clarification for newtype constructors when using `coerce` - - - - - b2d8cd85 by Matt Walker at 2024-01-26T09:50:08-05:00 Fix #24308 Add tests for semicolon separated where clauses - - - - - 0da490a1 by Ben Gamari at 2024-01-26T17:34:41-05:00 hsc2hs: Bump submodule - - - - - 3f442fd2 by Ben Gamari at 2024-01-26T17:34:41-05:00 Bump containers submodule to 0.7 - - - - - 82a1c656 by Sebastian Nagel at 2024-01-29T02:32:40-05:00 base: with{Binary}File{Blocking} only annotates own exceptions Fixes #20886 This ensures that inner, unrelated exceptions are not misleadingly annotated with the opened file. - - - - - 9294a086 by Andreas Klebinger at 2024-01-29T02:33:15-05:00 Fix fma warning when using llvm on aarch64. On aarch64 fma is always on so the +fma flag doesn't exist for that target. Hence no need to try and pass +fma to llvm. Fixes #24379 - - - - - ced2e731 by sheaf at 2024-01-29T17:27:12-05:00 No shadowing warnings for NoFieldSelector fields This commit ensures we don't emit shadowing warnings when a user shadows a field defined with NoFieldSelectors. Fixes #24381 - - - - - 8eeadfad by Patrick at 2024-01-29T17:27:51-05:00 Fix bug wrong span of nested_doc_comment #24378 close #24378 1. Update the start position of span in `nested_doc_comment` correctly. and hence the spans of identifiers of haddoc can be computed correctly. 2. add test `HaddockSpanIssueT24378`. - - - - - a557580f by Alexey Radkov at 2024-01-30T19:41:52-05:00 Fix irrelevant dodgy-foreign-imports warning on import f-pointers by value A test *сс018* is attached (not sure about the naming convention though). Note that without the fix, the test fails with the *dodgy-foreign-imports* warning passed to stderr. The warning disappears after the fix. GHC shouldn't warn on imports of natural function pointers from C by value (which is feasible with CApiFFI), such as ```haskell foreign import capi "cc018.h value f" f :: FunPtr (Int -> IO ()) ``` where ```c void (*f)(int); ``` See a related real-world use-case [here](https://gitlab.com/daniel-casanueva/pcre-light/-/merge_requests/17). There, GHC warns on import of C function pointer `pcre_free`. - - - - - ca99efaf by Alexey Radkov at 2024-01-30T19:41:53-05:00 Rename test cc018 -> T24034 - - - - - 88c38dd5 by Ben Gamari at 2024-01-30T19:42:28-05:00 rts/TraverseHeap.c: Ensure that PosixSource.h is included first - - - - - ca2e919e by Simon Peyton Jones at 2024-01-31T09:29:45+00:00 Make decomposeRuleLhs a bit more clever This fixes #24370 by making decomposeRuleLhs undertand dictionary /functions/ as well as plain /dictionaries/ - - - - - 94ce031d by Teo Camarasu at 2024-02-01T05:49:49-05:00 doc: Add -Dn flag to user guide Resolves #24394 - - - - - 31553b11 by Ben Gamari at 2024-02-01T12:21:29-05:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 0785cf81 by Ben Gamari at 2024-02-01T12:21:29-05:00 codeGen: Use relaxed accesses in ticky bumping - - - - - be423dda by Ben Gamari at 2024-02-01T12:21:29-05:00 base: use atomic write when updating timer manager - - - - - 8a310e35 by Ben Gamari at 2024-02-01T12:21:29-05:00 Use relaxed atomics to manipulate TSO status fields - - - - - d6809ee4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Add necessary barriers when manipulating TSO owner - - - - - 39e3ac5d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Use `switch` to branch on why_blocked This is a semantics-preserving refactoring. - - - - - 515eb33d by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix synchronization on thread blocking state We now use a release barrier whenever we update a thread's blocking state. This required widening StgTSO.why_blocked as AArch64 does not support atomic writes on 16-bit values. - - - - - eb38812e by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS and only needs relaxed ordering. - - - - - 26c48dd6 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in threadStatus# - - - - - 6af43ab4 by Ben Gamari at 2024-02-01T12:21:29-05:00 rts: Fix data race in Interpreter's preemption check - - - - - 9502ad3c by Ben Gamari at 2024-02-01T12:21:29-05:00 rts/Messages: Fix data race - - - - - 60802db5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts/Prof: Fix data race - - - - - ef8ccef5 by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use relaxed ordering on dirty/clean info tables updates When changing the dirty/clean state of a mutable object we needn't have any particular ordering. - - - - - 76fe2b75 by Ben Gamari at 2024-02-01T12:21:30-05:00 codeGen: Use relaxed-read in closureInfoPtr - - - - - a6316eb4 by Ben Gamari at 2024-02-01T12:21:30-05:00 STM: Use acquire loads when possible Full sequential consistency is not needed here. - - - - - 6bddfd3d by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Use fence rather than redundant load Previously we would use an atomic load to ensure acquire ordering. However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this more directly. - - - - - 55c65dbc by Ben Gamari at 2024-02-01T12:21:30-05:00 rts: Fix data races in profiling timer - - - - - 856b5e75 by Ben Gamari at 2024-02-01T12:21:30-05:00 Add Note [C11 memory model] - - - - - 6534da24 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: move generic cmm optimization logic in NCG to a standalone module This commit moves GHC.CmmToAsm.cmmToCmm to a standalone module, GHC.Cmm.GenericOpt. The main motivation is enabling this logic to be run in the wasm backend NCG code, which is defined in other modules that's imported by GHC.CmmToAsm, causing a cyclic dependency issue. - - - - - 87e34888 by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: explicitly disable PIC in wasm32 NCG This commit explicitly disables the ncgPIC flag for the wasm32 target. The wasm backend doesn't support PIC for the time being. - - - - - c6ce242e by Cheng Shao at 2024-02-01T12:22:07-05:00 compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. - - - - - 151dda4e by Andrei Borzenkov at 2024-02-01T12:22:43-05:00 Namespacing for WARNING/DEPRECATED pragmas (#24396) New syntax for WARNING and DEPRECATED pragmas was added, namely namespace specifierss: namespace_spec ::= 'type' | 'data' | {- empty -} warning ::= warning_category namespace_spec namelist strings deprecation ::= namespace_spec namelist strings A new data type was introduced to represent these namespace specifiers: data NamespaceSpecifier = NoSpecifier | TypeNamespaceSpecifier (EpToken "type") | DataNamespaceSpecifier (EpToken "data") Extension field XWarning now contains this NamespaceSpecifier. lookupBindGroupOcc function was changed: it now takes NamespaceSpecifier and checks that the namespace of the found names matches the passed flag. With this change {-# WARNING data D "..." #-} pragma will only affect value namespace and {-# WARNING type D "..." #-} will only affect type namespace. The same logic is applicable to DEPRECATED pragmas. Finding duplicated warnings inside rnSrcWarnDecls now takes into consideration NamespaceSpecifier flag to allow warnings with the same names that refer to different namespaces. - - - - - 38c3afb6 by Bryan Richter at 2024-02-01T12:23:19-05:00 CI: Disable the test-cabal-reinstall job Fixes #24363 - - - - - 27020458 by Matthew Craven at 2024-02-03T01:53:26-05:00 Bump bytestring submodule to something closer to 0.12.1 ...mostly so that 16d6b7e835ffdcf9b894e79f933dd52348dedd0c (which reworks unaligned writes in Builder) and the stuff in https://github.com/haskell/bytestring/pull/631 can see wider testing. The less-terrible code for unaligned writes used in Builder on hosts not known to be ulaigned-friendly also takes less effort for GHC to compile, resulting in a metric decrease for T21839c on some platforms. The metric increase on T21839r is caused by the unrelated commit 750dac33465e7b59100698a330b44de7049a345c. It perhaps warrants further analysis and discussion (see #23822) but is not critical. Metric Decrease: T21839c Metric Increase: T21839r - - - - - cdddeb0f by Rodrigo Mesquita at 2024-02-03T01:54:02-05:00 Work around autotools setting C11 standard in CC/CXX In autoconf >=2.70, C11 is set by default for $CC and $CXX via the -std=...11 flag. In this patch, we split the "-std" flag out of the $CC and $CXX variables, which we traditionally assume to be just the executable name/path, and move it to $CFLAGS/$CXXFLAGS instead. Fixes #24324 - - - - - 5ff7cc26 by Apoorv Ingle at 2024-02-03T13:14:46-06:00 Expand `do` blocks right before typechecking using the `HsExpansion` philosophy. - Fixes #18324 #20020 #23147 #22788 #15598 #22086 #21206 - The change is detailed in - Note [Expanding HsDo with HsExpansion] in `GHC.Tc.Gen.Do` - Note [Doing HsExpansion in the Renamer vs Typechecker] in `GHC.Rename.Expr` expains the rational of doing expansions in type checker as opposed to in the renamer - Adds new datatypes: - `GHC.Hs.Expr.XXExprGhcRn`: new datatype makes this expansion work easier 1. Expansion bits for Expressions, Statements and Patterns in (`ExpandedThingRn`) 2. `PopErrCtxt` a special GhcRn Phase only artifcat to pop the previous error message in the error context stack - `GHC.Basic.Origin` now tracks the reason for expansion in case of Generated This is useful for type checking cf. `GHC.Tc.Gen.Expr.tcExpr` case for `HsLam` - Kills `HsExpansion` and `HsExpanded` as we have inlined them in `XXExprGhcRn` and `XXExprGhcTc` - Ensures warnings such as 1. Pattern match checks 2. Failable patterns 3. non-() return in body statements are preserved - Kill `HsMatchCtxt` in favor of `TcMatchAltChecker` - Testcases: * T18324 T20020 T23147 T22788 T15598 T22086 * T23147b (error message check), * DoubleMatch (match inside a match for pmc check) * pattern-fails (check pattern match with non-refutable pattern, eg. newtype) * Simple-rec (rec statements inside do statment) * T22788 (code snippet from #22788) * DoExpanion1 (Error messages for body statments) * DoExpansion2 (Error messages for bind statements) * DoExpansion3 (Error messages for let statements) Also repoint haddock to the right submodule so that the test (haddockHypsrcTest) pass Metric Increase 'compile_time/bytes allocated': T9020 The testcase is a pathalogical example of a `do`-block with many statements that do nothing. Given that we are expanding the statements into function binds, we will have to bear a (small) 2% cost upfront in the compiler to unroll the statements. - - - - - 0df8ce27 by Vladislav Zavialov at 2024-02-04T03:55:14-05:00 Reduce parser allocations in allocateCommentsP In the most common case, the comment queue is empty, so we can skip the work of processing it. This reduces allocations by about 10% in the parsing001 test. Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - cfd68290 by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Stop dropping a case whose binder is demanded This MR fixes #24251. See Note [Case-to-let for strictly-used binders] in GHC.Core.Opt.Simplify.Iteration, plus #24251, for lots of discussion. Final Nofib changes over 0.1%: +----------------------------------------- | imaginary/digits-of-e2 -2.16% | imaginary/rfib -0.15% | real/fluid -0.10% | real/gamteb -1.47% | real/gg -0.20% | real/maillist +0.19% | real/pic -0.23% | real/scs -0.43% | shootout/n-body -0.41% | shootout/spectral-norm -0.12% +======================================== | geom mean -0.05% Pleasingly, overall executable size is down by just over 1%. Compile times (in perf/compiler) wobble around a bit +/- 0.5%, but the geometric mean is -0.1% which seems good. - - - - - e4d137bb by Simon Peyton Jones at 2024-02-05T17:58:33-05:00 Add Note [Bangs in Integer functions] ...to document the bangs in the functions in GHC.Num.Integer - - - - - ce90f12f by Andrei Borzenkov at 2024-02-05T17:59:09-05:00 Hide WARNING/DEPRECATED namespacing under -XExplicitNamespaces (#24396) - - - - - e2ea933f by Simon Peyton Jones at 2024-02-06T10:12:04-05:00 Refactoring in preparation for lazy skolemisation * Make HsMatchContext and HsStmtContext be parameterised over the function name itself, rather than over the pass. See [mc_fun field of FunRhs] in Language.Haskell.Syntax.Expr - Replace types HsMatchContext GhcPs --> HsMatchContextPs HsMatchContext GhcRn --> HsMatchContextRn HsMatchContext GhcTc --> HsMatchContextRn (sic! not Tc) HsStmtContext GhcRn --> HsStmtContextRn - Kill off convertHsMatchCtxt * Split GHC.Tc.Type.BasicTypes.TcSigInfo so that TcCompleteSig (describing a complete user-supplied signature) is its own data type. - Split TcIdSigInfo(CompleteSig, PartialSig) into TcCompleteSig(CSig) TcPartialSig(PSig) - Use TcCompleteSig in tcPolyCheck, CheckGen - Rename types and data constructors: TcIdSigInfo --> TcIdSig TcPatSynInfo(TPSI) --> TcPatSynSig(PatSig) - Shuffle around helper functions: tcSigInfoName (moved to GHC.Tc.Types.BasicTypes) completeSigPolyId_maybe (moved to GHC.Tc.Types.BasicTypes) tcIdSigName (inlined and removed) tcIdSigLoc (introduced) - Rearrange the pattern match in chooseInferredQuantifiers * Rename functions and types: tcMatchesCase --> tcCaseMatches tcMatchesFun --> tcFunBindMatches tcMatchLambda --> tcLambdaMatches tcPats --> tcMatchPats matchActualFunTysRho --> matchActualFunTys matchActualFunTySigma --> matchActualFunTy * Add HasDebugCallStack constraints to: mkBigCoreVarTupTy, mkBigCoreTupTy, boxTy, mkPiTy, mkPiTys, splitAppTys, splitTyConAppNoView_maybe * Use `penv` from the outer context in the inner loop of GHC.Tc.Gen.Pat.tcMultiple * Move tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys down the file, factor out and export tcMkScaledFunTy. * Move isPatSigCtxt down the file. * Formatting and comments Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - f5d3e03c by Andrei Borzenkov at 2024-02-06T10:12:04-05:00 Lazy skolemisation for @a-binders (#17594) This patch is a preparation for @a-binders implementation. The main changes are: * Skolemisation is now prepared to deal with @binders. See Note [Skolemisation overview] in GHC.Tc.Utils.Unify. Most of the action is in - Utils.Unify.matchExpectedFunTys - Gen.Pat.tcMatchPats - Gen.Expr.tcPolyExprCheck - Gen.Binds.tcPolyCheck Some accompanying refactoring: * I found that funTyConAppTy_maybe was doing a lot of allocation, and rejigged userTypeError_maybe to avoid calling it. - - - - - 532993c8 by Zubin Duggal at 2024-02-06T10:12:41-05:00 driver: Really don't lose track of nodes when we fail to resolve cycles This fixes a bug in 8db8d2fd1c881032b1b360c032b6d9d072c11723, where we could lose track of acyclic components at the start of an unresolved cycle. We now ensure we never loose track of any of these components. As T24275 demonstrates, a "cyclic" SCC might not really be a true SCC: When viewed without boot files, we have a single SCC ``` [REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A [main:T24275A {-# SOURCE #-}]] ``` But with boot files this turns into ``` [NONREC main:T24275B {-# SOURCE #-} [], REC main:T24275B [main:T24275B {-# SOURCE #-}, main:T24275A {-# SOURCE #-}] main:T24275A {-# SOURCE #-} [main:T24275B], NONREC main:T24275A [main:T24275A {-# SOURCE #-}]] ``` Note that this is truly not an SCC, as no nodes are reachable from T24275B.hs-boot. However, we treat this entire group as a single "SCC" because it seems so when we analyse the graph without taking boot files into account. Indeed, we must return a single ResolvedCycle element in the BuildPlan for this as described in Note [Upsweep]. However, since after resolving this is not a true SCC anymore, `findCycle` fails to find a cycle and we have a sub-optimal error message as a result. To handle this, I extended `findCycle` to not assume its input is an SCC, and to try harder to find cycles in its input. Fixes #24275 - - - - - b35dd613 by Zubin Duggal at 2024-02-06T10:13:17-05:00 GHCi: Lookup breakpoint CCs in the correct module We need to look up breakpoint CCs in the module that the breakpoint points to, and not the current module. Fixes #24327 - - - - - b09e6958 by Zubin Duggal at 2024-02-06T10:13:17-05:00 testsuite: Add test for #24327 - - - - - 569b4c10 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add compile_artifact, ignore_extension flag In b521354216f2821e00d75f088d74081d8b236810 the testsuite gained the capability to collect generic metrics. But this assumed that the test was not linking and producing artifacts and we only wanted to track object files, interface files, or build artifacts from the compiler build. However, some backends, such as the JS backend, produce artifacts when compiling, such as the jsexe directory which we want to track. This patch: - tweaks the testsuite to collect generic metrics on any build artifact in the test directory. - expands the exe_extension function to consider windows and adds the ignore_extension flag. - Modifies certain tests to add the ignore_extension flag. Tests such as heaprof002 expect a .ps file, but on windows without ignore_extensions the testsuite will look for foo.exe.ps. Hence the flag. - adds the size_hello_artifact test - - - - - 75a31379 by doyougnu at 2024-02-07T03:06:26-05:00 ts: add wasm_arch, heapprof002 wasm extension - - - - - c9731d6d by Rodrigo Mesquita at 2024-02-07T03:07:03-05:00 Synchronize bindist configure for #24324 In cdddeb0f1280b40cc194028bbaef36e127175c4c, we set up a workaround for #24324 in the in-tree configure script, but forgot to update the bindist configure script accordingly. This updates it. - - - - - d309f4e7 by Matthew Pickering at 2024-02-07T03:07:38-05:00 distrib/configure: Fix typo in CONF_GCC_LINKER_OPTS_STAGE2 variable Instead we were setting CONF_GCC_LINK_OPTS_STAGE2 which meant that we were missing passing `--target` when invoking the linker. Fixes #24414 - - - - - 77db84ab by Ben Gamari at 2024-02-08T00:35:22-05:00 llvmGen: Adapt to allow use of new pass manager. We now must use `-passes` in place of `-O<n>` due to #21936. Closes #21936. - - - - - 3c9ddf97 by Matthew Pickering at 2024-02-08T00:35:59-05:00 testsuite: Mark length001 as fragile on javascript Modifying the timeout multiplier is not a robust way to get this test to reliably fail. Therefore we mark it as fragile until/if javascript ever supports the stack limit. - - - - - 20b702b5 by Matthew Pickering at 2024-02-08T00:35:59-05:00 Javascript: Don't filter out rtsDeps list This logic appears to be incorrect as it would drop any dependency which was not in a direct dependency of the package being linked. In the ghc-internals split this started to cause errors because `ghc-internal` is not a direct dependency of most packages, and hence important symbols to keep which are hard coded into the js runtime were getting dropped. - - - - - 2df96366 by Ben Gamari at 2024-02-08T00:35:59-05:00 base: Cleanup whitespace in cbits - - - - - 44f6557a by Ben Gamari at 2024-02-08T00:35:59-05:00 Move `base` to `ghc-internal` Here we move a good deal of the implementation of `base` into a new package, `ghc-internal` such that it can be evolved independently from the user-visible interfaces of `base`. While we want to isolate implementation from interfaces, naturally, we would like to avoid turning `base` into a mere set of module re-exports. However, this is a non-trivial undertaking for a variety of reasons: * `base` contains numerous known-key and wired-in things, requiring corresponding changes in the compiler * `base` contains a significant amount of C code and corresponding autoconf logic, which is very fragile and difficult to break apart * `base` has numerous import cycles, which are currently dealt with via carefully balanced `hs-boot` files * We must not break existing users To accomplish this migration, I tried the following approaches: * [Split-GHC.Base]: Break apart the GHC.Base knot to allow incremental migration of modules into ghc-internal: this knot is simply too intertwined to be easily pulled apart, especially given the rather tricky import cycles that it contains) * [Move-Core]: Moving the "core" connected component of base (roughly 150 modules) into ghc-internal. While the Haskell side of this seems tractable, the C dependencies are very subtle to break apart. * [Move-Incrementally]: 1. Move all of base into ghc-internal 2. Examine the module structure and begin moving obvious modules (e.g. leaves of the import graph) back into base 3. Examine the modules remaining in ghc-internal, refactor as necessary to facilitate further moves 4. Go to (2) iterate until the cost/benefit of further moves is insufficient to justify continuing 5. Rename the modules moved into ghc-internal to ensure that they don't overlap with those in base 6. For each module moved into ghc-internal, add a shim module to base with the declarations which should be exposed and any requisite Haddocks (thus guaranteeing that base will be insulated from changes in the export lists of modules in ghc-internal Here I am using the [Move-Incrementally] approach, which is empirically the least painful of the unpleasant options above Bumps haddock submodule. Metric Decrease: haddock.Cabal haddock.base Metric Increase: MultiComponentModulesRecomp T16875 size_hello_artifact - - - - - e8fb2451 by Vladislav Zavialov at 2024-02-08T00:36:36-05:00 Haddock comments on infix constructors (#24221) Rewrite the `HasHaddock` instance for `ConDecl GhcPs` to account for infix constructors. This change fixes a Haddock regression (introduced in 19e80b9af252) that affected leading comments on infix data constructor declarations: -- | Docs for infix constructor | Int :* Bool The comment should be associated with the data constructor (:*), not with its left-hand side Int. - - - - - 9060d55b by Ben Gamari at 2024-02-08T00:37:13-05:00 Add os-string as a boot package Introduces `os-string` submodule. This will be necessary for `filepath-1.5`. - - - - - 9d65235a by Ben Gamari at 2024-02-08T00:37:13-05:00 gitignore: Ignore .hadrian_ghci_multi/ - - - - - d7ee12ea by Ben Gamari at 2024-02-08T00:37:13-05:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. - - - - - f2dffd2e by Ben Gamari at 2024-02-08T00:37:13-05:00 Bump filepath to 1.5.0.0 Required bumps of the following submodules: * `directory` * `filepath` * `haskeline` * `process` * `unix` * `hsc2hs` * `Win32` * `semaphore-compat` and the addition of `os-string` as a boot package. - - - - - ab533e71 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Use specific clang assembler when compiling with -fllvm There are situations where LLVM will produce assembly which older gcc toolchains can't handle. For example on Deb10, it seems that LLVM >= 13 produces assembly which the default gcc doesn't support. A more robust solution in the long term is to require a specific LLVM compatible assembler when using -fllvm. Fixes #16354 - - - - - c32b6426 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update CI images with LLVM 15, ghc-9.6.4 and cabal-install-3.10.2.0 - - - - - 5fcd58be by Matthew Pickering at 2024-02-08T00:37:50-05:00 Update bootstrap plans for 9.4.8 and 9.6.4 - - - - - 707a32f5 by Matthew Pickering at 2024-02-08T00:37:50-05:00 Add alpine 3_18 release job This is mainly experimental and future proofing to enable a smooth transition to newer alpine releases once 3_12 is too old. - - - - - c37931b3 by John Ericson at 2024-02-08T06:39:05-05:00 Generate LLVM min/max bound policy via Hadrian Per #23966, I want the top-level configure to only generate configuration data for Hadrian, not do any "real" tasks on its own. This is part of that effort --- one less file generated by it. (It is still done with a `.in` file, so in a future world non-Hadrian also can easily create this file.) Split modules: - GHC.CmmToLlvm.Config - GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds - GHC.CmmToLlvm.Version.Type This also means we can get rid of the silly `unused.h` introduced in !6803 / 7dfcab2f4bcb7206174ea48857df1883d05e97a2 as temporary kludge. Part of #23966 - - - - - 9f987235 by Apoorv Ingle at 2024-02-08T06:39:42-05:00 Enable mdo statements to use HsExpansions Fixes: #24411 Added test T24411 for regression - - - - - 762b2120 by Jade at 2024-02-08T15:17:15+00:00 Improve Monad, Functor & Applicative docs This patch aims to improve the documentation of Functor, Applicative, Monad and related symbols. The main goal is to make it more consistent and make accessible. See also: !10979 (closed) and !10985 (closed) Ticket #17929 Updates haddock submodule - - - - - 151770ca by Josh Meredith at 2024-02-10T14:28:15-05:00 JavaScript codegen: Use GHC's tag inference where JS backend-specific evaluation inference was previously used (#24309) - - - - - 2e880635 by Zubin Duggal at 2024-02-10T14:28:51-05:00 ci: Allow release-hackage-lint to fail Otherwise it blocks the ghcup metadata pipeline from running. - - - - - b0293f78 by Matthew Pickering at 2024-02-10T14:29:28-05:00 rts: eras profiling mode The eras profiling mode is useful for tracking the life-time of closures. When a closure is written, the current era is recorded in the profiling header. This records the era in which the closure was created. * Enable with -he * User mode: Use functions ghc-experimental module GHC.Profiling.Eras to modify the era * Automatically: --automatic-era-increment, increases the user era on major collections * The first era is era 1 * -he<era> can be used with other profiling modes to select a specific era If you just want to record the era but not to perform heap profiling you can use `-he --no-automatic-heap-samples`. https://well-typed.com/blog/2024/01/ghc-eras-profiling/ Fixes #24332 - - - - - be674a2c by Jade at 2024-02-10T14:30:04-05:00 Adjust error message for trailing whitespace in as-pattern. Fixes #22524 - - - - - 53ef83f9 by doyougnu at 2024-02-10T14:30:47-05:00 gitlab: js: add codeowners Fixes: - #24409 Follow on from: - #21078 and MR !9133 - When we added the JS backend this was forgotten. This patch adds the rightful codeowners. - - - - - 8bbe12f2 by Matthew Pickering at 2024-02-10T14:31:23-05:00 Bump CI images so that alpine3_18 image includes clang15 The only changes here are that clang15 is now installed on the alpine-3_18 image. - - - - - df9fd9f7 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: handle stored null StablePtr Some Haskell codes unsafely cast StablePtr into ptr to compare against NULL. E.g. in direct-sqlite: if castStablePtrToPtr aggStPtr /= nullPtr then where `aggStPtr` is read (`peek`) from zeroed memory initially. We fix this by giving these StablePtr the same representation as other null pointers. It's safe because StablePtr at offset 0 is unused (for this exact reason). - - - - - 55346ede by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: disable MergeObjsMode test This isn't implemented for JS backend objects. - - - - - aef587f6 by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: add support for linking C sources Support linking C sources with JS output of the JavaScript backend. See the added documentation in the users guide. The implementation simply extends the JS linker to use the objects (.o) that were already produced by the emcc compiler and which were filtered out previously. I've also added some options to control the link with C functions (see the documentation about pragmas). With this change I've successfully compiled the direct-sqlite package which embeds the sqlite.c database code. Some wrappers are still required (see the documentation about wrappers) but everything generic enough to be reused for other libraries have been integrated into rts/js/mem.js. - - - - - b71b392f by Sylvain Henry at 2024-02-12T12:18:42-05:00 JS: avoid EMCC logging spurious failure emcc would sometime output messages like: cache:INFO: generating system asset: symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json... (this will be cached in "/emsdk/upstream/emscripten/cache/symbol_lists/424b44514e43d789148e69e4e7d1c7fdc0350b79.json" for subsequent builds) cache:INFO: - ok Cf https://github.com/emscripten-core/emscripten/issues/18607 This breaks our tests matching the stderr output. We avoid this by setting EMCC_LOGGING=0 - - - - - ff2c0cc9 by Simon Peyton Jones at 2024-02-12T12:19:17-05:00 Remove a dead comment Just remove an out of date block of commented-out code, and tidy up the relevant Notes. See #8317. - - - - - bedb4f0d by Teo Camarasu at 2024-02-12T18:50:33-05:00 nonmoving: Add support for heap profiling Add support for heap profiling while using the nonmoving collector. We greatly simply the implementation by disabling concurrent collection for GCs when heap profiling is enabled. This entails that the marked objects on the nonmoving heap are exactly the live objects. Note that we match the behaviour for live bytes accounting by taking the size of objects on the nonmoving heap to be that of the segment's block rather than the object itself. Resolves #22221 - - - - - d0d5acb5 by Teo Camarasu at 2024-02-12T18:51:09-05:00 doc: Add requires prof annotation to options that require it Resolves #24421 - - - - - 57bb8c92 by Cheng Shao at 2024-02-13T14:07:49-05:00 deriveConstants: add needed constants for wasm backend This commit adds needed constants to deriveConstants. They are used by RTS code in the wasm backend to support the JSFFI logic. - - - - - 615eb855 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms The pure Haskell implementation causes i386 regression in unrelated work that can be fixed by using C-based atomic increment, see added comment for details. - - - - - a9918891 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow JSFFI for wasm32 This commit allows the javascript calling convention to be used when the target platform is wasm32. - - - - - 8771a53b by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: allow boxed JSVal as a foreign type This commit allows the boxed JSVal type to be used as a foreign argument/result type. - - - - - 053c92b3 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: ensure ctors have the right priority on wasm32 This commit fixes the priorities of ctors generated by GHC codegen on wasm32, see the referred note for details. - - - - - b7942e0a by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JSFFI desugar logic for wasm32 This commit adds JSFFI desugar logic for the wasm backend. - - - - - 2c1dca76 by Cheng Shao at 2024-02-13T14:07:49-05:00 compiler: add JavaScriptFFI to supported extension list on wasm32 This commit adds JavaScriptFFI as a supported extension when the target platform is wasm32. - - - - - 9ad0e2b4 by Cheng Shao at 2024-02-13T14:07:49-05:00 rts/ghc-internal: add JSFFI support logic for wasm32 This commit adds rts/ghc-internal logic to support the wasm backend's JSFFI functionality. - - - - - e9ebea66 by Cheng Shao at 2024-02-13T14:07:49-05:00 ghc-internal: fix threadDelay for wasm in browsers This commit fixes broken threadDelay for wasm when it runs in browsers, see added note for detailed explanation. - - - - - f85f3fdb by Cheng Shao at 2024-02-13T14:07:49-05:00 utils: add JSFFI utility code This commit adds JavaScript util code to utils to support the wasm backend's JSFFI functionality: - jsffi/post-link.mjs, a post-linker to process the linked wasm module and emit a small complement JavaScript ESM module to be used with it at runtime - jsffi/prelude.js, a tiny bit of prelude code as the JavaScript side of runtime logic - jsffi/test-runner.mjs, run the jsffi test cases Co-authored-by: amesgen <amesgen at amesgen.de> - - - - - 77e91500 by Cheng Shao at 2024-02-13T14:07:49-05:00 hadrian: distribute jsbits needed for wasm backend's JSFFI support The post-linker.mjs/prelude.js files are now distributed in the bindist libdir, so when using the wasm backend's JSFFI feature, the user wouldn't need to fetch them from a ghc checkout manually. - - - - - c47ba1c3 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add opts.target_wrapper This commit adds opts.target_wrapper which allows overriding the target wrapper on a per test case basis when testing a cross target. This is used when testing the wasm backend's JSFFI functionality; the rest of the cases are tested using wasmtime, though the jsffi cases are tested using the node.js based test runner. - - - - - 8e048675 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: T22774 should work for wasm JSFFI T22774 works since the wasm backend now supports the JSFFI feature. - - - - - 1d07f9a6 by Cheng Shao at 2024-02-13T14:07:49-05:00 testsuite: add JSFFI test cases for wasm backend This commit adds a few test cases for the wasm backend's JSFFI functionality, as well as a simple README to instruct future contributors to add new test cases. - - - - - b8997080 by Cheng Shao at 2024-02-13T14:07:49-05:00 docs: add documentation for wasm backend JSFFI This commit adds changelog and user facing documentation for the wasm backend's JSFFI feature. - - - - - ffeb000d by David Binder at 2024-02-13T14:08:30-05:00 Add tests from libraries/process/tests and libraries/Win32/tests to GHC These tests were previously part of the libraries, which themselves are submodules of the GHC repository. This commit moves the tests directly to the GHC repository. - - - - - 5a932cf2 by David Binder at 2024-02-13T14:08:30-05:00 Do not execute win32 tests on non-windows runners - - - - - 500d8cb8 by Jade at 2024-02-13T14:09:07-05:00 prevent GHCi (and runghc) from suggesting other symbols when not finding main Fixes: #23996 - - - - - b19ec331 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: update xxHash to v0.8.2 - - - - - 4a97bdb8 by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: use XXH3_64bits hash on all 64-bit platforms This commit enables XXH3_64bits hash to be used on all 64-bit platforms. Previously it was only enabled on x86_64, so platforms like aarch64 silently falls back to using XXH32 which degrades the hashing function quality. - - - - - ee01de7d by Cheng Shao at 2024-02-13T14:09:46-05:00 rts: define XXH_INLINE_ALL This commit cleans up how we include the xxhash.h header and only define XXH_INLINE_ALL, which is sufficient to inline the xxHash functions without symbol collision. - - - - - 0e01e1db by Alan Zimmerman at 2024-02-14T02:13:22-05:00 EPA: Move EpAnn out of extension points Leaving a few that are too tricky, maybe some other time. Also - remove some unneeded helpers from Parser.y - reduce allocations with strictness annotations Updates haddock submodule Metric Decrease: parsing001 - - - - - de589554 by Andreas Klebinger at 2024-02-14T02:13:59-05:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 - - - - - 325b7613 by Ben Gamari at 2024-02-14T14:27:45-05:00 rts/EventLog: Place eliminate duplicate strlens Previously many of the `post*` implementations would first compute the length of the event's strings in order to determine the event length. Later we would then end up computing the length yet again in `postString`. Now we instead pass the string length to `postStringLen`, avoiding the repeated work. - - - - - 8aafa51c by Ben Gamari at 2024-02-14T14:27:46-05:00 rts/eventlog: Place upper bound on IPE string field lengths The strings in IPE events may be of unbounded length. Limit the lengths of these fields to 64k characters to ensure that we don't exceed the maximum event length. - - - - - 0e60d52c by Zubin Duggal at 2024-02-14T14:27:46-05:00 rts: drop unused postString function - - - - - d8d1333a by Cheng Shao at 2024-02-14T14:28:23-05:00 compiler/rts: fix wasm unreg regression This commit fixes two wasm unreg regressions caught by a nightly pipeline: - Unknown stg_scheduler_loopzh symbol when compiling scheduler.cmm - Invalid _hs_constructor(101) function name when handling ctor - - - - - 264a4fa9 by Owen Shepherd at 2024-02-15T09:41:06-05:00 feat: Add sortOn to Data.List.NonEmpty Adds `sortOn` to `Data.List.NonEmpty`, and adds comments describing when to use it, compared to `sortWith` or `sortBy . comparing`. The aim is to smooth out the API between `Data.List`, and `Data.List.NonEmpty`. This change has been discussed in the [clc issue](https://github.com/haskell/core-libraries-committee/issues/227). - - - - - b57200de by Fendor at 2024-02-15T09:41:47-05:00 Prefer RdrName over OccName for looking up locations in doc renaming step Looking up by OccName only does not take into account when functions are only imported in a qualified way. Fixes issue #24294 Bump haddock submodule to include regression test - - - - - 8ad02724 by Luite Stegeman at 2024-02-15T17:33:32-05:00 JS: add simple optimizer The simple optimizer reduces the size of the code generated by the JavaScript backend without the complexity and performance penalty of the optimizer in GHCJS. Also see #22736 Metric Decrease: libdir size_hello_artifact - - - - - 20769b36 by Matthew Pickering at 2024-02-15T17:34:07-05:00 base: Expose `--no-automatic-time-samples` in `GHC.RTS.Flags` API This patch builds on 5077416e12cf480fb2048928aa51fa4c8fc22cf1 and modifies the base API to reflect the new RTS flag. CLC proposal #243 - https://github.com/haskell/core-libraries-committee/issues/243 Fixes #24337 - - - - - 08031ada by Teo Camarasu at 2024-02-16T13:37:00-05:00 base: export System.Mem.performBlockingMajorGC The corresponding C function was introduced in ba73a807edbb444c49e0cf21ab2ce89226a77f2e. As part of #22264. Resolves #24228 The CLC proposal was disccused at: https://github.com/haskell/core-libraries-committee/issues/230 Co-authored-by: Ben Gamari <bgamari.foss at gmail.com> - - - - - 1f534c2e by Florian Weimer at 2024-02-16T13:37:42-05:00 Fix C output for modern C initiative GCC 14 on aarch64 rejects the C code written by GHC with this kind of error: error: assignment to ‘ffi_arg’ {aka ‘long unsigned int’} from ‘HsPtr’ {aka ‘void *’} makes integer from pointer without a cast [-Wint-conversion] 68 | *(ffi_arg*)resp = cret; | ^ Add the correct cast. For more information on this see: https://fedoraproject.org/wiki/Changes/PortingToModernC Tested-by: Richard W.M. Jones <rjones at redhat.com> - - - - - 5d3f7862 by Matthew Craven at 2024-02-16T13:38:18-05:00 Bump bytestring submodule to 0.12.1.0 - - - - - 902ebcc2 by Ian-Woo Kim at 2024-02-17T06:01:01-05:00 Add missing BCO handling in scavenge_one. - - - - - 97d26206 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Make cast between words and floats real primops (#24331) First step towards fixing #24331. Replace foreign prim imports with real primops. - - - - - a40e4781 by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: add constant folding for bitcast between float and word (#24331) - - - - - 5fd2c00f by Sylvain Henry at 2024-02-17T06:01:44-05:00 Perf: replace stack checks with assertions in casting primops There are RESERVED_STACK_WORDS free words (currently 21) on the stack, so omit the checks. Suggested by Cheng Shao. - - - - - 401dfe7b by Sylvain Henry at 2024-02-17T06:01:44-05:00 Reexport primops from GHC.Float + add deprecation - - - - - 4ab48edb by Ben Gamari at 2024-02-17T06:02:21-05:00 rts/Hash: Don't iterate over chunks if we don't need to free data When freeing a `HashTable` there is no reason to walk over the hash list before freeing it if the user has not given us a `dataFreeFun`. Noticed while looking at #24410. - - - - - bd5a1f91 by Cheng Shao at 2024-02-17T06:03:00-05:00 compiler: add SEQ_CST fence support In addition to existing Acquire/Release fences, this commit adds SEQ_CST fence support to GHC, allowing Cmm code to explicitly emit a fence that enforces total memory ordering. The following logic is added: - The MO_SeqCstFence callish MachOp - The %prim fence_seq_cst() Cmm syntax and the SEQ_CST_FENCE macro in Cmm.h - MO_SeqCstFence lowering logic in every single GHC codegen backend - - - - - 2ce2a493 by Cheng Shao at 2024-02-17T06:03:38-05:00 testsuite: fix hs_try_putmvar002 for targets without pthread.h hs_try_putmvar002 includes pthread.h and doesn't work on targets without this header (e.g. wasm32). It doesn't need to include this header at all. This was previously unnoticed by wasm CI, though recent toolchain upgrade brought in upstream changes that completely removes pthread.h in the single-threaded wasm32-wasi sysroot, therefore we need to handle that change. - - - - - 1fb3974e by Cheng Shao at 2024-02-17T06:03:38-05:00 ci: bump ci-images to use updated wasm image This commit bumps our ci-images revision to use updated wasm image. - - - - - 56e3f097 by Andrew Lelechenko at 2024-02-17T06:04:13-05:00 Bump submodule text to 2.1.1 T17123 allocates less because of improvements to Data.Text.concat in 1a6a06a. Metric Decrease: T17123 - - - - - a7569495 by Cheng Shao at 2024-02-17T06:04:51-05:00 rts: remove redundant rCCCS initialization This commit removes the redundant logic of initializing each Capability's rCCCS to CCS_SYSTEM in initProfiling(). Before initProfiling() is called during RTS startup, each Capability's rCCCS has already been assigned CCS_SYSTEM when they're first initialized. - - - - - 7a0293cc by Ben Gamari at 2024-02-19T07:11:00-05:00 Drop dependence on `touch` This drops GHC's dependence on the `touch` program, instead implementing it within GHC. This eliminates an external dependency and means that we have one fewer program to keep track of in the `configure` script - - - - - 0dbd729e by Andrei Borzenkov at 2024-02-19T07:11:37-05:00 Parser, renamer, type checker for @a-binders (#17594) GHC Proposal 448 introduces binders for invisible type arguments (@a-binders) in various contexts. This patch implements @-binders in lambda patterns and function equations: {-# LANGUAGE TypeAbstractions #-} id1 :: a -> a id1 @t x = x :: t -- @t-binder on the LHS of a function equation higherRank :: (forall a. (Num a, Bounded a) => a -> a) -> (Int8, Int16) higherRank f = (f 42, f 42) ex :: (Int8, Int16) ex = higherRank (\ @a x -> maxBound @a - x ) -- @a-binder in a lambda pattern in an argument -- to a higher-order function Syntax ------ To represent those @-binders in the AST, the list of patterns in Match now uses ArgPat instead of Pat: data Match p body = Match { ... - m_pats :: [LPat p], + m_pats :: [LArgPat p], ... } + data ArgPat pass + = VisPat (XVisPat pass) (LPat pass) + | InvisPat (XInvisPat pass) (HsTyPat (NoGhcTc pass)) + | XArgPat !(XXArgPat pass) The VisPat constructor represents patterns for visible arguments, which include ordinary value-level arguments and required type arguments (neither is prefixed with a @), while InvisPat represents invisible type arguments (prefixed with a @). Parser ------ In the grammar (Parser.y), the lambda and lambda-cases productions of aexp non-terminal were updated to accept argpats instead of apats: aexp : ... - | '\\' apats '->' exp + | '\\' argpats '->' exp ... - | '\\' 'lcases' altslist(apats) + | '\\' 'lcases' altslist(argpats) ... + argpat : apat + | PREFIX_AT atype Function left-hand sides did not require any changes to the grammar, as they were already parsed with productions capable of parsing @-binders. Those binders were being rejected in post-processing (isFunLhs), and now we accept them. In Parser.PostProcess, patterns are constructed with the help of PatBuilder, which is used as an intermediate data structure when disambiguating between FunBind and PatBind. In this patch we define ArgPatBuilder to accompany PatBuilder. ArgPatBuilder is a short-lived data structure produced in isFunLhs and consumed in checkFunBind. Renamer ------- Renaming of @-binders builds upon prior work on type patterns, implemented in 2afbddb0f24, which guarantees proper scoping and shadowing behavior of bound type variables. This patch merely defines rnLArgPatsAndThen to process a mix of visible and invisible patterns: + rnLArgPatsAndThen :: NameMaker -> [LArgPat GhcPs] -> CpsRn [LArgPat GhcRn] + rnLArgPatsAndThen mk = mapM (wrapSrcSpanCps rnArgPatAndThen) where + rnArgPatAndThen (VisPat x p) = ... rnLPatAndThen ... + rnArgPatAndThen (InvisPat _ tp) = ... rnHsTyPat ... Common logic between rnArgPats and rnPats is factored out into the rn_pats_general helper. Type checker ------------ Type-checking of @-binders builds upon prior work on lazy skolemisation, implemented in f5d3e03c56f. This patch extends tcMatchPats to handle @-binders. Now it takes and returns a list of LArgPat rather than LPat: tcMatchPats :: ... - -> [LPat GhcRn] + -> [LArgPat GhcRn] ... - -> TcM ([LPat GhcTc], a) + -> TcM ([LArgPat GhcTc], a) Invisible binders in the Match are matched up with invisible (Specified) foralls in the type. This is done with a new clause in the `loop` worker of tcMatchPats: loop :: [LArgPat GhcRn] -> [ExpPatType] -> TcM ([LArgPat GhcTc], a) loop (L l apat : pats) (ExpForAllPatTy (Bndr tv vis) : pat_tys) ... -- NEW CLAUSE: | InvisPat _ tp <- apat, isSpecifiedForAllTyFlag vis = ... In addition to that, tcMatchPats no longer discards type patterns. This is done by filterOutErasedPats in the desugarer instead. x86_64-linux-deb10-validate+debug_info Metric Increase: MultiLayerModulesTH_OneShot - - - - - 486979b0 by Jade at 2024-02-19T07:12:13-05:00 Add specialized sconcat implementation for Data.Monoid.First and Data.Semigroup.First Approved CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/246 Fixes: #24346 - - - - - 17e309d2 by John Ericson at 2024-02-19T07:12:49-05:00 Fix reST in users guide It appears that aef587f65de642142c1dcba0335a301711aab951 wasn't valid syntax. - - - - - 35b0ad90 by Brandon Chinn at 2024-02-19T07:13:25-05:00 Fix searching for errors in sphinx build - - - - - 4696b966 by Cheng Shao at 2024-02-19T07:14:02-05:00 hadrian: fix wasm backend post linker script permissions The post-link.mjs script was incorrectly copied and installed as a regular data file without executable permission, this commit fixes it. - - - - - a6142e0c by Cheng Shao at 2024-02-19T07:14:40-05:00 testsuite: mark T23540 as fragile on i386 See #24449 for details. - - - - - 249caf0d by Matthew Craven at 2024-02-19T20:36:09-05:00 Add @since annotation to Data.Data.mkConstrTag - - - - - cdd939e7 by Jade at 2024-02-19T20:36:46-05:00 Enhance documentation of Data.Complex - - - - - d04f384f by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian/bindist: Ensure that phony rules are marked as such Otherwise make may not run the rule if file with the same name as the rule happens to exist. - - - - - efcbad2d by Ben Gamari at 2024-02-21T04:59:23-05:00 hadrian: Generate HSC2HS_EXTRAS variable in bindist installation We must generate the hsc2hs wrapper at bindist installation time since it must contain `--lflag` and `--cflag` arguments which depend upon the installation path. The solution here is to substitute these variables in the configure script (see mk/hsc2hs.in). This is then copied over a dummy wrapper in the install rules. Fixes #24050. - - - - - c540559c by Matthew Pickering at 2024-02-21T04:59:23-05:00 ci: Show --info for installed compiler - - - - - ab9281a2 by Matthew Pickering at 2024-02-21T04:59:23-05:00 configure: Correctly set --target flag for linker opts Previously we were trying to use the FP_CC_SUPPORTS_TARGET with 4 arguments, when it only takes 3 arguments. Instead we need to use the `FP_PROG_CC_LINKER_TARGET` function in order to set the linker flags. Actually fixes #24414 - - - - - 9460d504 by Rodrigo Mesquita at 2024-02-21T04:59:59-05:00 configure: Do not override existing linker flags in FP_LD_NO_FIXUP_CHAINS - - - - - 77629e76 by Andrei Borzenkov at 2024-02-21T05:00:35-05:00 Namespacing for fixity signatures (#14032) Namespace specifiers were added to syntax of fixity signatures: - sigdecl ::= infix prec ops | ... + sigdecl ::= infix prec namespace_spec ops | ... To preserve namespace during renaming MiniFixityEnv type now has separate FastStringEnv fields for names that should be on the term level and for name that should be on the type level. makeMiniFixityEnv function was changed to fill MiniFixityEnv in the right way: - signatures without namespace specifiers fill both fields - signatures with 'data' specifier fill data field only - signatures with 'type' specifier fill type field only Was added helper function lookupMiniFixityEnv that takes care about looking for a name in an appropriate namespace. Updates haddock submodule. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 84357d11 by Teo Camarasu at 2024-02-21T05:01:11-05:00 rts: only collect live words in nonmoving census when non-concurrent This avoids segfaults when the mutator modifies closures as we examine them. Resolves #24393 - - - - - 9ca56dd3 by Ian-Woo Kim at 2024-02-21T05:01:53-05:00 mutex wrap in refreshProfilingCCSs - - - - - 1387966a by Cheng Shao at 2024-02-21T05:02:32-05:00 rts: remove unused HAVE_C11_ATOMICS macro This commit removes the unused HAVE_C11_ATOMICS macro. We used to have a few places that have fallback paths when HAVE_C11_ATOMICS is not defined, but that is completely redundant, since the FP_CC_SUPPORTS__ATOMICS configure check will fail when the C compiler doesn't support C11 style atomics. There are also many places (e.g. in unreg backend, SMP.h, library cbits, etc) where we unconditionally use C11 style atomics anyway which work in even CentOS 7 (gcc 4.8), the oldest distro we test in our CI, so there's no value in keeping HAVE_C11_ATOMICS. - - - - - 0f40d68f by Andreas Klebinger at 2024-02-21T05:03:09-05:00 RTS: -Ds - make sure incall is non-zero before dereferencing it. Fixes #24445 - - - - - e5886de5 by Ben Gamari at 2024-02-21T05:03:44-05:00 rts/AdjustorPool: Use ExecPage abstraction This is just a minor cleanup I found while reviewing the implementation. - - - - - 09941666 by Adam Gundry at 2024-02-21T13:53:12+00:00 Define GHC2024 language edition (#24320) See https://github.com/ghc-proposals/ghc-proposals/pull/613. Also fixes #24343 and improves the documentation of language editions. Co-authored-by: Joachim Breitner <mail at joachim-breitner.de> - - - - - 5121a4ed by Ben Gamari at 2024-02-23T06:40:55-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. Bumps haddock submodule. - - - - - 0eb2265d by Hécate Moonlight at 2024-02-24T16:02:16-05:00 Improve the synopsis and description of base - - - - - 2e36f5d2 by Jade at 2024-02-24T16:02:51-05:00 Error Messages: Properly align cyclic module error Fixes: #24476 - - - - - bbfb051c by Ben Gamari at 2024-02-24T19:10:23-05:00 Allow docstrings after exports Here we extend the parser and AST to preserve docstrings following export items. We then extend Haddock to parse `@since` annotations in such docstrings, allowing changes in export structure to be properly documented. - - - - - d8d6ad8c by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Move modules into GHC.Internal.* namespace Bumps haddock submodule due to testsuite output changes. - - - - - a82af7cd by Ben Gamari at 2024-02-24T19:10:23-05:00 ghc-internal: Rewrite `@since ` to `@since base-` These will be incrementally moved to the export sites in `base` where possible. - - - - - ca3836e1 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Migrate Haddock `not-home` pragmas from `ghc-internal` This ensures that we do not use `base` stub modules as declarations' homes when not appropriate. - - - - - c8cf3e26 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Partially freeze exports of GHC.Base Sadly there are still a few module reexports. However, at least we have decoupled from the exports of `GHC.Internal.Base`. - - - - - 272573c6 by Ben Gamari at 2024-02-24T19:10:23-05:00 Move Haddock named chunks - - - - - 2d8a881d by Ben Gamari at 2024-02-24T19:10:23-05:00 Drop GHC.Internal.Data.Int - - - - - 55c4c385 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler: Fix mention to `GHC....` modules in wasm desugaring Really, these references should be via known-key names anyways. I have fixed the proximate issue here but have opened #24472 to track the additional needed refactoring. - - - - - 64150911 by Ben Gamari at 2024-02-24T19:10:23-05:00 Accept performance shifts from ghc-internal restructure As expected, Haddock now does more work. Less expected is that some other testcases actually get faster, presumably due to less interface file loading. As well, the size_hello_artifact test regressed a bit when debug information is enabled due to debug information for the new stub symbols. Metric Decrease: T12227 T13056 Metric Increase: haddock.Cabal haddock.base MultiLayerModulesTH_OneShot size_hello_artifact - - - - - 317a915b by Ben Gamari at 2024-02-24T19:10:23-05:00 Expose GHC.Wasm.Prim from ghc-experimental Previously this was only exposed from `ghc-internal` which violates our agreement that users shall not rely on things exposed from that package. Fixes #24479. - - - - - 3bbd2bf2 by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Small optimisation of evCallStack Don't lookupIds unless we actually need them. - - - - - 3e5c9e3c by Ben Gamari at 2024-02-24T19:10:23-05:00 compiler/tc: Use toException instead of SomeException - - - - - 125714a6 by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Factor out errorBelch This was useful when debugging - - - - - 3d6aae7c by Ben Gamari at 2024-02-24T19:10:23-05:00 base: Clean up imports of GHC.Stack.CloneStack - - - - - 6900306e by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move PrimMVar to GHC.Internal.MVar - - - - - 28f8a148 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Move prettyCallStack to GHC.Internal.Stack - - - - - 4892de47 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Explicit dependency to workaround #24436 Currently `ghc -M` fails to account for `.hs-boot` files correctly, leading to issues with cross-package one-shot builds failing. This currently manifests in `GHC.Exception` due to the boot file for `GHC.Internal.Stack`. Work around this by adding an explicit `import`, ensuring that `GHC.Internal.Stack` is built before `GHC.Exception`. See #24436. - - - - - 294c93a5 by Ben Gamari at 2024-02-24T19:10:24-05:00 base: Use displayException in top-level exception handler Happily this also allows us to eliminate a special case for Deadlock exceptions. Implements [CLC #198](https://github.com/haskell/core-libraries-committee/issues/198). - - - - - cf756a25 by Ben Gamari at 2024-02-24T22:11:53-05:00 rts: Fix symbol references in Wasm RTS - - - - - 4e4d47a0 by Jade at 2024-02-26T15:17:20-05:00 GHCi: Improve response to unloading, loading and reloading modules Fixes #13869 - - - - - f3de8a3c by Zubin Duggal at 2024-02-26T15:17:57-05:00 rel-eng/fetch-gitlab.py: Fix name of aarch64 alpine 3_18 release job - - - - - c71bfdff by Cheng Shao at 2024-02-26T15:18:35-05:00 hadrian/hie-bios: pass -j to hadrian This commit passes -j to hadrian in the hadrian/hie-bios scripts. When the user starts HLS in a fresh clone that has just been configured, it takes quite a while for hie-bios to pick up the ghc flags and start actual indexing, due to the fact that the hadrian build step defaulted to -j1, so -j speeds things up and improve HLS user experience in GHC. Also add -j flag to .ghcid to speed up ghcid, and sets the Windows build root to .hie-bios which also works and unifies with other platforms, the previous build root _hie-bios was missing from .gitignore anyway. - - - - - 50bfdb46 by Cheng Shao at 2024-02-26T15:18:35-05:00 ci: enable parallelism in hadrian/ghci scripts This commit enables parallelism when the hadrian/ghci scripts are called in CI. The time bottleneck is in the hadrian build step, but previously the build step wasn't parallelized. - - - - - 61a78231 by Felix Yan at 2024-02-26T15:19:14-05:00 m4: Correctly detect GCC version When calling as `cc`, GCC does not outputs lowercased "gcc" at least in 13.2.1 version here. ``` $ cc --version cc (GCC) 13.2.1 20230801 ... ``` This fails the check and outputs the confusing message: `configure: $CC is not gcc; assuming it's a reasonably new C compiler` This patch makes it check for upper-cased "GCC" too so that it works correctly: ``` checking version of gcc... 13.2.1 ``` - - - - - 001aa539 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Fix formatting in whereFrom docstring Previously it used markdown syntax rather than Haddock syntax for code quotes - - - - - e8034d15 by Teo Camarasu at 2024-02-27T13:26:46-05:00 Move ClosureType type to ghc-internal - Use ClosureType for InfoProv.ipDesc. - Use ClosureType for CloneStack.closureType. - Now ghc-heap re-exports this type from ghc-internal. See the accompanying CLC proposal: https://github.com/haskell/core-libraries-committee/issues/210 Resolves #22600 - - - - - 3da0a551 by Matthew Craven at 2024-02-27T13:27:22-05:00 StgToJS: Simplify ExprInline constructor of ExprResult Its payload was used only for a small optimization in genAlts, avoiding a few assignments for programs of this form: case NormalDataCon arg1 arg2 of x { NormalDataCon x1 x2 -> ... ; } But when compiling with optimizations, this sort of code is generally eliminated by case-of-known-constructor in Core-to-Core. So it doesn't seem worth tracking and cleaning up again in StgToJS. - - - - - 61bc92cc by Cheng Shao at 2024-02-27T16:58:42-05:00 rts: add missing ccs_mutex guard to internal_dlopen See added comment for details. Closes #24423. - - - - - dd29d3b2 by doyougnu at 2024-02-27T16:59:23-05:00 cg: Remove GHC.Cmm.DataFlow.Collections In pursuit of #15560 and #17957 and generally removing redundancy. - - - - - d3a050d2 by Cheng Shao at 2024-02-27T17:00:00-05:00 utils: remove unused lndir from tree Ever since the removal of the make build system, the in tree lndir hasn't been actually built, so this patch removes it. - - - - - 74b24a9b by Teo Camarasu at 2024-02-28T16:32:58+00:00 rts: avoid checking bdescr of value outside of Haskell heap In nonmovingTidyWeaks we want to check if the key of a weak pointer lives in the non-moving heap. We do this by checking the flags of the block the key lives in. But we need to be careful with values that live outside the Haskell heap, since they will lack a block descriptor and looking for one may lead to a segfault. In this case we should just accept that it isn't on the non-moving heap. Resolves #24492 - - - - - b4cae4ec by Simon Peyton Jones at 2024-02-29T02:10:08-05:00 In mkDataConRep, ensure the in-scope set is right A small change that fixes #24489 - - - - - 3836a110 by Cheng Shao at 2024-02-29T21:25:45-05:00 testsuite: fix T23540 fragility on 32-bit platforms T23540 is fragile on 32-bit platforms. The root cause is usage of `getEvidenceTreesAtPoint`, which internally relies on `Name`'s `Ord` instance, which is indeterministic. The solution is adding a deterministic `Ord` instance for `EvidenceInfo` and sorting the evidence trees before pretty printing. Fixes #24449. - - - - - 960c8d47 by Teo Camarasu at 2024-02-29T21:26:20-05:00 Reduce AtomicModifyIORef increment count This test leads to a lot of contention when N>2 and becomes very slow. Let's reduce the amount of work we do to compensate. Resolves #24490 - - - - - 2e46c8ad by Matthew Pickering at 2024-03-01T05:48:06-05:00 hadrian: Improve parallelism in binary-dist-dir rule I noticed that the "docs" target was needed after the libraries and executables were built. We can improve the parallelism by needing everything at once so that documentation can be built immediately after a library is built for example. - - - - - cb6c11fe by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Bump windows and freebsd boot compilers to 9.6.4 We have previously bumped the docker images to use 9.6.4, but neglected to bump the windows images until now. - - - - - 30f06996 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: darwin: Update to 9.6.2 for boot compiler 9.6.4 is currently broken due to #24050 Also update to use LLVM-15 rather than LLVM-11, which is out of date. - - - - - d9d69e12 by Matthew Pickering at 2024-03-01T05:48:07-05:00 Bump minimum bootstrap version to 9.6 - - - - - 67ace1c5 by Matthew Pickering at 2024-03-01T05:48:07-05:00 ci: Enable more documentation building Here we enable documentation building on 1. Darwin: The sphinx toolchain was already installed so we enable html and manpages. 2. Rocky8: Full documentation (toolchain already installed) 3. Alpine: Full documetnation (toolchain already installed) 4. Windows: HTML and manpages (toolchain already installed) Fixes #24465 - - - - - 39583c39 by Matthew Pickering at 2024-03-01T05:48:42-05:00 ci: Bump ci-images to allow updated aarch64-alpine image with llvm15 and clang15 - - - - - d91d00fc by Torsten Schmits at 2024-03-01T15:01:50-05:00 Introduce ListTuplePuns extension This implements Proposal 0475, introducing the `ListTuplePuns` extension which is enabled by default. Disabling this extension makes it invalid to refer to list, tuple and sum type constructors by using built-in syntax like `[Int]`, `(Int, Int)`, `(# Int#, Int# #)` or `(# Int | Int #)`. Instead, this syntax exclusively denotes data constructors for use with `DataKinds`. The conventional way of referring to these data constructors by prefixing them with a single quote (`'(Int, Int)`) is now a parser error. Tuple declarations have been moved to `GHC.Tuple.Prim` and the `Solo` data constructor has been renamed to `MkSolo` (in a previous commit). Unboxed tuples and sums now have real source declarations in `GHC.Types`. Unit and solo types for tuples are now called `Unit`, `Unit#`, `Solo` and `Solo#`. Constraint tuples now have the unambiguous type constructors `CTuple<n>` as well as `CUnit` and `CSolo`, defined in `GHC.Classes` like before. A new parser construct has been added for the unboxed sum data constructor declarations. The type families `Tuple`, `Sum#` etc. that were intended to provide nicer syntax have been omitted from this change set due to inference problems, to be implemented at a later time. See the MR discussion for more info. Updates the submodule utils/haddock. Updates the cabal submodule due to new language extension. Metric Increase: haddock.base Metric Decrease: MultiLayerModulesTH_OneShot size_hello_artifact Proposal document: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst Merge request: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8820 Tracking ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/21294 - - - - - bbdb6286 by Sylvain Henry at 2024-03-01T15:01:50-05:00 JS linker: filter unboxed tuples - - - - - dec6d8d3 by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Improve error messages coming from non-linear patterns This enriched the `CtOrigin` for non-linear patterns to include data of the pattern that created the constraint (which can be quite useful if it occurs nested in a pattern) as well as an explanation why the pattern is non-restricted in (at least in some cases). - - - - - 6612388e by Arnaud Spiwack at 2024-03-01T15:02:30-05:00 Adjust documentation of linear lets according to committee decision - - - - - 1c064ef1 by Cheng Shao at 2024-03-02T17:11:19-05:00 compiler: start deprecating cmmToRawCmmHook cmmToRawCmmHook was added 4 years ago in d561c8f6244f8280a2483e8753c38e39d34c1f01. Its only user is the Asterius project, which has been archived and deprecated in favor of the ghc wasm backend. This patch starts deprecating cmmToRawCmmHook by placing a DEPRECATED pragma, and actual removal shall happen in a future GHC major release if no issue to oppose the deprecation has been raised in the meantime. - - - - - 9b74845f by Andrew Lelechenko at 2024-03-02T17:11:55-05:00 Data.List.NonEmpty.unzip: use WARNING with category instead of DEPRECATED CLC proposal: https://github.com/haskell/core-libraries-committee/issues/258 - - - - - 61bb5ff6 by Finley McIlwaine at 2024-03-04T09:01:40-08:00 add -fprof-late-overloaded and -fprof-late-overloaded-calls * Refactor late cost centre insertion for extensibility * Add two more late cost centre insertion methods that add SCCs to overloaded top level bindings and call sites with dictionary arguments. * Some tests for the basic functionality of the new insertion methods Resolves: #24500 - - - - - 82ccb801 by Andreas Klebinger at 2024-03-04T19:59:14-05:00 x86-ncg: Fix fma codegen when arguments are globals Fix a bug in the x86 ncg where results would be wrong when the desired output register and one of the input registers were the same global. Also adds a tiny optimization to make use of the memory addressing support when convenient. Fixes #24496 - - - - - 18ad1077 by Matthew Pickering at 2024-03-05T14:22:31-05:00 rel_eng: Update hackage docs upload scripts This adds the upload of ghc-internal and ghc-experimental to our scripts which upload packages to hackage. - - - - - bf47c9ba by Matthew Pickering at 2024-03-05T14:22:31-05:00 docs: Remove stray module comment from GHC.Profiling.Eras - - - - - 37d9b340 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix ghc-internal cabal file The file mentioned some artifacts relating to the base library. I have renamed these to the new ghc-internal variants. - - - - - 23f2a478 by Matthew Pickering at 2024-03-05T14:22:31-05:00 Fix haddock source links and hyperlinked source There were a few issues with the hackage links: 1. We were using the package id rather than the package name for the package links. This is fixed by now allowing the template to mention %pkg% or %pkgid% and substituing both appropiatly. 2. The `--haddock-base-url` flag is renamed to `--haddock-for-hackage` as the new base link works on a local or remote hackage server. 3. The "src" path including too much stuff, so cross-package source links were broken as the template was getting double expanded. Fixes #24086 - - - - - 2fa336a9 by Ben Gamari at 2024-03-05T14:23:07-05:00 filepath: Bump submodule to 1.5.2.0 - - - - - 31217944 by Ben Gamari at 2024-03-05T14:23:07-05:00 os-string: Bump submodule to 2.0.2 - - - - - 4074a3f2 by Matthew Pickering at 2024-03-05T21:44:35-05:00 base: Reflect new era profiling RTS flags in GHC.RTS.Flags * -he profiling mode * -he profiling selector * --automatic-era-increment CLC proposal #254 - https://github.com/haskell/core-libraries-committee/issues/254 - - - - - a8c0e31b by Sylvain Henry at 2024-03-05T21:45:14-05:00 JS: faster implementation for some numeric primitives (#23597) Use faster implementations for the following primitives in the JS backend by not using JavaScript's BigInt: - plusInt64 - minusInt64 - minusWord64 - timesWord64 - timesInt64 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 21e3f325 by Cheng Shao at 2024-03-05T21:45:52-05:00 rts: add -xr option to control two step allocator reserved space size This patch adds a -xr RTS option to control the size of virtual memory address space reserved by the two step allocator on a 64-bit platform, see added documentation for explanation. Closes #24498. - - - - - dedcf102 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: expose HeapAlloc.h as public header This commit exposes HeapAlloc.h as a public header. The intention is to expose HEAP_ALLOCED/HEAP_ALLOCED_GC, so they can be used in assertions in other public headers, and they may also be useful for user code. - - - - - d19441d7 by Cheng Shao at 2024-03-06T13:39:04-05:00 rts: assert pointer is indeed heap allocated in Bdescr() This commit adds an assertion to Bdescr() to assert the pointer is indeed heap allocated. This is useful to rule out RTS bugs that attempt to access non-existent block descriptor of a static closure, #24492 being one such example. - - - - - 9a656a04 by Ben Gamari at 2024-03-06T13:39:39-05:00 ghc-experimental: Add dummy dependencies to work around #23942 This is a temporary measure to improve CI reliability until a proper solution is developed. Works around #23942. - - - - - 1e84b924 by Simon Peyton Jones at 2024-03-06T13:39:39-05:00 Three compile perf improvements with deep nesting These were changes are all triggered by #24471. 1. Make GHC.Core.Opt.SetLevels.lvlMFE behave better when there are many free variables. See Note [Large free-variable sets]. 2. Make GHC.Core.Opt.Arity.floatIn a bit lazier in its Cost argument. This benefits the common case where the ArityType turns out to be nullary. See Note [Care with nested expressions] 3. Make GHC.CoreToStg.Prep.cpeArg behave for deeply-nested expressions. See Note [Eta expansion of arguments in CorePrep] wrinkle (EA2). Compile times go down by up to 4.5%, and much more in artificial cases. (Geo mean of compiler/perf changes is -0.4%.) Metric Decrease: CoOpt_Read T10421 T12425 - - - - - c4b13113 by Hécate Moonlight at 2024-03-06T13:40:17-05:00 Use "module" instead of "library" when applicable in base haddocks - - - - - 9cd9efb4 by Vladislav Zavialov at 2024-03-07T13:01:54+03:00 Rephrase error message to say "visible arguments" (#24318) * Main change: make the error message generated by mkFunTysMsg more accurate by changing "value arguments" to "visible arguments". * Refactor: define a new type synonym VisArity and use it instead of Arity in a few places. It might be the case that there other places in the compiler that should talk about visible arguments rather than value arguments, but I haven't tried to find them all, focusing only on the error message reported in the ticket. - - - - - d523a6a7 by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump array submodule - - - - - 7e55003c by Ben Gamari at 2024-03-07T19:40:45-05:00 Bump stm submodule - - - - - 32d337ef by Ben Gamari at 2024-03-07T19:40:45-05:00 Introduce exception context Here we introduce the `ExceptionContext` type and `ExceptionAnnotation` class, allowing dynamically-typed user-defined annotations to be attached to exceptions. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 - - - - - 39f3d922 by Ben Gamari at 2024-03-07T19:40:46-05:00 testsuite/interface-stability: Update documentation - - - - - fdea7ada by Ben Gamari at 2024-03-07T19:40:46-05:00 ghc-internal: comment formatting - - - - - 4fba42ef by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Default and warn ExceptionContext constraints - - - - - 3886a205 by Ben Gamari at 2024-03-07T19:40:46-05:00 base: Introduce exception backtraces Here we introduce the `Backtraces` type and associated machinery for attaching these via `ExceptionContext`. These has a few compile-time regressions (`T15703` and `T9872d`) due to the additional dependencies in the exception machinery. As well, there is a surprisingly large regression in the `size_hello_artifact` test. This appears to be due to various `Integer` and `Read` bits now being reachable at link-time. I believe it should be possible to avoid this but I have accepted the change for now to get the feature merged. CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/199 GHC Proposal: https://github.com/ghc-proposals/ghc-proposals/pull/330 Metric Increase: T15703 T9872d size_hello_artifact - - - - - 18c5409f by Ben Gamari at 2024-03-07T19:40:46-05:00 users guide: Release notes for exception backtrace work - - - - - f849c5fc by Ben Gamari at 2024-03-07T19:40:46-05:00 compiler: Don't show ExceptionContext of GhcExceptions Most GhcExceptions are user-facing errors and therefore the ExceptionContext has little value. Ideally we would enable it in the DEBUG compiler but I am leaving this for future work. - - - - - dc646e6f by Sylvain Henry at 2024-03-07T19:40:46-05:00 Disable T9930fail for the JS target (cf #19174) - - - - - bfc09760 by Alan Zimmerman at 2024-03-07T19:41:22-05:00 Update showAstData to honour blanking of AnnParen Also tweak rendering of SrcSpan to remove extra blank line. - - - - - 50454a29 by Ben Gamari at 2024-03-08T03:32:42-05:00 ghc-internal: Eliminate GHC.Internal.Data.Kind This was simply reexporting things from `ghc-prim`. Instead reexport these directly from `Data.Kind`. Also add build ordering dependency to work around #23942. - - - - - 38a4b6ab by Ben Gamari at 2024-03-08T03:33:18-05:00 rts: Fix SET_HDR initialization of retainer set This fixes a regression in retainer set profiling introduced by b0293f78cb6acf2540389e22bdda420d0ab874da. Prior to that commit the heap traversal word would be initialized by `SET_HDR` using `LDV_RECORD_CREATE`. However, the commit added a `doingLDVProfiling` check in `LDV_RECORD_CREATE`, meaning that this initialization no longer happened. Given that this initialization was awkwardly indirectly anyways, I have fixed this by explicitly initializating the heap traversal word to `NULL` in `SET_PROF_HDR`. This is equivalent to the previous behavior, but much more direct. Fixes #24513. - - - - - 2859a637 by Ben Gamari at 2024-03-08T18:26:47-05:00 base: Use strerror_r instead of strerror As noted by #24344, `strerror` is not necessarily thread-safe. Thankfully, POSIX.1-2001 has long offered `strerror_r`, which is safe to use. Fixes #24344. CLC discussion: https://github.com/haskell/core-libraries-committee/issues/249 - - - - - edb9bf77 by Jade at 2024-03-09T03:39:38-05:00 Error messages: Improve Error messages for Data constructors in type signatures. This patch improves the error messages from invalid type signatures by trying to guess what the user did and suggesting an appropriate fix. Partially fixes: #17879 - - - - - cfb197e3 by Patrick at 2024-03-09T03:40:15-05:00 HieAst: add module name #24493 The main purpose of this is to tuck the module name `xxx` in `module xxx where` into the hieAst. It should fix #24493. The following have been done: 1. Renamed and update the `tcg_doc_hdr :: Maybe (LHsDoc GhcRn)` to `tcg_hdr_info :: (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName))` To store the located module name information. 2. update the `RenamedSource` and `RenamedStuff` with extra `Maybe (XRec GhcRn ModuleName)` located module name information. 3. add test `testsuite/tests/hiefile/should_compile/T24493.hs` to ensure the module name is added and update several relevent tests. 4. accompanied submodule haddoc test update MR in https://gitlab.haskell.org/ghc/haddock/-/merge_requests/53 - - - - - 2341d81e by Vaibhav Sagar at 2024-03-09T03:40:54-05:00 GHC.Utils.Binary: fix a couple of typos - - - - - 5580e1bd by Ben Gamari at 2024-03-09T03:41:30-05:00 rts: Drop .wasm suffix from .prof file names This replicates the behavior on Windows, where `Hi.exe` will produce profiling output named `Hi.prof` instead of `Hi.exe.prof`. While in the area I also fixed the extension-stripping logic, which incorrectly rewrote `Hi.exefoo` to `Hi.foo`. Closes #24515. - - - - - 259495ee by Cheng Shao at 2024-03-09T03:41:30-05:00 testsuite: drop exe extension from .hp & .prof filenames See #24515 for details. - - - - - c477a8d2 by Ben Gamari at 2024-03-09T03:42:05-05:00 rts/linker: Enable GOT support on all platforms There is nothing platform-dependent about our GOT implementation and GOT support is needed by `T24171` on i386. - - - - - 2e592857 by Vladislav Zavialov at 2024-03-09T03:42:41-05:00 Drop outdated comment on TcRnIllformedTypePattern This should have been done in 0f0c53a501b but I missed it. - - - - - c554b4da by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Bounds check array write - - - - - 15c590a5 by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/CloneStack: Don't expose helper functions in header - - - - - e831ce31 by Ben Gamari at 2024-03-09T09:39:20-05:00 base: Move internals of GHC.InfoProv into GHC.InfoProv.Types Such that we can add new helpers into GHC.InfoProv.Types without breakage. - - - - - 6948e24d by Ben Gamari at 2024-03-09T09:39:20-05:00 rts: Lazily decode IPE tables Previously we would eagerly allocate `InfoTableEnt`s for each info table registered in the info table provenance map. However, this costs considerable memory and initialization time. Instead we now lazily decode these tables. This allows us to use one-third the memory *and* opens the door to taking advantage of sharing opportunities within a module. This required considerable reworking since lookupIPE now must be passed its result buffer. - - - - - 9204a04e by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Don't expose helper in header - - - - - 308926ff by Ben Gamari at 2024-03-09T09:39:20-05:00 rts/IPE: Share module_name within a Node This allows us to shave a 64-bit word off of the packed IPE entry size. - - - - - bebdea05 by Ben Gamari at 2024-03-09T09:39:20-05:00 IPE: Expose unit ID in InfoTableProv Here we add the unit ID to the info table provenance structure. - - - - - 6519c9ad by Ben Gamari at 2024-03-09T09:39:35-05:00 rts: Refactor GHC.Stack.CloneStack.decode Don't allocate a Ptr constructor per frame. - - - - - ed0b69dc by Ben Gamari at 2024-03-09T09:39:35-05:00 base: Do not expose whereFrom# from GHC.Exts - - - - - 2b1faea9 by Vladislav Zavialov at 2024-03-09T17:38:21-05:00 docs: Update info on TypeAbstractions * Mention TypeAbstractions in 9.10.1-notes.rst * Set the status to "Experimental". * Add a "Since: GHC 9.x" comment to each section. - - - - - f8b88918 by Ben Gamari at 2024-03-09T21:21:46-05:00 ci-images: Bump Alpine image to bootstrap with 9.8.2 - - - - - 705e6927 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark T24171 as fragile due to #24512 I will fix this but not in time for 9.10.1-alpha1 - - - - - c74196e1 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Mark linker_unload_native as fragile In particular this fails on platforms without `dlinfo`. I plan to address this but not before 9.10.1-alpha1. - - - - - f4d87f7a by Ben Gamari at 2024-03-09T21:21:46-05:00 configure: Bump version to 9.10 - - - - - 88df9a5f by Ben Gamari at 2024-03-09T21:21:46-05:00 Bump transformers submodule to 0.6.1.1 - - - - - 8176d5e8 by Ben Gamari at 2024-03-09T21:21:46-05:00 testsuite: Increase ulimit for T18623 1 MByte was just too tight and failed intermittently on some platforms (e.g. CentOS 7). Bumping the limit to 8 MByte should provide sufficient headroom. Fixes #23139. - - - - - c74b38a3 by Ben Gamari at 2024-03-09T21:21:46-05:00 base: Bump version to 4.20.0.0 - - - - - b2937fc3 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-internal: Set initial version at 9.1001.0 This provides PVP compliance while maintaining a clear correspondence between GHC releases and `ghc-internal` versions. - - - - - 4ae7d868 by Ben Gamari at 2024-03-09T21:21:46-05:00 ghc-prim: Bump version to 0.11.0 - - - - - 50798dc6 by Ben Gamari at 2024-03-09T21:21:46-05:00 template-haskell: Bump version to 2.22.0.0 - - - - - 8564f976 by Ben Gamari at 2024-03-09T21:21:46-05:00 base-exports: Accommodate spurious whitespace changes in 32-bit output It appears that this was - - - - - 9d4f0e98 by Ben Gamari at 2024-03-09T21:21:46-05:00 users-guide: Move exception backtrace relnotes to 9.10 This was previously mistakenly added to the GHC 9.8 release notes. - - - - - 145eae60 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix name of Rocky8 artifact - - - - - 39c2a630 by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/rel_eng: Fix path of generate_jobs_metadata - - - - - aed034de by Ben Gamari at 2024-03-09T21:21:46-05:00 gitlab/upload: Rework recompression The old `combine` approach was quite fragile due to use of filename globbing. Moreover, it didn't parallelize well. This refactoring makes the goal more obvious, parallelizes better, and is more robust. - - - - - dc207d06 by Ben Gamari at 2024-03-10T08:56:08-04:00 configure: Bump GHC version to 9.11 Bumps haddock submodule. - - - - - 8b2513e8 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload code when profiling is enabled The heap census may contain references (e.g. `Counter.identity`) to static data which must be available when the census is reported at the end of execution. Fixes #24512. - - - - - 7810b4c3 by Ben Gamari at 2024-03-11T01:20:03-04:00 rts/linker: Don't unload native objects when dlinfo isn't available To do so is unsafe as we have no way of identifying references to symbols provided by the object. Fixes #24513. Fixes #23993. - - - - - 0590764c by Ben Gamari at 2024-03-11T01:20:39-04:00 rel_eng/upload: Purge both $rel_name/ and $ver/ This is necessary for prereleases, where GHCup accesses the release via `$ver/` - - - - - b85a4631 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Remove duplicate code normalising slashes - - - - - c91946f9 by Brandon Chinn at 2024-03-12T19:25:56-04:00 Simplify regexes with raw strings - - - - - 1a5f53c6 by Brandon Chinn at 2024-03-12T19:25:57-04:00 Don't normalize backslashes in characters - - - - - 7ea971d3 by Andrei Borzenkov at 2024-03-12T19:26:32-04:00 Fix compiler crash caused by implicit RHS quantification in type synonyms (#24470) - - - - - 39f3ac3e by Cheng Shao at 2024-03-12T19:27:11-04:00 Revert "compiler: make genSym use C-based atomic increment on non-JS 32-bit platforms" This reverts commit 615eb855416ce536e02ed935ecc5a6f25519ae16. It was originally intended to fix #24449, but it was merely sweeping the bug under the rug. 3836a110577b5c9343915fd96c1b2c64217e0082 has properly fixed the fragile test, and we no longer need the C version of genSym. Furthermore, the C implementation causes trouble when compiling with clang that targets i386 due to alignment warning and libatomic linking issue, so it makes sense to revert it. - - - - - e6bfb85c by Cheng Shao at 2024-03-12T19:27:11-04:00 compiler: fix out-of-bound memory access of genSym on 32-bit This commit fixes an unnoticed out-of-bound memory access of genSym on 32-bit. ghc_unique_inc is 32-bit sized/aligned on 32-bit platforms, but we mistakenly treat it as a Word64 pointer in genSym, and therefore will accidentally load 2 garbage higher bytes, or with a small but non-zero chance, overwrite something else in the data section depends on how the linker places the data segments. This regression was introduced in !11802 and fixed here. - - - - - 77171cd1 by Ben Orchard at 2024-03-14T09:00:40-04:00 Note mutability of array and address access primops Without an understanding of immutable vs. mutable memory, the index primop family have a potentially non-intuitive type signature: indexOffAddr :: Addr# -> Int# -> a readOffAddr :: Addr# -> Int# -> State# d -> (# State# d, a #) indexOffAddr# might seem like a free generality improvement, which it certainly is not! This change adds a brief note on mutability expectations for most index/read/write access primops. - - - - - 7da7f8f6 by Alan Zimmerman at 2024-03-14T09:01:15-04:00 EPA: Fix regression discarding comments in contexts Closes #24533 - - - - - 73be65ab by Fendor at 2024-03-19T01:42:53-04:00 Fix sharing of 'IfaceTyConInfo' during core to iface type translation During heap analysis, we noticed that during generation of 'mi_extra_decls' we have lots of duplicates for the instances: * `IfaceTyConInfo NotPromoted IfaceNormalTyCon` * `IfaceTyConInfo IsPromoted IfaceNormalTyCon` which should be shared instead of duplicated. This duplication increased the number of live bytes by around 200MB while loading the agda codebase into GHCi. These instances are created during `CoreToIface` translation, in particular `toIfaceTyCon`. The generated core looks like: toIfaceTyCon = \ tc_sjJw -> case $wtoIfaceTyCon tc_sjJw of { (# ww_sjJz, ww1_sjNL, ww2_sjNM #) -> IfaceTyCon ww_sjJz (IfaceTyConInfo ww1_sjNL ww2_sjNM) } whichs removes causes the sharing to work propery. Adding explicit sharing, with NOINLINE annotations, changes the core to: toIfaceTyCon = \ tc_sjJq -> case $wtoIfaceTyCon tc_sjJq of { (# ww_sjNB, ww1_sjNC #) -> IfaceTyCon ww_sjNB ww1_sjNC } which looks much more like sharing is happening. We confirmed via ghc-debug that all duplications were eliminated and the number of live bytes are noticeably reduced. - - - - - bd8209eb by Alan Zimmerman at 2024-03-19T01:43:28-04:00 EPA: Address more 9.10.1-alpha1 regressions from recent changes Closes #24533 Hopefully for good this time - - - - - 31bf85ee by Fendor at 2024-03-19T14:48:08-04:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. - - - - - f45f700e by Matthew Pickering at 2024-03-19T14:48:44-04:00 Read global package database from settings file Before this patch, the global package database was always assumed to be in libdir </> package.conf.d. This causes issues in GHC's build system because there are sometimes situations where the package database you need to use is not located in the same place as the settings file. * The stage1 compiler needs to use stage1 libraries, so we should set "Global Package DB" for the stage1 compiler to the stage1 package database. * Stage 2 cross compilers need to use stage2 libraries, so likewise, we should set the package database path to `_build/stage2/lib/` * The normal situation is where the stage2 compiler uses stage1 libraries. Then everything lines up. * When installing we have rearranged everything so that the settings file and package database line up properly, so then everything should continue to work as before. In this case we set the relative package db path to `package.conf.d`, so it resolves the same as before. * ghc-pkg needs to be modified as well to look in the settings file fo the package database rather than assuming the global package database location relative to the lib folder. * Cabal/cabal-install will work correctly because they query the global package database using `--print-global-package-db`. A reasonable question is why not generate the "right" settings files in the right places in GHC's build system. In order to do this you would need to engineer wrappers for all executables to point to a specific libdir. There are also situations where the same package db is used by two different compilers with two different settings files (think stage2 cross compiler and stage3 compiler). In short, this 10 line patch allows for some reasonable simplifications in Hadrian at very little cost to anything else. Fixes #24502 - - - - - 4c8f1794 by Matthew Pickering at 2024-03-19T14:48:44-04:00 hadrian: Remove stage1 testsuite wrappers logic Now instead of producing wrappers which pass the global package database argument to ghc and ghc-pkg, we write the location of the correct package database into the settings file so you can just use the intree compiler directly. - - - - - da0d8ba5 by Matthew Craven at 2024-03-19T14:49:20-04:00 Remove unused ghc-internal module "GHC.Internal.Constants" - - - - - b56d2761 by Matthew Craven at 2024-03-19T14:49:20-04:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 349ea330 by Fendor at 2024-03-19T14:50:00-04:00 Eliminate thunk in 'IfaceTyCon' Heap analysis showed that `IfaceTyCon` retains a thunk to `IfaceTyConInfo`, defeating the sharing of the most common instances of `IfaceTyConInfo`. We make sure the indirection is removed by adding bang patterns to `IfaceTyCon`. Experimental results on the agda code base, where the `mi_extra_decls` were read from disk: Before this change, we observe around 8654045 instances of: `IfaceTyCon[Name,THUNK_1_0]` But these thunks almost exclusively point to a shared value! Forcing the thunk a little bit more, leads to `ghc-debug` reporting: `IfaceTyCon[Name:Name,IfaceTyConInfo]` and a noticeable reduction of live bytes (on agda ~10%). - - - - - 594bee0b by Krzysztof Gogolewski at 2024-03-19T14:50:36-04:00 Minor misc cleanups - GHC.HsToCore.Foreign.JavaScript: remove dropRuntimeRepArgs; boxed tuples don't take RuntimeRep args - GHC.HsToCore.Foreign.Call: avoid partial pattern matching - GHC.Stg.Unarise: strengthen the assertion; we can assert that non-rubbish literals are unary rather than just non-void - GHC.Tc.Gen.HsType: make sure the fsLit "literal" rule fires - users_guide/using-warnings.rst: remove -Wforall-identifier, now deprecated and does nothing - users_guide/using.rst: fix formatting - andy_cherry/test.T: remove expect_broken_for(23272...), 23272 is fixed The rest are simple cleanups. - - - - - cf55a54b by Ben Gamari at 2024-03-19T14:51:12-04:00 mk/relpath: Fix quoting Previously there were two instances in this script which lacked proper quoting. This resulted in `relpath` invocations in the binary distribution Makefile producing incorrect results on Windows, leading to confusing failures from `sed` and the production of empty package registrations. Fixes #24538. - - - - - 5ff88389 by Bryan Richter at 2024-03-19T14:51:48-04:00 testsuite: Disable T21336a on wasm - - - - - 60023351 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian/bindist: Eliminate extraneous `dirname` invocation Previously we would call `dirname` twice per installed library file. We now instead reuse this result. This helps appreciably on Windows, where processes are quite expensive. - - - - - 616ac300 by Ben Gamari at 2024-03-19T22:33:10-04:00 hadrian: Package mingw toolchain in expected location This fixes #24525, a regression due to 41cbaf44a6ab5eb9fa676d65d32df8377898dc89. Specifically, GHC expects to find the mingw32 toolchain in the binary distribution root. However, after this patch it was packaged in the `lib/` directory. - - - - - de9daade by Ben Gamari at 2024-03-19T22:33:11-04:00 gitlab/rel_eng: More upload.sh tweaks - - - - - 1dfe12db by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_eng: Drop dead prepare_docs codepath - - - - - dd2d748b by Ben Gamari at 2024-03-19T22:33:11-04:00 rel_env/recompress_all: unxz before recompressing Previously we would rather compress the xz *again*, before in addition compressing it with the desired scheme. Fixes #24545. - - - - - 9d936c57 by Ben Gamari at 2024-03-19T22:33:11-04:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. - - - - - 6d398066 by Ben Gamari at 2024-03-19T22:33:11-04:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. - - - - - 576f8b7e by Zubin Duggal at 2024-03-19T22:33:46-04:00 Revert "Apply shellcheck suggestion to SUBST_TOOLDIR" This reverts commit c82770f57977a2b5add6e1378f234f8dd6153392. The shellcheck suggestion is spurious and results in SUBST_TOOLDIR being a no-op. `set` sets positional arguments for bash, but we want to set the variable given as the first autoconf argument. Fixes #24542 Metric decreases because the paths in the settings file are now shorter, so we allocate less when we read the settings file. ------------------------- Metric Decrease: T12425 T13035 T9198 ------------------------- - - - - - cdfe6e01 by Fendor at 2024-03-19T22:34:22-04:00 Compact serialisation of IfaceAppArgs In #24563, we identified that IfaceAppArgs serialisation tags each cons cell element with a discriminator byte. These bytes add up quickly, blowing up interface files considerably when '-fwrite-if-simplified-core' is enabled. We compact the serialisation by writing out the length of 'IfaceAppArgs', followed by serialising the elements directly without any discriminator byte. This improvement can decrease the size of some interface files by up to 35%. - - - - - 97a2bb1c by Simon Peyton Jones at 2024-03-20T17:11:29+00:00 Expand untyped splices in tcPolyExprCheck Fixes #24559 - - - - - 5f275176 by Alan Zimmerman at 2024-03-20T22:44:12-04:00 EPA: Clean up Exactprint helper functions a bit - Introduce a helper lens to compose on `EpAnn a` vs `a` versions - Rename some prime versions of functions back to non-prime They were renamed during the rework - - - - - da2a10ce by Vladislav Zavialov at 2024-03-20T22:44:48-04:00 Type operators in promoteOccName (#24570) Type operators differ from term operators in that they are lexically classified as (type) constructors, not as (type) variables. Prior to this change, promoteOccName did not account for this difference, causing a scoping issue that affected RequiredTypeArguments. type (!@#) = Bool f = idee (!@#) -- Not in scope: ‘!@#’ (BUG) Now we have a special case in promoteOccName to account for this. - - - - - 247fc0fa by Preetham Gujjula at 2024-03-21T10:19:18-04:00 docs: Remove mention of non-existent Ord instance for Complex The documentation for Data.Complex says that the Ord instance for Complex Float is deficient, but there is no Ord instance for Complex a. The Eq instance for Complex Float is similarly deficient, so we use that as an example instead. - - - - - 6fafc51e by Andrei Borzenkov at 2024-03-21T10:19:54-04:00 Fix TH handling in `pat_to_type_pat` function (#24571) There was missing case for `SplicePat` in `pat_to_type_at` function, hence patterns with splicing that checked against `forall->` doesn't work properly because they fall into the "illegal pattern" case. Code example that is now accepted: g :: forall a -> () g $([p| a |]) = () - - - - - 52072f8e by Sylvain Henry at 2024-03-21T21:01:59-04:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. - - - - - 7dfdf3d9 by Sylvain Henry at 2024-03-21T21:02:40-04:00 Lexer: small perf changes - Use unsafeChr because we know our values to be valid - Remove some unnecessary use of `ord` (return Word8 values directly) - - - - - 864922ef by Sylvain Henry at 2024-03-21T21:02:40-04:00 JS: fix some comments - - - - - 3e0b2b1f by Sebastian Graf at 2024-03-21T21:03:16-04:00 Simplifier: Re-do dependency analysis in abstractFloats (#24551) In #24551, we abstracted a string literal binding over a type variable, triggering a CoreLint error when that binding floated to top-level. The solution implemented in this patch fixes this by re-doing dependency analysis on a simplified recursive let binding that is about to be type abstracted, in order to find the minimal set of type variables to abstract over. See wrinkle (AB5) of Note [Floating and type abstraction] for more details. Fixes #24551 - - - - - 8a8ac65a by Matthew Craven at 2024-03-23T00:20:52-04:00 Improve toInteger @Word32 on 64-bit platforms On 64-bit platforms, every Word32 fits in an Int, so we can convert to Int# without having to perform the overflow check integerFromWord# uses internally. - - - - - 0c48f2b9 by Apoorv Ingle at 2024-03-23T00:21:28-04:00 Fix for #24552 (see testcase T24552) Fixes for a bug in desugaring pattern synonyms matches, introduced while working on on expanding `do`-blocks in #18324 The `matchWrapper` unecessarily (and incorrectly) filtered out the default wild patterns in a match. Now the wild pattern alternative is simply ignored by the pm check as its origin is `Generated`. The current code now matches the expected semantics according to the language spec. - - - - - b72705e9 by Simon Peyton Jones at 2024-03-23T00:22:04-04:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] - - - - - 8f7cfc7e by Tristan Cacqueray at 2024-03-23T00:22:44-04:00 docs: remove the don't use float hint This hint is outdated, ``Complex Float`` are now specialised, and the heap space suggestion needs more nuance so it should be explained in the unboxed/storable array documentation. - - - - - 5bd8ed53 by Andreas Klebinger at 2024-03-23T16:18:33-04:00 NCG: Fix a bug in jump shortcutting. When checking if a jump has more than one destination account for the possibility of some jumps not being representable by a BlockId. We do so by having isJumpishInstr return a `Maybe BlockId` where Nothing represents non-BlockId jump destinations. Fixes #24507 - - - - - 8d67f247 by Ben Gamari at 2024-03-23T16:19:09-04:00 docs: Drop old release notes, add for 9.12.1 - - - - - 7db8c992 by Cheng Shao at 2024-03-25T13:45:46-04:00 rts: fix clang compilation on aarch64 This patch fixes function prototypes in ARMOutlineAtomicsSymbols.h which causes "error: address argument to atomic operation must be a pointer to _Atomic type" when compiling with clang on aarch64. - - - - - 237194ce by Sylvain Henry at 2024-03-25T13:46:27-04:00 Lexer: fix imports for Alex 3.5.1 (#24583) - - - - - 810660b7 by Cheng Shao at 2024-03-25T22:19:16-04:00 libffi-tarballs: bump libffi-tarballs submodule to libffi 3.4.6 This commit bumps the libffi-tarballs submodule to libffi 3.4.6, which includes numerous upstream libffi fixes, especially https://github.com/libffi/libffi/issues/760. - - - - - d2ba41e8 by Alan Zimmerman at 2024-03-25T22:19:51-04:00 EPA: do not duplicate comments in signature RHS - - - - - 32a8103f by Rodrigo Mesquita at 2024-03-26T21:16:12-04:00 configure: Use LDFLAGS when trying linkers A user may configure `LDFLAGS` but not `LD`. When choosing a linker, we will prefer `ldd`, then `ld.gold`, then `ld.bfd` -- however, we have to check for a working linker. If either of these fail, we try the next in line. However, we were not considering the `$LDFLAGS` when checking if these linkers worked. So we would pick a linker that does not support the current $LDFLAGS and fail further down the line when we used that linker with those flags. Fixes #24565, where `LDFLAGS=-Wl,-z,pack-relative-relocs` is not supported by `ld.gold` but that was being picked still. - - - - - bf65a7c3 by Rodrigo Mesquita at 2024-03-26T21:16:48-04:00 bindist: Clean xattrs of bin and lib at configure time For issue #21506, we started cleaning the extended attributes of binaries and libraries from the bindist *after* they were installed to workaround notarisation (#17418), as part of `make install`. However, the `ghc-toolchain` binary that is now shipped with the bindist must be run at `./configure` time. Since we only cleaned the xattributes of the binaries and libs after they were installed, in some situations users would be unable to run `ghc-toolchain` from the bindist, failing at configure time (#24554). In this commit we move the xattr cleaning logic to the configure script. Fixes #24554 - - - - - cfeb70d3 by Rodrigo Mesquita at 2024-03-26T21:17:24-04:00 Revert "NCG: Fix a bug in jump shortcutting." This reverts commit 5bd8ed53dcefe10b72acb5729789e19ceb22df66. Fixes #24586 - - - - - 13223f6d by Serge S. Gulin at 2024-03-27T07:28:51-04:00 JS: `h$rts_isProfiled` is removed from `profiling` and left its version at `rts/js/config.js` - - - - - 0acfe391 by Alan Zimmerman at 2024-03-27T07:29:27-04:00 EPA: Do not extend declaration range for trailine zero len semi The lexer inserts virtual semicolons having zero width. Do not use them to extend the list span of items in a list. - - - - - cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - a0442600 by Ben Gamari at 2024-04-29T10:52:46+01:00 rts: Add support for hugepages Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 65dd3ca6 by Matthew Pickering at 2024-04-29T10:54:31+01:00 Add cpp - - - - - 15 changed files: - − .appveyor.sh - + .editorconfig - .ghcid - .gitattributes - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - − .gitlab/circle-ci-job.sh - + .gitlab/darwin/nix/sources.json - + .gitlab/darwin/nix/sources.nix - + .gitlab/darwin/toolchain.nix - + .gitlab/generate-ci/LICENSE - + .gitlab/generate-ci/README.mkd - + .gitlab/generate-ci/flake.lock - + .gitlab/generate-ci/flake.nix The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5b5bbfbff6c434ac16930617d1b77370edb905c...65dd3ca68f13f88628225882a4f9b2dd1ef672d0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5b5bbfbff6c434ac16930617d1b77370edb905c...65dd3ca68f13f88628225882a4f9b2dd1ef672d0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 11:16:33 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 29 Apr 2024 07:16:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/conf-hi-hadrian Message-ID: <662f819148e43_261384c7daf810788d@gitlab.mail> Matthew Pickering pushed new branch wip/conf-hi-hadrian at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/conf-hi-hadrian You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 11:35:58 2024 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 29 Apr 2024 07:35:58 -0400 Subject: [Git][ghc/ghc][wip/T20749] 3 commits: CorePrep: Attach evaldUnfolding to floats to detect more values Message-ID: <662f861e8cc6_261384fdfa2012101f@gitlab.mail> Sebastian Graf pushed to branch wip/T20749 at Glasgow Haskell Compiler / GHC Commits: 271bfcd4 by Sebastian Graf at 2024-04-29T13:34:42+02:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - ed9c3c77 by Sebastian Graf at 2024-04-29T13:34:42+02:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> - - - - - 8dfbffed by Sebastian Graf at 2024-04-29T13:35:15+02:00 Fixing T15226 by calling exprOkForSpec in exprIsHNF. Urgh! - - - - - 29 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Utils/Misc.hs - testsuite/tests/dmdanal/sigs/T16859.stderr - testsuite/tests/ghci/should_run/T21052.stdout - testsuite/tests/simplCore/should_compile/T23083.stderr - + testsuite/tests/simplCore/should_run/T20749.hs - + testsuite/tests/simplCore/should_run/T20749.stdout - + testsuite/tests/simplCore/should_run/T24662.hs - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/simplStg/should_compile/T19717.stderr - testsuite/tests/simplStg/should_compile/inferTags002.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -640,6 +640,8 @@ pcDataConWithFixity' declared_infix dc_name wrk_key rri -- See Note [Constructor tag allocation] and #14657 data_con = mkDataCon dc_name declared_infix prom_info (map (const no_bang) arg_tys) + (map (const HsLazy) arg_tys) + (map (const NotMarkedStrict) arg_tys) [] -- No labelled fields tyvars ex_tyvars conc_tyvars ===================================== compiler/GHC/Core.hs ===================================== @@ -42,7 +42,7 @@ module GHC.Core ( foldBindersOfBindStrict, foldBindersOfBindsStrict, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, - collectArgs, stripNArgs, collectArgsTicks, flattenBinds, + collectArgs, collectValArgs, stripNArgs, collectArgsTicks, flattenBinds, collectFunSimple, exprToType, @@ -1029,6 +1029,64 @@ tail position: A cast changes the type, but the type must be the same. But operationally, casts are vacuous, so this is a bit unfortunate! See #14610 for ideas how to fix this. +Note [Strict fields in Core] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Evaluating a data constructor worker evaluates its strict fields. + +In other words, if `MkT` is strict in its first field and `xs` reduces to +`error "boom"`, then `MkT xs b` will throw that error. +Consequently, it is sound to seq the field before the call to the constructor, +e.g., with `case xs of xs' { __DEFAULT -> MkT xs' b }`. +Let's call this transformation "field seq insertion". + +Note in particular that the data constructor application `MkT xs b` above is +*not* a value, unless `xs` is! + +This has pervasive effect on the Core pipeline: + + * `exprIsHNF`/`exprIsConLike`/`exprOkForSpeculation` need to assert that the + strict arguments of a DataCon worker are values/ok-for-spec themselves. + + * `exprIsConApp_maybe` inserts field seqs in the `FloatBind`s it returns, so + that the Simplifier, Constant-folding, the pattern-match checker, etc. + all see the inserted field seqs when they match on strict workers. Often this + is just to emphasise strict semantics, but for case-of-known constructor + and case-to-let, field insertion is *vital*, otherwise these transformations + would lose field seqs that the user expects to happen, perhaps in order to + fix a space leak. For example, + case MkT xs b of MkT xs' b' -> b' + optimising this expression with case-of-known-con must leave behind the + field seq on `xs`, thus + case xs of xs' { __DEFAULT -> b } + + * The demand signature of a data constructor is strict in strict field + position when otherwise it is lazy. Likewise the demand *transformer* + of a DataCon worker can stricten up demands on strict field args. + See Note [Demand transformer for data constructors]. + + * In the absence of `-fpedantic-bottoms`, it is still possible that some seqs + are ultimately dropped or delayed due to eta-expansion. + See Note [Dealing with bottom]. + +Strict field semantics is exploited in STG by Note [Tag Inference]: +It performs field seq insertion to statically guarantee *taggedness* of strict +fields, establishing the Note [STG Strict Field Invariant]. (Happily, most +of those seqs are immediately detected as redundant by tag inference and are +omitted.) From then on, DataCon worker semantics are actually lazy, hence it is +important that STG passes maintain the Strict Field Invariant. + +Historical Note: +The delightfully simple description of strict field semantics is the result of +a long saga (#20749, the bits about strict data constructors in #21497, #22475), +where we tried a more lenient (but actually not) semantics first that would +allow both strict and lazy implementations of DataCon workers. This was favoured +because the "pervasive effect" throughout the compiler was deemed too large +(when it really turned out to be quite modest). +Alas, this semantics would require us to implement `exprIsHNF` in *exactly* the +same way as above, otherwise the analysis would not be conservative wrt. the +lenient semantics (which includes the strict one). It is also much harder to +explain and maintain, as it turned out. + ************************************************************************ * * In/Out type synonyms @@ -2158,6 +2216,17 @@ collectArgs expr go (App f a) as = go f (a:as) go e as = (e, as) +-- | Takes a nested application expression and returns the function +-- being applied and the arguments to which it is applied +collectValArgs :: Expr b -> (Expr b, [Arg b]) +collectValArgs expr + = go expr [] + where + go (App f a) as + | isValArg a = go f (a:as) + | otherwise = go f as + go e as = (e, as) + -- | Takes a nested application expression and returns the function -- being applied. Looking through casts and ticks to find it. collectFunSimple :: Expr b -> Expr b ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -49,18 +49,20 @@ module GHC.Core.DataCon ( dataConIsInfix, dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitTyThings, - dataConRepStrictness, dataConImplBangs, dataConBoxer, + dataConRepStrictness, + dataConImplBangs, dataConBoxer, splitDataProductType_maybe, -- ** Predicates on DataCons isNullarySrcDataCon, isNullaryRepDataCon, + isLazyDataConRep, isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon, isUnboxedSumDataCon, isCovertGadtDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, dataConUserTyVarsNeedWrapper, checkDataConTyVars, - isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, + isBanged, isUnpacked, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, -- ** Promotion related functions @@ -524,6 +526,18 @@ data DataCon -- Matches 1-1 with dcOrigArgTys -- Hence length = dataConSourceArity dataCon + dcImplBangs :: [HsImplBang], + -- The actual decisions made (including failures) + -- about the original arguments; 1-1 with orig_arg_tys + -- See Note [Bangs on data constructor arguments] + + dcStricts :: [StrictnessMark], + -- One mark for every field of the DataCon worker; + -- if it's empty, then all fields are lazy, + -- otherwise 1-1 with dataConRepArgTys. + -- See also Note [Strict fields in Core] in GHC.Core + -- for the effect on the strictness signature + dcFields :: [FieldLabel], -- Field labels for this constructor, in the -- same order as the dcOrigArgTys; @@ -826,13 +840,6 @@ data DataConRep -- after unboxing and flattening, -- and *including* all evidence args - , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] - - , dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures) - -- about the original arguments; 1-1 with orig_arg_tys - -- See Note [Bangs on data constructor arguments] - } type DataConEnv a = UniqFM DataCon a -- Keyed by DataCon @@ -901,43 +908,8 @@ eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Data-con worker strictness] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Notice that we do *not* say the worker Id is strict even if the data -constructor is declared strict - e.g. data T = MkT ![Int] Bool -Even though most often the evals are done by the *wrapper* $WMkT, there are -situations in which tag inference will re-insert evals around the worker. -So for all intents and purposes the *worker* MkT is strict, too! - -Unfortunately, if we exposed accurate strictness of DataCon workers, we'd -see the following transformation: - - f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs - ==> { drop-seq, binder swap on xs' } - f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs - ==> { case-to-let } - f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs! - -I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs` -and then doing case-to-let. The issue is that `exprIsHNF` currently says that -every DataCon worker app is a value. The implicit assumption is that surrounding -evals will have evaluated strict fields like `xs` before! But now that we had -just dropped the eval on `xs`, that assumption is no longer valid. - -Long story short: By keeping the demand signature lazy, the Simplifier will not -drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others -remains sound. - -Similarly, during demand analysis in dmdTransformDataConSig, we bump up the -field demand with `C_01`, *not* `C_11`, because the latter exposes too much -strictness that will drop the eval on `xs` above. - -This issue is discussed at length in -"Failed idea: no wrappers for strict data constructors" in #21497 and #22475. - -Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool @@ -963,8 +935,8 @@ Terminology: the flag settings in the importing module. Also see Note [Bangs on imported data constructors] in GHC.Types.Id.Make -* The dcr_bangs field of the dcRep field records the [HsImplBang] - If T was defined in this module, Without -O the dcr_bangs might be +* The dcImplBangs field records the [HsImplBang] + If T was defined in this module, Without -O the dcImplBangs might be [HsStrict _, HsStrict _, HsLazy] With -O it might be [HsStrict _, HsUnpack _, HsLazy] @@ -973,6 +945,19 @@ Terminology: With -XStrictData it might be [HsStrict _, HsUnpack _, HsStrict _] +* Core passes will often need to know whether the DataCon worker or wrapper in + an application is strict in some (lifted) field or not. This is tracked in the + demand signature attached to a DataCon's worker resp. wrapper Id. + + So if you've got a DataCon dc, you can get the demand signature by + `idDmdSig (dataConWorkId dc)` and make out strict args by testing with + `isStrictDmd`. Similarly, `idDmdSig <$> dataConWrapId_maybe dc` gives + you the demand signature of the wrapper, if it exists. + + These demand signatures are set in GHC.Types.Id.Make.mkDataConWorkId, + compute from the single source of truth `dataConRepStrictness`, which is + generated from `dcStricts`. + Note [Detecting useless UNPACK pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to issue a warning when there's an UNPACK pragma in the source code, @@ -1008,7 +993,6 @@ we consult HsImplBang: The boolean flag is used only for this warning. See #11270 for motivation. - ************************************************************************ * * \subsection{Instances} @@ -1110,6 +1094,11 @@ isBanged (HsUnpack {}) = True isBanged (HsStrict {}) = True isBanged HsLazy = False +isUnpacked :: HsImplBang -> Bool +isUnpacked (HsUnpack {}) = True +isUnpacked (HsStrict {}) = False +isUnpacked HsLazy = False + isSrcStrict :: SrcStrictness -> Bool isSrcStrict SrcStrict = True isSrcStrict _ = False @@ -1135,13 +1124,15 @@ cbvFromStrictMark MarkedStrict = MarkedCbv -- | Build a new data constructor mkDataCon :: Name - -> Bool -- ^ Is the constructor declared infix? - -> TyConRepName -- ^ TyConRepName for the promoted TyCon - -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user - -> [FieldLabel] -- ^ Field labels for the constructor, - -- if it is a record, otherwise empty - -> [TyVar] -- ^ Universals. - -> [TyCoVar] -- ^ Existentials. + -> Bool -- ^ Is the constructor declared infix? + -> TyConRepName -- ^ TyConRepName for the promoted TyCon + -> [HsSrcBang] -- ^ Strictness/unpack annotations, from user + -> [HsImplBang] -- ^ Strictness/unpack annotations, as inferred by the compiler + -> [StrictnessMark] -- ^ Strictness marks for the DataCon worker's fields in Core + -> [FieldLabel] -- ^ Field labels for the constructor, + -- if it is a record, otherwise empty + -> [TyVar] -- ^ Universals. + -> [TyCoVar] -- ^ Existentials. -> ConcreteTyVars -- ^ TyVars which must be instantiated with -- concrete types @@ -1163,7 +1154,9 @@ mkDataCon :: Name -- Can get the tag from the TyCon mkDataCon name declared_infix prom_info - arg_stricts -- Must match orig_arg_tys 1-1 + arg_stricts -- Must match orig_arg_tys 1-1 + impl_bangs -- Must match orig_arg_tys 1-1 + str_marks -- Must be empty or match dataConRepArgTys 1-1 fields univ_tvs ex_tvs conc_tvs user_tvbs eq_spec theta @@ -1180,6 +1173,8 @@ mkDataCon name declared_infix prom_info = con where is_vanilla = null ex_tvs && null eq_spec && null theta + str_marks' | not $ any isMarkedStrict str_marks = [] + | otherwise = str_marks con = MkData {dcName = name, dcUnique = nameUnique name, dcVanilla = is_vanilla, dcInfix = declared_infix, @@ -1192,7 +1187,8 @@ mkDataCon name declared_infix prom_info dcStupidTheta = stupid_theta, dcOrigArgTys = orig_arg_tys, dcOrigResTy = orig_res_ty, dcRepTyCon = rep_tycon, - dcSrcBangs = arg_stricts, + dcSrcBangs = arg_stricts, dcImplBangs = impl_bangs, + dcStricts = str_marks', dcFields = fields, dcTag = tag, dcRepType = rep_ty, dcWorkId = work_id, dcRep = rep, @@ -1435,20 +1431,25 @@ isNullarySrcDataCon dc = dataConSourceArity dc == 0 isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 +isLazyDataConRep :: DataCon -> Bool +-- ^ True <==> All fields are lazy +isLazyDataConRep dc = null (dcStricts dc) + dataConRepStrictness :: DataCon -> [StrictnessMark] --- ^ Give the demands on the arguments of a --- Core constructor application (Con dc args) -dataConRepStrictness dc = case dcRep dc of - NoDataConRep -> [NotMarkedStrict | _ <- dataConRepArgTys dc] - DCR { dcr_stricts = strs } -> strs +-- ^ Give the demands on the runtime arguments of a Core DataCon worker +-- application. +-- The length of the list matches `dataConRepArgTys` (e.g., the number +-- of runtime arguments). +dataConRepStrictness dc + | isLazyDataConRep dc + = replicate (dataConRepArity dc) NotMarkedStrict + | otherwise + = dcStricts dc dataConImplBangs :: DataCon -> [HsImplBang] -- The implementation decisions about the strictness/unpack of each -- source program argument to the data constructor -dataConImplBangs dc - = case dcRep dc of - NoDataConRep -> replicate (dcSourceArity dc) HsLazy - DCR { dcr_bangs = bangs } -> bangs +dataConImplBangs dc = dcImplBangs dc dataConBoxer :: DataCon -> Maybe DataConBoxer dataConBoxer (MkData { dcRep = DCR { dcr_boxer = boxer } }) = Just boxer ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -1533,7 +1533,7 @@ myExprIsCheap (AE { am_opts = opts, am_sigs = sigs }) e mb_ty -- See Note [Eta expanding through dictionaries] -- See Note [Eta expanding through CallStacks] - cheap_fun e = exprIsCheapX (myIsCheapApp sigs) e + cheap_fun e = exprIsCheapX (myIsCheapApp sigs) False e -- | A version of 'isCheapApp' that considers results from arity analysis. -- See Note [Arity analysis] for what's in the signature environment and why ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -209,7 +209,7 @@ cprAnal, cprAnal' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' cprAnal env e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ - cprAnal' env e + cprAnal' env e cprAnal' _ (Lit lit) = (topCprType, Lit lit) cprAnal' _ (Type ty) = (topCprType, Type ty) -- Doesn't happen, in fact @@ -296,9 +296,16 @@ data TermFlag -- Better than using a Bool -- See Note [Nested CPR] exprTerminates :: CoreExpr -> TermFlag +-- ^ A /very/ simple termination analysis. exprTerminates e - | exprIsHNF e = Terminates -- A /very/ simple termination analysis. - | otherwise = MightDiverge + | exprIsHNF e = Terminates + | exprOkForSpeculation e = Terminates + | otherwise = MightDiverge + -- Annoyingly, we have to check both for HNF and ok-for-spec. + -- * `I# (x# *# 2#)` is ok-for-spec, but not in HNF. Still worth CPR'ing! + -- * `lvl` is an HNF if its unfolding is evaluated + -- (perhaps `lvl = I# 0#` at top-level). But, tiresomely, it is never + -- ok-for-spec due to Note [exprOkForSpeculation and evaluated variables]. cprAnalApp :: AnalEnv -> CoreExpr -> [(CprType, CoreArg)] -> (CprType, CoreExpr) -- Main function that takes care of /nested/ CPR. See Note [Nested CPR] @@ -367,8 +374,8 @@ cprTransformDataConWork env con args , wkr_arity <= mAX_CPR_SIZE -- See Note [Trimming to mAX_CPR_SIZE] , args `lengthIs` wkr_arity , ae_rec_dc env con /= DefinitelyRecursive -- See Note [CPR for recursive data constructors] - -- , pprTrace "cprTransformDataConWork" (ppr con <+> ppr wkr_arity <+> ppr args) True - = CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) + = -- pprTraceWith "cprTransformDataConWork" (\r -> ppr con <+> ppr wkr_arity <+> ppr args <+> ppr r) $ + CprType 0 (ConCpr (dataConTag con) (strictZipWith extract_nested_cpr args wkr_str_marks)) | otherwise = topCprType where @@ -505,7 +512,8 @@ cprAnalBind env id rhs | isDataStructure id -- Data structure => no code => no need to analyse rhs = (id, rhs, env) | otherwise - = (id `setIdCprSig` sig', rhs', env') + = -- pprTrace "cprAnalBind" (ppr id <+> ppr sig <+> ppr sig') + (id `setIdCprSig` sig', rhs', env') where (rhs_ty, rhs') = cprAnal env rhs -- possibly trim thunk CPR info ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -835,6 +835,10 @@ to the Divergence lattice, but in practice it turned out to be hard to untaint from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. +You might think that we should check for side-effects rather than just for +precise exceptions. Right you are! See Note [Side-effects and strictness] +for why we unfortunately do not. + Note [Demand analysis for recursive data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T11545 features a single-product, recursive data type ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -8,14 +8,13 @@ module GHC.Core.Opt.Simplify.Env ( -- * The simplifier mode - SimplMode(..), updMode, - smPedanticBottoms, smPlatform, + SimplMode(..), updMode, smPlatform, -- * Environments SimplEnv(..), pprSimplEnv, -- Temp not abstract seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle, seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames, - seOptCoercionOpts, sePedanticBottoms, sePhase, sePlatform, sePreInline, + seOptCoercionOpts, sePhase, sePlatform, sePreInline, seRuleOpts, seRules, seUnfoldingOpts, mkSimplEnv, extendIdSubst, extendCvIdSubst, extendTvSubst, extendCvSubst, @@ -235,9 +234,6 @@ seNames env = sm_names (seMode env) seOptCoercionOpts :: SimplEnv -> OptCoercionOpts seOptCoercionOpts env = sm_co_opt_opts (seMode env) -sePedanticBottoms :: SimplEnv -> Bool -sePedanticBottoms env = smPedanticBottoms (seMode env) - sePhase :: SimplEnv -> CompilerPhase sePhase env = sm_phase (seMode env) @@ -292,9 +288,6 @@ instance Outputable SimplMode where where pp_flag f s = ppUnless f (text "no") <+> s -smPedanticBottoms :: SimplMode -> Bool -smPedanticBottoms opts = ao_ped_bot (sm_arity_opts opts) - smPlatform :: SimplMode -> Platform smPlatform opts = roPlatform (sm_rule_opts opts) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2204,14 +2204,14 @@ zap the SubstEnv. This is VITAL. Consider We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!! -Note [Fast path for data constructors] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Fast path for lazy data constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For applications of a data constructor worker, the full glory of rebuildCall is a waste of effort; * They never inline, obviously * They have no rewrite rules -* They are not strict (see Note [Data-con worker strictness] - in GHC.Core.DataCon) +* Though they might be strict (see Note [Strict fields in Core] in GHC.Core), + we will exploit that strictness through their demand signature So it's fine to zoom straight to `rebuild` which just rebuilds the call in a very straightforward way. @@ -2235,7 +2235,7 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont - | isDataConWorkId var -- See Note [Fast path for data constructors] + | isDataConWorkId var -- See Note [Fast path for lazy data constructors] = rebuild env (Var var) cont | otherwise = case substId env var of @@ -3420,7 +3420,7 @@ a case pattern. This is *important*. Consider We really must record that b is already evaluated so that we don't go and re-evaluate it when constructing the result. -See Note [Data-con worker strictness] in GHC.Core.DataCon +See Note [Strict fields in Core] in GHC.Core. NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1277,11 +1277,8 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr -- simplifier produces rhs[exp/a], changing semantics if exp is not ok-for-spec -- Good: returning (Mk#, [x]) with a float of case exp of x { DEFAULT -> [] } -- simplifier produces case exp of a { DEFAULT -> exp[x/a] } - = let arg' = subst_expr subst arg - bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) - float = FloatCase arg' bndr DEFAULT [] - subst' = subst_extend_in_scope subst bndr - in go subst' (float:floats) fun (CC (Var bndr : args) mco) + , (subst', float, bndr) <- case_bind subst arg arg_type + = go subst' (float:floats) fun (CC (Var bndr : args) mco) | otherwise = go subst floats fun (CC (subst_expr subst arg : args) mco) @@ -1324,8 +1321,10 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr | Just con <- isDataConWorkId_maybe fun , count isValArg args == idArity fun - = succeedWith in_scope floats $ - pushCoDataCon con args mco + , (in_scope', seq_floats, args') <- mkFieldSeqFloats in_scope con args + -- mkFieldSeqFloats: See Note [Strict fields in Core] + = succeedWith in_scope' (seq_floats ++ floats) $ + pushCoDataCon con args' mco -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do @@ -1411,6 +1410,38 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr extend (Left in_scope) v e = Right (extendSubst (mkEmptySubst in_scope) v e) extend (Right s) v e = Right (extendSubst s v e) + case_bind :: Either InScopeSet Subst -> CoreExpr -> Type -> (Either InScopeSet Subst, FloatBind, Id) + case_bind subst expr expr_ty = (subst', float, bndr) + where + bndr = setCaseBndrEvald MarkedStrict $ + uniqAway (subst_in_scope subst) $ + mkWildValBinder ManyTy expr_ty + subst' = subst_extend_in_scope subst bndr + expr' = subst_expr subst expr + float = FloatCase expr' bndr DEFAULT [] + + mkFieldSeqFloats :: InScopeSet -> DataCon -> [CoreExpr] -> (InScopeSet, [FloatBind], [CoreExpr]) + -- See Note [Strict fields in Core] for what a field seq is and why we + -- insert them + mkFieldSeqFloats in_scope dc args + | isLazyDataConRep dc + = (in_scope, [], args) + | otherwise + = (in_scope', floats', ty_args ++ val_args') + where + (ty_args, val_args) = splitAtList (dataConUnivAndExTyCoVars dc) args + (in_scope', floats', val_args') = foldr do_one (in_scope, [], []) $ zipEqual "mkFieldSeqFloats" str_marks val_args + str_marks = dataConRepStrictness dc + do_one (str, arg) (in_scope,floats,args) + | NotMarkedStrict <- str = no_seq + | exprIsHNF arg = no_seq + | otherwise = (in_scope', float:floats, Var bndr:args) + where + no_seq = (in_scope, floats, arg:args) + (in_scope', float, bndr) = + case case_bind (Left in_scope) arg (exprType arg) of + (Left in_scope', float, bndr) -> (in_scope', float, bndr) + (right, _, _) -> pprPanic "case_bind did not preserve Left" (ppr in_scope $$ ppr arg $$ ppr right) -- See Note [exprIsConApp_maybe on literal strings] dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -55,7 +55,7 @@ module GHC.Core.Type ( splitForAllForAllTyBinders, splitForAllForAllTyBinder_maybe, splitForAllTyCoVar_maybe, splitForAllTyCoVar, splitForAllTyVar_maybe, splitForAllCoVar_maybe, - splitPiTy_maybe, splitPiTy, splitPiTys, + splitPiTy_maybe, splitPiTy, splitPiTys, collectPiTyBinders, getRuntimeArgTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, @@ -290,6 +290,7 @@ import GHC.Utils.Panic import GHC.Data.FastString import GHC.Data.Maybe ( orElse, isJust, firstJust ) +import GHC.List (build) -- $type_classification -- #type_classification# @@ -2031,6 +2032,18 @@ splitPiTys ty = split ty ty [] split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs split orig_ty _ bs = (reverse bs, orig_ty) +collectPiTyBinders :: Type -> [PiTyBinder] +collectPiTyBinders ty = build $ \c n -> + let + split (ForAllTy b res) = Named b `c` split res + split (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) + = Anon (Scaled w arg) af `c` split res + split ty | Just ty' <- coreView ty = split ty' + split _ = n + in + split ty +{-# INLINE collectPiTyBinders #-} + -- | Extracts a list of run-time arguments from a function type, -- looking through newtypes to the right of arrows. -- ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1493,18 +1493,23 @@ in this (which it previously was): in \w. v True -} --------------------- -exprIsWorkFree :: CoreExpr -> Bool -- See Note [exprIsWorkFree] -exprIsWorkFree e = exprIsCheapX isWorkFreeApp e - -exprIsCheap :: CoreExpr -> Bool -exprIsCheap e = exprIsCheapX isCheapApp e +------------------------------------- +type CheapAppFun = Id -> Arity -> Bool + -- Is an application of this function to n *value* args + -- always cheap, assuming the arguments are cheap? + -- True mainly of data constructors, partial applications; + -- but with minor variations: + -- isWorkFreeApp + -- isCheapApp + -- isExpandableApp -exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool +exprIsCheapX :: CheapAppFun -> Bool -> CoreExpr -> Bool {-# INLINE exprIsCheapX #-} --- allow specialization of exprIsCheap and exprIsWorkFree +-- allow specialization of exprIsCheap, exprIsWorkFree and exprIsExpandable -- instead of having an unknown call to ok_app -exprIsCheapX ok_app e +-- expandable: Only True for exprIsExpandable, where Case and Let are never +-- expandable. +exprIsCheapX ok_app expandable e = ok e where ok e = go 0 e @@ -1515,7 +1520,7 @@ exprIsCheapX ok_app e go _ (Type {}) = True go _ (Coercion {}) = True go n (Cast e _) = go n e - go n (Case scrut _ _ alts) = ok scrut && + go n (Case scrut _ _ alts) = not expandable && ok scrut && and [ go n rhs | Alt _ _ rhs <- alts ] go n (Tick t e) | tickishCounts t = False | otherwise = go n e @@ -1523,90 +1528,26 @@ exprIsCheapX ok_app e | otherwise = go n e go n (App f e) | isRuntimeArg e = go (n+1) f && ok e | otherwise = go n f - go n (Let (NonRec _ r) e) = go n e && ok r - go n (Let (Rec prs) e) = go n e && all (ok . snd) prs + go n (Let (NonRec _ r) e) = not expandable && go n e && ok r + go n (Let (Rec prs) e) = not expandable && go n e && all (ok . snd) prs -- Case: see Note [Case expressions are work-free] -- App, Let: see Note [Arguments and let-bindings exprIsCheapX] +-------------------- +exprIsWorkFree :: CoreExpr -> Bool +-- See Note [exprIsWorkFree] +exprIsWorkFree e = exprIsCheapX isWorkFreeApp False e -{- Note [exprIsExpandable] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -An expression is "expandable" if we are willing to duplicate it, if doing -so might make a RULE or case-of-constructor fire. Consider - let x = (a,b) - y = build g - in ....(case x of (p,q) -> rhs)....(foldr k z y).... - -We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), -but we do want - - * the case-expression to simplify - (via exprIsConApp_maybe, exprIsLiteral_maybe) - - * the foldr/build RULE to fire - (by expanding the unfolding during rule matching) - -So we classify the unfolding of a let-binding as "expandable" (via the -uf_expandable field) if we want to do this kind of on-the-fly -expansion. Specifically: - -* True of constructor applications (K a b) - -* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. - (NB: exprIsCheap might not be true of this) - -* False of case-expressions. If we have - let x = case ... in ...(case x of ...)... - we won't simplify. We have to inline x. See #14688. - -* False of let-expressions (same reason); and in any case we - float lets out of an RHS if doing so will reveal an expandable - application (see SimplEnv.doFloatFromRhs). - -* Take care: exprIsExpandable should /not/ be true of primops. I - found this in test T5623a: - let q = /\a. Ptr a (a +# b) - in case q @ Float of Ptr v -> ...q... - - q's inlining should not be expandable, else exprIsConApp_maybe will - say that (q @ Float) expands to (Ptr a (a +# b)), and that will - duplicate the (a +# b) primop, which we should not do lightly. - (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) --} +-------------------- +exprIsCheap :: CoreExpr -> Bool +-- See Note [exprIsCheap] +exprIsCheap e = exprIsCheapX isCheapApp False e -------------------------------------- +-------------------- exprIsExpandable :: CoreExpr -> Bool -- See Note [exprIsExpandable] -exprIsExpandable e - = ok e - where - ok e = go 0 e - - -- n is the number of value arguments - go n (Var v) = isExpandableApp v n - go _ (Lit {}) = True - go _ (Type {}) = True - go _ (Coercion {}) = True - go n (Cast e _) = go n e - go n (Tick t e) | tickishCounts t = False - | otherwise = go n e - go n (Lam x e) | isRuntimeVar x = n==0 || go (n-1) e - | otherwise = go n e - go n (App f e) | isRuntimeArg e = go (n+1) f && ok e - | otherwise = go n f - go _ (Case {}) = False - go _ (Let {}) = False - - -------------------------------------- -type CheapAppFun = Id -> Arity -> Bool - -- Is an application of this function to n *value* args - -- always cheap, assuming the arguments are cheap? - -- True mainly of data constructors, partial applications; - -- but with minor variations: - -- isWorkFreeApp - -- isCheapApp +exprIsExpandable e = exprIsCheapX isExpandableApp True e isWorkFreeApp :: CheapAppFun isWorkFreeApp fn n_val_args @@ -1626,7 +1567,7 @@ isCheapApp fn n_val_args | isDeadEndId fn = True -- See Note [isCheapApp: bottoming functions] | otherwise = case idDetails fn of - DataConWorkId {} -> True -- Actually handled by isWorkFreeApp + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId op _ -> primOpIsCheap op @@ -1641,6 +1582,7 @@ isExpandableApp fn n_val_args | isWorkFreeApp fn n_val_args = True | otherwise = case idDetails fn of + -- DataConWorkId {} -> _ -- Handled by isWorkFreeApp RecSelId {} -> n_val_args == 1 -- See Note [Record selection] ClassOpId {} -> n_val_args == 1 PrimOpId {} -> False @@ -1672,6 +1614,50 @@ isExpandableApp fn n_val_args I'm not sure why we have a special case for bottoming functions in isCheapApp. Maybe we don't need it. +Note [exprIsExpandable] +~~~~~~~~~~~~~~~~~~~~~~~ +An expression is "expandable" if we are willing to duplicate it, if doing +so might make a RULE or case-of-constructor fire. Consider + let x = (a,b) + y = build g + in ....(case x of (p,q) -> rhs)....(foldr k z y).... + +We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold), +but we do want + + * the case-expression to simplify + (via exprIsConApp_maybe, exprIsLiteral_maybe) + + * the foldr/build RULE to fire + (by expanding the unfolding during rule matching) + +So we classify the unfolding of a let-binding as "expandable" (via the +uf_expandable field) if we want to do this kind of on-the-fly +expansion. Specifically: + +* True of constructor applications (K a b) + +* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic. + (NB: exprIsCheap might not be true of this) + +* False of case-expressions. If we have + let x = case ... in ...(case x of ...)... + we won't simplify. We have to inline x. See #14688. + +* False of let-expressions (same reason); and in any case we + float lets out of an RHS if doing so will reveal an expandable + application (see SimplEnv.doFloatFromRhs). + +* Take care: exprIsExpandable should /not/ be true of primops. I + found this in test T5623a: + let q = /\a. Ptr a (a +# b) + in case q @ Float of Ptr v -> ...q... + + q's inlining should not be expandable, else exprIsConApp_maybe will + say that (q @ Float) expands to (Ptr a (a +# b)), and that will + duplicate the (a +# b) primop, which we should not do lightly. + (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.) + Note [isExpandableApp: bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's important that isExpandableApp does not respond True to bottoming @@ -1852,7 +1838,7 @@ expr_ok fun_ok primop_ok other_expr _ -> False ----------------------------- -app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool +app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreArg] -> Bool app_ok fun_ok primop_ok fun args | not (fun_ok fun) = False -- This code path is only taken for Note [Speculative evaluation] @@ -1867,13 +1853,11 @@ app_ok fun_ok primop_ok fun args -- DFuns terminate, unless the dict is implemented -- with a newtype in which case they may not - DataConWorkId {} -> args_ok - -- The strictness of the constructor has already - -- been expressed by its "wrapper", so we don't need - -- to take the arguments into account - -- Well, we thought so. But it's definitely wrong! - -- See #20749 and Note [How untagged pointers can - -- end up in strict fields] in GHC.Stg.InferTags + DataConWorkId dc + | isLazyDataConRep dc + -> args_ok + | otherwise + -> fields_ok (dataConRepStrictness dc) ClassOpId _ is_terminating_result | is_terminating_result -- See Note [exprOkForSpeculation and type classes] @@ -1923,7 +1907,7 @@ app_ok fun_ok primop_ok fun args -- Even if a function call itself is OK, any unlifted -- args are still evaluated eagerly and must be checked - args_ok = and (zipWith arg_ok arg_tys args) + args_ok = all2Prefix arg_ok arg_tys args arg_ok :: PiTyVarBinder -> CoreExpr -> Bool arg_ok (Named _) _ = True -- A type argument arg_ok (Anon ty _) arg -- A term argument @@ -1932,6 +1916,17 @@ app_ok fun_ok primop_ok fun args | otherwise = expr_ok fun_ok primop_ok arg + -- Used for DataCon worker arguments + fields_ok str_marks = all3Prefix field_ok arg_tys str_marks args + field_ok :: PiTyVarBinder -> StrictnessMark -> CoreExpr -> Bool + field_ok (Named _) _ _ = True + field_ok (Anon ty _) str arg + | NotMarkedStrict <- str -- iff it's a lazy field + , definitelyLiftedType (scaledThing ty) -- and its type is lifted + = True -- then the worker app does not eval + | otherwise + = expr_ok fun_ok primop_ok arg + ----------------------------- altsAreExhaustive :: [Alt b] -> Bool -- True <=> the case alternatives are definitely exhaustive @@ -2157,12 +2152,14 @@ exprIsConLike = exprIsHNFlike isConLikeId isConLikeUnfolding -- or PAPs. -- exprIsHNFlike :: HasDebugCallStack => (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool -exprIsHNFlike is_con is_con_unf = is_hnf_like +exprIsHNFlike is_con is_con_unf e + = -- pprTraceWith "hnf" (\r -> ppr r <+> ppr e) $ + is_hnf_like e where is_hnf_like (Var v) -- NB: There are no value args at this point - = id_app_is_value v 0 -- Catches nullary constructors, - -- so that [] and () are values, for example - -- and (e.g.) primops that don't have unfoldings + = id_app_is_value v [] -- Catches nullary constructors, + -- so that [] and () are values, for example + -- and (e.g.) primops that don't have unfoldings || is_con_unf (idUnfolding v) -- Check the thing's unfolding; it might be bound to a value -- or to a guaranteed-evaluated variable (isEvaldUnfolding) @@ -2186,7 +2183,7 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like -- See Note [exprIsHNF Tick] is_hnf_like (Cast e _) = is_hnf_like e is_hnf_like (App e a) - | isValArg a = app_is_value e 1 + | isValArg a = app_is_value e [a] | otherwise = is_hnf_like e is_hnf_like (Let _ e) = is_hnf_like e -- Lazy let(rec)s don't affect us is_hnf_like (Case e b _ as) @@ -2194,26 +2191,64 @@ exprIsHNFlike is_con is_con_unf = is_hnf_like = is_hnf_like rhs is_hnf_like _ = False - -- 'n' is the number of value args to which the expression is applied - -- And n>0: there is at least one value argument - app_is_value :: CoreExpr -> Int -> Bool - app_is_value (Var f) nva = id_app_is_value f nva - app_is_value (Tick _ f) nva = app_is_value f nva - app_is_value (Cast f _) nva = app_is_value f nva - app_is_value (App f a) nva - | isValArg a = - app_is_value f (nva + 1) && - not (needsCaseBinding (exprType a) a) - -- For example f (x /# y) where f has arity two, and the first - -- argument is unboxed. This is not a value! - -- But f 34# is a value. - -- NB: Check app_is_value first, the arity check is cheaper - | otherwise = app_is_value f nva - app_is_value _ _ = False - - id_app_is_value id n_val_args - = is_con id - || idArity id > n_val_args + -- Collect arguments through Casts and Ticks and call id_app_is_value + app_is_value :: CoreExpr -> [CoreArg] -> Bool + app_is_value (Var f) as = id_app_is_value f as + app_is_value (Tick _ f) as = app_is_value f as + app_is_value (Cast f _) as = app_is_value f as + app_is_value (App f a) as | isValArg a = app_is_value f (a:as) + | otherwise = app_is_value f as + app_is_value _ _ = False + + id_app_is_value id val_args = + case compare (idArity id) (length val_args) of + EQ | is_con id -> -- Saturated app of a DataCon/CONLIKE Id + case mb_str_marks id of + Just str_marks -> -- with strict fields + assert (val_args `equalLength` str_marks) $ + fields_hnf str_marks + Nothing -> -- without strict fields: like PAP + args_hnf -- NB: CONLIKEs are lazy! + + GT -> -- PAP: Check unlifted val_args + args_hnf + + _ -> False + + where + -- Saturated, Strict DataCon: Check unlifted val_args and strict fields + fields_hnf str_marks = all3Prefix check_field val_arg_tys str_marks val_args + + -- PAP: Check unlifted val_args + args_hnf = all2Prefix check_arg val_arg_tys val_args + + fun_ty = idType id + val_arg_tys = mapMaybe anonPiTyBinderType_maybe (collectPiTyBinders fun_ty) + -- val_arg_tys = map exprType val_args, but much less costly. + -- The obvious definition regresses T16577 by 30% so we don't do it. + + check_arg a_ty a + | mightBeUnliftedType a_ty = exprOkForSpeculation a -- is_hnf_like a + | otherwise = True + -- Check unliftedness; for example f (x /# 12#) where f has arity two, + -- and the first argument is unboxed. This is not a value! + -- But f 34# is a value, so check args for HNFs. + -- NB: We check arity (and CONLIKEness) first because it's cheaper + -- and we reject quickly on saturated apps. + check_field a_ty str a + | mightBeUnliftedType a_ty = exprOkForSpeculation a -- is_hnf_like a + | isMarkedStrict str = is_hnf_like a + | otherwise = True + -- isMarkedStrict: Respect Note [Strict fields in Core] + + mb_str_marks id + | Just dc <- isDataConWorkId_maybe id + , not (isLazyDataConRep dc) + = Just (dataConRepStrictness dc) + | otherwise + = Nothing + +{-# INLINE exprIsHNFlike #-} {- Note [exprIsHNF Tick] @@ -2775,7 +2810,7 @@ This means the seqs on x and y both become no-ops and compared to the first vers The downside is that the caller of $wfoo potentially has to evaluate `y` once if we can't prove it isn't already evaluated. But y coming out of a strict field is in WHNF so safe to evaluated. And most of the time it will be properly tagged+evaluated -already at the call site because of the Strict Field Invariant! See Note [Strict Field Invariant] for more in this. +already at the call site because of the Strict Field Invariant! See Note [STG Strict Field Invariant] for more in this. This makes GHC itself around 1% faster despite doing slightly more work! So this is generally quite good. We only apply this when we think there is a benefit in doing so however. There are a number of cases in which ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -630,11 +630,10 @@ cpeBind :: TopLevelFlag -> CorePrepEnv -> CoreBind cpeBind top_lvl env (NonRec bndr rhs) | not (isJoinId bndr) = do { (env1, bndr1) <- cpCloneBndr env bndr - ; let dmd = idDemandInfo bndr - is_unlifted = isUnliftedType (idType bndr) + ; let dmd = idDemandInfo bndr + lev = typeLevity (idType bndr) ; (floats, rhs1) <- cpePair top_lvl NonRecursive - dmd is_unlifted - env bndr1 rhs + dmd lev env bndr1 rhs -- See Note [Inlining in CorePrep] ; let triv_rhs = exprIsTrivial rhs1 env2 | triv_rhs = extendCorePrepEnvExpr env1 bndr rhs1 @@ -644,7 +643,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = snocFloat floats new_float - new_float = mkNonRecFloat env is_unlifted bndr1 rhs1 + (new_float, _bndr2) = mkNonRecFloat env lev bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -660,7 +659,7 @@ cpeBind top_lvl env (Rec pairs) | not (isJoinId (head bndrs)) = do { (env, bndrs1) <- cpCloneBndrs env bndrs ; let env' = enterRecGroupRHSs env bndrs1 - ; stuff <- zipWithM (cpePair top_lvl Recursive topDmd False env') + ; stuff <- zipWithM (cpePair top_lvl Recursive topDmd Lifted env') bndrs1 rhss ; let (zipManyFloats -> floats, rhss1) = unzip stuff @@ -709,12 +708,12 @@ cpeBind top_lvl env (Rec pairs) --------------- -cpePair :: TopLevelFlag -> RecFlag -> Demand -> Bool +cpePair :: TopLevelFlag -> RecFlag -> Demand -> Levity -> CorePrepEnv -> OutId -> CoreExpr -> UniqSM (Floats, CpeRhs) -- Used for all bindings -- The binder is already cloned, hence an OutId -cpePair top_lvl is_rec dmd is_unlifted env bndr rhs +cpePair top_lvl is_rec dmd lev env bndr rhs = assert (not (isJoinId bndr)) $ -- those should use cpeJoinPair do { (floats1, rhs1) <- cpeRhsE env rhs @@ -729,9 +728,9 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkNonRecFloat env False v rhs2 + ; let (float, v') = mkNonRecFloat env Lifted v rhs2 ; return ( snocFloat floats2 float - , cpeEtaExpand arity (Var v)) }) + , cpeEtaExpand arity (Var v')) }) -- Wrap floating ticks ; let (floats4, rhs4) = wrapTicks floats3 rhs3 @@ -742,7 +741,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs want_float_from_rhs floats rhs | isTopLevel top_lvl = wantFloatTop floats - | otherwise = wantFloatLocal is_rec dmd is_unlifted floats rhs + | otherwise = wantFloatLocal is_rec dmd lev floats rhs {- Note [Silly extra arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -908,8 +907,7 @@ cpeRhsE env (Case scrut bndr ty alts) ; case alts'' of [Alt DEFAULT _ rhs] -- See Note [Flatten case-binds] - | let is_unlifted = isUnliftedType (idType bndr2) - , let float = mkCaseFloat is_unlifted bndr2 scrut' + | let float = mkCaseFloat bndr2 scrut' -> return (snocFloat floats float, rhs) _ -> return (floats, Case scrut' bndr2 (cpSubstTy env ty) alts'') } where @@ -1148,8 +1146,7 @@ cpeApp top_env expr ; (floats2, thing) <- cpeBody env thing ; case_bndr <- newVar ty ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] - ; let is_unlifted = False -- otherwise seq# would not type-check - ; let float = mkCaseFloat is_unlifted case_bndr thing + ; let float = mkCaseFloat case_bndr thing ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } cpe_app env (Var v) args @@ -1553,9 +1550,9 @@ cpeArg :: CorePrepEnv -> Demand -> CoreArg -> UniqSM (Floats, CpeArg) cpeArg env dmd arg = do { (floats1, arg1) <- cpeRhsE env arg -- arg1 can be a lambda - ; let arg_ty = exprType arg1 - is_unlifted = isUnliftedType arg_ty - dec = wantFloatLocal NonRecursive dmd is_unlifted floats1 arg1 + ; let arg_ty = exprType arg1 + lev = typeLevity arg_ty + dec = wantFloatLocal NonRecursive dmd lev floats1 arg1 ; (floats2, arg2) <- executeFloatDecision dec floats1 arg1 -- Else case: arg1 might have lambdas, and we can't -- put them inside a wrapBinds @@ -1570,8 +1567,9 @@ cpeArg env dmd arg ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 -- See Note [Eta expansion of arguments in CorePrep] - ; let arg_float = mkNonRecFloat env is_unlifted v arg3 - ; return (snocFloat floats2 arg_float, varToCoreExpr v) } + ; let (arg_float, v') = mkNonRecFloat env lev v arg3 + ---; pprTraceM "cpeArg" (ppr arg1 $$ ppr dec $$ ppr arg2) + ; return (snocFloat floats2 arg_float, varToCoreExpr v') } } cpeArgArity :: CorePrepEnv -> FloatDecision -> Floats -> CoreArg -> Arity @@ -1793,10 +1791,10 @@ cpeEtaExpand arity expr Note [Pin demand info on floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We pin demand info on floated lets, so that we can see the one-shot thunks. +We pin demand info on floated lets, so that we can see one-shot thunks. For example, f (g x) -where `f` uses its argument at least once, creates a Float for `y = g x` and we +where `f` uses its argument at most once, creates a Float for `y = g x` and we should better pin appropriate demand info on `y`. Note [Flatten case-binds] @@ -1807,7 +1805,7 @@ Suppose we have the following call, where f is strict: `case` out because `f` is strict.) In Prep, `cpeArg` will ANF-ise that argument, and we'll get a `FloatingBind` - Float (a = case x of y { DEFAULT -> blah }) CaseBound top_lvl + Float (a = case x of y { DEFAULT -> blah }) CaseBound top-lvl with the call `f a`. When we wrap that `Float` we will get @@ -1826,8 +1824,8 @@ This is easy to avoid: turn that into a FloatingBind of its own. This is easily done in the Case equation for `cpsRhsE`. Then our example will generate /two/ floats: - Float (y = x) CaseBound top_lvl - Float (a = blah) CaseBound top_lvl + Float (y = x) CaseBound str-ctx + Float (a = blah) CaseBound top-lvl and we'll end up with nested cases. @@ -1840,6 +1838,124 @@ Of course, the Simplifier never leaves us with an argument like this, but we and the above footwork in cpsRhsE avoids generating a nested case. +Note [Pin evaluatedness on floats] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider a call to a CBV function, such as a DataCon worker with *strict* fields, +in a *lazy* context, such as in the arg of a lazy function call to `f`: + + + data Box a = Box !a + ... f (Box e) ... -- f lazy, Box strict + +(A live example of this is T24730, inspired by $walexGetByte.) +During ANFisation, we will `mkNonRecFloat` for `e`, binding it to a +fresh binder `sat`, and binding `Box sat` as well to a fresh binder `sat2`. +We want to avoid allocating a thunk for `sat2` as often as possible, building +on the let floating mechanism in Case (2) of Note [wantFloatLocal]. + +Note that this mechanism requires `sat` to be detected as a value after +floating out any ok-for-spec floats, according to `exprIsHNF`. This means we +need an `evaldUnfolding` on `sat`, and `mkNonRecFloat` must do the pinning. + +There are two interesting cases: + + 1. When `e = I# (x +# 1#)`, we decompose into + case x +# 1# of x' -> + --- + I# x' + where everything above --- are floats and below --- is the residual RHS. + Here, `I# x'` is a value because `x'` is (NB: x' is a variable of unlifted type). + Following Case (2) of Note [wantFloatLocal], we want to float out the + ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's + field, to get + case x +# 1# of x' -> + let sat = I# x' in + --- + Box sat + And since we pin an `evaldUnfolding` on `sat`, we may even float out of + `f`'s lazy argument, again by Case (2) of Note [wantFloatLocal] + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 + If `sat` didn't have the `evaldUnfolding`, we'd get a large thunk in f's arg: + let sat2 = + case x +# 1# of x' -> + let sat = I# x' in + Box sat in + f sat2 + 2. + +Although `e` might not be a value, it might still decompose into floats that are +ok-for-spec and a value, for example + e = I# (x +# 1#) +decomposes into +Following Case (2) of Note [wantFloatLocal], we want to float out the +ok-for-spec `x +# 1#` computation in order not to allocate a thunk for Box's +field, to get + case x +# 1# of x' -> + let sat = I# x' in + Box sat +Nice! But now we want to do the same for the argument to `f`, to get + case x +# 1# of x' -> + let sat = I# x' in + let sat2 = Box sat in + f sat2 +(NB: Since all floats are ok-for-spec, we may float out of the lazy argument.) +BUT, in order to do that in Case (2) of Note [wantFloatLocal], we must detect +`Box sat` as a value according to `exprIsHNF`; otherwise floating would be +unproductive. Crucially, this means we need `sat` to look evaluated, because +it ends up in a strict field. +We achieve this by attaching and `evaldUnfolding` to `sat` in `mkNonRecFloat`. + +*When + + 1. When `e=Just y` is a value, we will float `sat=Just y` as far as possible, + to top-level, even. It is important that we mark `sat` as evaluated (via + setting its unfolding to `evaldUnfolding`), otherwise we get a superfluous + thunk to carry out the field seq on Box's field, because + `exprIsHNF sat == False`: + + let sat = Just y in + let sat2 = case sat of x { __DEFAULT } -> Box x in + -- NONONO, want just `sat2 = Box x` + f sat2 + + This happened in $walexGetByte, where the thunk caused additional + allocation. + + 2. Similarly, when `e` is not a value, we still know that it is strictly + evaluated. Hence it is going to be case-bound, and we anticipate that `sat` + will be a case binder which is *always* evaluated. + Hence in this case, we also mark `sat` as evaluated via its unfolding. + This happened in GHC.Linker.Deps.$wgetLinkDeps, where without + `evaldUnfolding` we ended up with this: + + Word64Map = ... | Bin ... ... !Word64Map !Word64Map + case ... of { Word64Map.Bin a b l r -> + case insert ... of sat { __DEFAULT -> + case Word64Map.Bin a b l sat of sat2 { __DEFAULT -> + f sat2 + }}} + + Note that *the DataCon app `Bin a b l sat` was case-bound*, because it was + not detected to be a value according to `exprIsHNF`. + That is because the strict field `sat` lacked the `evaldUnfolding`, + although it ended up being case-bound. + + Small wrinkle: + It could be that `sat=insert ...` floats to top-level, where it is not + eagerly evaluated. In this case, we may not give `sat` an `evaldUnfolding`. + We detect this case by looking at the `FloatInfo` of `sat=insert ...`: If + it says `TopLvlFloatable`, we are conservative and will not give `sat` an + `evaldUnfolding`. + +TLDR; when creating a new float `sat=e` in `mkNonRecFloat`, propagate `sat` with +an `evaldUnfolding` if either + + 1. `e` is a value, or + 2. `sat=e` is case-bound, but won't float to top-level. + Note [Speculative evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since call-by-value is much cheaper than call-by-need, we case-bind arguments @@ -2121,64 +2237,94 @@ zipFloats = appFloats zipManyFloats :: [Floats] -> Floats zipManyFloats = foldr zipFloats emptyFloats -mkCaseFloat :: Bool -> Id -> CpeRhs -> FloatingBind -mkCaseFloat is_unlifted bndr scrut - = Float (NonRec bndr scrut) bound info +data FloatInfoArgs + = FIA + { fia_levity :: Levity + , fia_demand :: Demand + , fia_is_hnf :: Bool + , fia_is_string :: Bool + , fia_is_dc_worker :: Bool + , fia_ok_for_spec :: Bool + } + +defFloatInfoArgs :: Id -> CoreExpr -> FloatInfoArgs +defFloatInfoArgs bndr rhs + = FIA + { fia_levity = typeLevity (idType bndr) + , fia_demand = idDemandInfo bndr -- mkCaseFloat uses evalDmd + , fia_is_hnf = exprIsHNF rhs + , fia_is_string = exprIsTickedString rhs + , fia_is_dc_worker = isJust (isDataConId_maybe bndr) -- mkCaseFloat uses False + , fia_ok_for_spec = False -- mkNonRecFloat uses exprOkForSpecEval + } + +decideFloatInfo :: FloatInfoArgs -> (BindInfo, FloatInfo) +decideFloatInfo FIA{fia_levity=lev, fia_demand=dmd, fia_is_hnf=is_hnf, + fia_is_string=is_string, fia_is_dc_worker=is_dc_worker, + fia_ok_for_spec=ok_for_spec} + | Lifted <- lev, is_hnf = (LetBound, TopLvlFloatable) + -- is_lifted: We currently don't allow unlifted values at the + -- top-level or inside letrecs + -- (but SG thinks that in principle, we should) + | is_dc_worker = (LetBound, TopLvlFloatable) + -- We need this special case for nullary unlifted DataCon + -- workers/wrappers (top-level bindings) until #17521 is fixed + | is_string = (CaseBound, TopLvlFloatable) + -- String literals are unboxed (so must be case-bound) and float to + -- the top-level + | ok_for_spec = (CaseBound, case lev of Unlifted -> LazyContextFloatable + Lifted -> TopLvlFloatable) + -- See Note [Speculative evaluation] + -- Ok-for-spec-eval things will be case-bound, lifted or not. + -- But when it's lifted we are ok with floating it to top-level + -- (where it is actually bound lazily). + | Unlifted <- lev = (CaseBound, StrictContextFloatable) + | isStrUsedDmd dmd = (CaseBound, StrictContextFloatable) + -- These will never be floated out of a lazy RHS context + | Lifted <- lev = (LetBound, TopLvlFloatable) + -- And these float freely but can't be speculated, hence LetBound + +mkCaseFloat :: Id -> CpeRhs -> FloatingBind +mkCaseFloat bndr scrut + = -- pprTrace "mkCaseFloat" (ppr bndr <+> ppr (bound,info) + -- -- <+> ppr is_lifted <+> ppr is_strict + -- -- <+> ppr ok_for_spec <+> ppr evald + -- $$ ppr scrut) $ + Float (NonRec bndr scrut) bound info where - (bound, info) -{- -Eventually we want the following code, when #20749 is fixed. - | is_lifted, is_hnf = (LetBound, TopLvlFloatable) - -- `seq# (case x of x' { __DEFAULT -> StrictBox x' }) s` should - -- let-bind `StrictBox x'` after Note [Flatten case-binds]. --} - | exprIsTickedString scrut = (CaseBound, TopLvlFloatable) - -- String literals are unboxed (so must be case-bound) and float to - -- the top-level - | otherwise = (CaseBound, StrictContextFloatable) - -- For a Case, we never want to drop the eval; hence no need to test - -- for ok-for-spec-eval - _is_lifted = not is_unlifted - _is_hnf = exprIsHNF scrut - -mkNonRecFloat :: CorePrepEnv -> Bool -> Id -> CpeRhs -> FloatingBind -mkNonRecFloat env is_unlifted bndr rhs + !(bound, info) = decideFloatInfo $ (defFloatInfoArgs bndr scrut) + { fia_demand = evalDmd + -- Strict demand, so that we do not let-bind unless it's a value + , fia_is_dc_worker = False + -- DataCon worker *bindings* are never case-bound + , fia_ok_for_spec = False + -- We do not currently float around case bindings. + -- (ok-for-spec case bindings are unlikely anyway.) + } + +mkNonRecFloat :: CorePrepEnv -> Levity -> Id -> CpeRhs -> (FloatingBind, Id) +mkNonRecFloat env lev bndr rhs = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info) - -- <+> ppr is_lifted <+> ppr is_strict - -- <+> ppr ok_for_spec + -- <+> if is_strict then text "strict" else if is_lifted then text "lazy" else text "unlifted" + -- <+> if ok_for_spec then text "ok-for-spec" else empty + -- <+> if evald then text "evald" else empty -- $$ ppr rhs) $ - Float (NonRec bndr rhs) bound info + (Float (NonRec bndr' rhs) bound info, bndr') where - (bound, info) - | is_lifted, is_hnf = (LetBound, TopLvlFloatable) - -- is_lifted: We currently don't allow unlifted values at the - -- top-level or inside letrecs - -- (but SG thinks that in principle, we should) - | is_data_con bndr = (LetBound, TopLvlFloatable) - -- We need this special case for nullary unlifted DataCon - -- workers/wrappers (top-level bindings) until #17521 is fixed - | exprIsTickedString rhs = (CaseBound, TopLvlFloatable) - -- String literals are unboxed (so must be case-bound) and float to - -- the top-level - | is_unlifted, ok_for_spec = (CaseBound, LazyContextFloatable) - | is_lifted, ok_for_spec = (CaseBound, TopLvlFloatable) - -- See Note [Speculative evaluation] - -- Ok-for-spec-eval things will be case-bound, lifted or not. - -- But when it's lifted we are ok with floating it to top-level - -- (where it is actually bound lazily). - | is_unlifted || is_strict = (CaseBound, StrictContextFloatable) - -- These will never be floated out of a lazy RHS context - | otherwise = assertPpr is_lifted (ppr rhs) $ - (LetBound, TopLvlFloatable) - -- And these float freely but can't be speculated, hence LetBound - - is_lifted = not is_unlifted + !(bound, info) = decideFloatInfo $ (defFloatInfoArgs bndr rhs) + { fia_levity = lev + , fia_is_hnf = is_hnf + , fia_ok_for_spec = ok_for_spec + } + is_hnf = exprIsHNF rhs - dmd = idDemandInfo bndr - is_strict = isStrUsedDmd dmd ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs is_rec_call = (`elemUnVarSet` cpe_rec_ids env) - is_data_con = isJust . isDataConId_maybe + + -- See Note [Pin evaluatedness on floats] + evald = is_hnf --- || (bound == CaseBound && info /= TopLvlFloatable) + bndr' | evald = bndr `setIdUnfolding` evaldUnfolding + | otherwise = bndr -- | Wrap floats around an expression wrapBinds :: Floats -> CpeBody -> CpeBody @@ -2285,6 +2431,10 @@ data FloatDecision = FloatNone | FloatAll +instance Outputable FloatDecision where + ppr FloatNone = text "none" + ppr FloatAll = text "all" + executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) executeFloatDecision dec floats rhs = case dec of @@ -2302,12 +2452,12 @@ wantFloatTop fs | fs_info fs `floatsAtLeastAsFarAs` TopLvlFloatable = FloatAll | otherwise = FloatNone -wantFloatLocal :: RecFlag -> Demand -> Bool -> Floats -> CpeRhs -> FloatDecision +wantFloatLocal :: RecFlag -> Demand -> Levity -> Floats -> CpeRhs -> FloatDecision -- See Note [wantFloatLocal] -wantFloatLocal is_rec rhs_dmd rhs_is_unlifted floats rhs +wantFloatLocal is_rec rhs_dmd rhs_lev floats rhs | isEmptyFloats floats -- Well yeah... || isStrUsedDmd rhs_dmd -- Case (1) of Note [wantFloatLocal] - || rhs_is_unlifted -- dito + || rhs_lev == Unlifted -- dito || (fs_info floats `floatsAtLeastAsFarAs` max_float_info && exprIsHNF rhs) -- Case (2) of Note [wantFloatLocal] = FloatAll @@ -2706,7 +2856,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do let litAddrRhs = Lit (LitString words) -- not "mkLitString"; that does UTF-8 encoding, which we don't want here - litAddrFloat = mkNonRecFloat env True litAddrId litAddrRhs + (litAddrFloat, litAddrId') = mkNonRecFloat env Unlifted litAddrId litAddrRhs contentsLength = mkIntLit platform (toInteger (BS.length words)) @@ -2719,7 +2869,7 @@ cpeBigNatLit env i = assert (i >= 0) $ do copyContentsCall = Var (primOpId CopyAddrToByteArrayOp) `App` Type realWorldTy - `App` Var litAddrId + `App` Var litAddrId' `App` Var mutableByteArrayId `App` mkIntLit platform 0 `App` contentsLength ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -64,8 +64,8 @@ With nofib being ~0.3% faster as well. See Note [Tag inference passes] for how we proceed to generate and use this information. -Note [Strict Field Invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [STG Strict Field Invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As part of tag inference we introduce the Strict Field Invariant. Which consists of us saying that: @@ -81,7 +81,7 @@ and will be tagged with `001` or `010` respectively. It will never point to a thunk, nor will it be tagged `000` (meaning "might be a thunk"). NB: Note that the proper tag for some objects is indeed `000`. Currently this is the case for PAPs. -This works analogous to how `WorkerLikeId`s work. See also Note [CBV Function Ids]. +This works analogous to how CBV functions work. See also Note [CBV Function Ids]. Why do we care? Because if we have code like: @@ -103,7 +103,7 @@ where we: * If not we convert `StrictJust x` into `case x of x' -> StrictJust x'` This is usually very beneficial but can cause regressions in rare edge cases where -we fail to proof that x is properly tagged, or where it simply isn't. +we fail to prove that x is properly tagged, or where it simply isn't. See Note [How untagged pointers can end up in strict fields] for how the second case can arise. @@ -124,15 +124,33 @@ Note that there are similar constraints around Note [CBV Function Ids]. Note [How untagged pointers can end up in strict fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Since the resolution of #20749 where Core passes assume that DataCon workers +evaluate their strict fields, it is pretty simple to see how the Simplifier +might exploit that knowledge to drop evals. Example: + + data T a = MkT !a + f :: [Int] -> T [Int] + f xs = xs `seq` MkT xs + +in Core we will have + + f = \xs -> MkT @[Int] xs + +No eval left there. + Consider data Set a = Tip | Bin !a (Set a) (Set a) We make a wrapper for Bin that evaluates its arguments $WBin x a b = case x of xv -> Bin xv a b Here `xv` will always be evaluated and properly tagged, just as the -Strict Field Invariant requires. +Note [STG Strict Field Invariant] requires. + +But alas, the Simplifier can destroy the invariant: see #15696. +Indeed, as Note [Strict fields in Core] explains, Core passes +assume that Data constructor workers evaluate their strict fields, +so the Simplifier will drop seqs freely. -But alas the Simplifier can destroy the invariant: see #15696. We start with thk = f () g x = ...(case thk of xv -> Bin xv Tip Tip)... @@ -153,7 +171,7 @@ Now you can see that the argument of Bin, namely thk, points to the thunk, not to the value as it did before. In short, although it may be rare, the output of optimisation passes -cannot guarantee to obey the Strict Field Invariant. For this reason +cannot guarantee to obey the Note [STG Strict Field Invariant]. For this reason we run tag inference. See Note [Tag inference passes]. Note [Tag inference passes] @@ -163,7 +181,7 @@ Tag inference proceeds in two passes: The result is then attached to /binders/. This is implemented by `inferTagsAnal` in GHC.Stg.InferTags * The second pass walks over the AST checking if the Strict Field Invariant is upheld. - See Note [Strict Field Invariant]. + See Note [STG Strict Field Invariant]. If required this pass modifies the program to uphold this invariant. Tag information is also moved from /binders/ to /occurrences/ during this pass. This is done by `GHC.Stg.InferTags.Rewrite (rewriteTopBinds)`. ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -57,7 +57,7 @@ The work of this pass is simple: * For any strict field we check if the argument is known to be properly tagged. * If it's not known to be properly tagged, we wrap the whole thing in a case, which will force the argument before allocation. -This is described in detail in Note [Strict Field Invariant]. +This is described in detail in Note [STG Strict Field Invariant]. The only slight complication is that we have to make sure not to invalidate free variable analysis in the process. @@ -210,7 +210,7 @@ When compiling bytecode we call myCoreToStg to get STG code first. myCoreToStg in turn calls out to stg2stg which runs the STG to STG passes followed by free variables analysis and the tag inference pass including its rewriting phase at the end. -Running tag inference is important as it upholds Note [Strict Field Invariant]. +Running tag inference is important as it upholds Note [STG Strict Field Invariant]. While code executed by GHCi doesn't take advantage of the SFI it can call into compiled code which does. So it must still make sure that the SFI is upheld. See also #21083 and #22042. ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -884,7 +884,7 @@ mostly relating to under what circumstances it evaluates its argument. Today, that story is simple: A dataToTag primop always evaluates its argument, unless tag inference determines the argument was already evaluated and correctly tagged. Getting here was a long journey, with -many similarities to the story behind Note [Strict Field Invariant] in +many similarities to the story behind Note [STG Strict Field Invariant] in GHC.Stg.InferTags. See also #15696. -} ===================================== compiler/GHC/Tc/TyCl/Build.hs ===================================== @@ -183,14 +183,15 @@ buildDataCon fam_envs dc_bang_opts src_name declared_infix prom_info src_bangs tag = lookupNameEnv_NF tag_map src_name -- See Note [Constructor tag allocation], fixes #14657 data_con = mkDataCon src_name declared_infix prom_info - src_bangs field_lbls + src_bangs impl_bangs str_marks field_lbls univ_tvs ex_tvs noConcreteTyVars user_tvbs eq_spec ctxt arg_tys res_ty NoPromInfo rep_tycon tag stupid_ctxt dc_wrk dc_rep dc_wrk = mkDataConWorkId work_name data_con - dc_rep = initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) + (dc_rep, impl_bangs, str_marks) = + initUs_ us (mkDataConRep dc_bang_opts fam_envs wrap_name data_con) ; traceIf (text "buildDataCon 2" <+> ppr src_name) ; return data_con } ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1391,33 +1391,16 @@ arguments. That is the job of dmdTransformDataConSig. More precisely, * it returns the demands on the arguments; in the above example that is [SL, A] -Nasty wrinkle. Consider this code (#22475 has more realistic examples but -assume this is what the demand analyser sees) - - data T = MkT !Int Bool - get :: T -> Bool - get (MkT _ b) = b - - foo = let v::Int = I# 7 - t::T = MkT v True - in get t - -Now `v` is unused by `get`, /but/ we can't give `v` an Absent demand, -else we'll drop the binding and replace it with an error thunk. -Then the code generator (more specifically GHC.Stg.InferTags.Rewrite) -will add an extra eval of MkT's argument to give - foo = let v::Int = error "absent" - t::T = case v of v' -> MkT v' True - in get t - -Boo! Because of this extra eval (added in STG-land), the truth is that `MkT` -may (or may not) evaluate its arguments (as established in #21497). Hence the -use of `bump` in dmdTransformDataConSig, which adds in a `C_01` eval. The -`C_01` says "may or may not evaluate" which is absolutely faithful to what -InferTags.Rewrite does. - -In particular it is very important /not/ to make that a `C_11` eval, -see Note [Data-con worker strictness]. +When the data constructor worker has strict fields, an additional seq +will be inserted for each field (Note [Strict fields in Core]). +Hence we add an additional `seqDmd` for each strict field to emulate +field seq insertion. + +For example, consider `data SP a b = MkSP !a !b` and expression `MkSP x y`, +with the same sub-demand P(SL,A). +The strict fields bump up the strictness; we'd get [SL,1!A] for the field +demands. Note that the first demand was unaffected by the seq, whereas +the second, previously absent demand became `seqDmd` exactly. -} {- ********************************************************************* @@ -1617,6 +1600,29 @@ a bad fit because expression may not throw a precise exception (increasing precision of the analysis), but that's just a favourable guess. +Note [Side-effects and strictness] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Due to historic reasons and the continued effort not to cause performance +regressions downstream, Strictness Analysis is currently prone to discarding +observable side-effects (other than precise exceptions, see +Note [Precise exceptions and strictness analysis]) in some cases. For example, + f :: MVar () -> Int -> IO Int + f mv x = putMVar mv () >> (x `seq` return x) +The call to `putMVar` is an observable side-effect. Yet, Strictness Analysis +currently concludes that `f` is strict in `x` and uses call-by-value. +That means `f mv (error "boom")` will error out with the imprecise exception +rather performing the side-effect. + +This is a conscious violation of the semantics described in the paper +"a semantics for imprecise exceptions"; so it would be great if we could +identify the offending primops and extend the idea in +Note [Which scrutinees may throw precise exceptions] to general side-effects. + +Unfortunately, the existing has-side-effects classification for primops is +too conservative, listing `writeMutVar#` and even `readMutVar#` as +side-effecting. That is due to #3207. A possible way forward is described in +#17900, but no effort has been so far towards a resolution. + Note [Exceptions and strictness] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to smart about catching exceptions, but we aren't anymore. @@ -2333,7 +2339,8 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd - str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] + str_field_dmd = seqDmd -- See the bit about strict fields + -- in Note [Demand transformer for data constructors] -- | A special 'DmdTransformer' for dictionary selectors that feeds the demand -- on the result into the indicated dictionary component (if saturated). ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -260,7 +260,7 @@ The invariants around the arguments of call by value function like Ids are then: * Any `WorkerLikeId` * Some `JoinId` bindings. -This works analogous to the Strict Field Invariant. See also Note [Strict Field Invariant]. +This works analogous to the Strict Field Invariant. See also Note [STG Strict Field Invariant]. To make this work what we do is: * During W/W and SpecConstr any worker/specialized binding we introduce ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Core.Coercion import GHC.Core.Reduction import GHC.Core.Make import GHC.Core.FVs ( mkRuleInfo ) -import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase, coreAltsType ) +import GHC.Core.Utils ( exprType, mkCast, coreAltsType ) import GHC.Core.Unfold.Make import GHC.Core.SimpleOpt import GHC.Core.TyCon @@ -597,8 +597,12 @@ mkDataConWorkId wkr_name data_con = mkGlobalId (DataConWorkId data_con) wkr_name wkr_ty alg_wkr_info where - tycon = dataConTyCon data_con -- The representation TyCon - wkr_ty = dataConRepType data_con + tycon = dataConTyCon data_con -- The representation TyCon + wkr_ty = dataConRepType data_con + univ_tvs = dataConUnivTyVars data_con + ex_tcvs = dataConExTyCoVars data_con + arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys + str_marks = dataConRepStrictness data_con ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo @@ -606,12 +610,19 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setDmdSigInfo` wkr_sig + -- Workers eval their strict fields + -- See Note [Strict fields in Core] `setLFInfo` wkr_lf_info - -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + wkr_sig = mkClosedDmdSig wkr_dmds topDiv + wkr_dmds = map mk_dmd str_marks + mk_dmd MarkedStrict = evalDmd + mk_dmd NotMarkedStrict = topDmd + -- See Note [LFInfo of DataCon workers and wrappers] wkr_lf_info | wkr_arity == 0 = LFCon data_con @@ -619,9 +630,6 @@ mkDataConWorkId wkr_name data_con -- LFInfo stores post-unarisation arity ----------- Workers for newtypes -------------- - univ_tvs = dataConUnivTyVars data_con - ex_tcvs = dataConExTyCoVars data_con - arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma @@ -789,10 +797,10 @@ mkDataConRep :: DataConBangOpts -> FamInstEnvs -> Name -> DataCon - -> UniqSM DataConRep + -> UniqSM (DataConRep, [HsImplBang], [StrictnessMark]) mkDataConRep dc_bang_opts fam_envs wrap_name data_con | not wrapper_reqd - = return NoDataConRep + = return (NoDataConRep, arg_ibangs, rep_strs) | otherwise = do { wrap_args <- mapM (newLocal (fsLit "conrep")) wrap_arg_tys @@ -856,11 +864,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con ; return (DCR { dcr_wrap_id = wrap_id , dcr_boxer = mk_boxer boxers - , dcr_arg_tys = rep_tys - , dcr_stricts = rep_strs - -- For newtypes, dcr_bangs is always [HsLazy]. - -- See Note [HsImplBangs for newtypes]. - , dcr_bangs = arg_ibangs }) } + , dcr_arg_tys = rep_tys } + , arg_ibangs, rep_strs) } where (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys, _orig_res_ty) @@ -918,8 +923,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. -- See dataConUserTyVarsNeedWrapper below. - && (any isBanged (ev_ibangs ++ arg_ibangs))) - -- Some forcing/unboxing (includes eq_spec) + && (any isUnpacked (ev_ibangs ++ arg_ibangs))) + -- Some unboxing (includes eq_spec) || isFamInstTyCon tycon -- Cast result @@ -1185,7 +1190,7 @@ dataConArgRep arg_ty HsLazy = ([(arg_ty, NotMarkedStrict)], (unitUnboxer, unitBoxer)) dataConArgRep arg_ty (HsStrict _) - = ([(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) + = ([(arg_ty, MarkedStrict)], (unitUnboxer, unitBoxer)) -- Seqs are inserted in STG dataConArgRep arg_ty (HsUnpack Nothing) = dataConArgUnpack arg_ty @@ -1215,9 +1220,6 @@ wrapCo co rep_ty (unbox_rep, box_rep) -- co :: arg_ty ~ rep_ty ; return (rep_ids, rep_expr `Cast` mkSymCo sco) } ------------------------ -seqUnboxer :: Unboxer -seqUnboxer v = return ([v], mkDefaultCase (Var v) v) - unitUnboxer :: Unboxer unitUnboxer v = return ([v], \e -> e) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Utils.Misc ( dropWhileEndLE, spanEnd, last2, lastMaybe, onJust, - List.foldl1', foldl2, count, countWhile, all2, + List.foldl1', foldl2, count, countWhile, all2, all2Prefix, all3Prefix, lengthExceeds, lengthIs, lengthIsNot, lengthAtLeast, lengthAtMost, lengthLessThan, @@ -652,6 +652,30 @@ all2 _ [] [] = True all2 p (x:xs) (y:ys) = p x y && all2 p xs ys all2 _ _ _ = False +all2Prefix :: (a -> b -> Bool) -> [a] -> [b] -> Bool +-- ^ `all2Prefix p xs ys` is a fused version of `and $ zipWith2 p xs ys`. +-- So if one list is shorter than the other, `p` is assumed to be `True` for the +-- suffix. +all2Prefix p = foldr k z + where + k x go ys' = case ys' of + (y:ys'') -> p x y && go ys'' + _ -> True + z _ = True +{-# INLINE all2Prefix #-} + +all3Prefix :: (a -> b -> c -> Bool) -> [a] -> [b] -> [c] -> Bool +-- ^ `all3Prefix p xs ys zs` is a fused version of `and $ zipWith3 p xs ys zs`. +-- So if one list is shorter than the others, `p` is assumed to be `True` for +-- the suffix. +all3Prefix p = foldr k z + where + k x go ys' zs' = case (ys',zs') of + (y:ys'',z:zs'') -> p x y z && go ys'' zs'' + _ -> False + z _ _ = True +{-# INLINE all3Prefix #-} + -- Count the number of times a predicate is true count :: (a -> Bool) -> [a] -> Int ===================================== testsuite/tests/dmdanal/sigs/T16859.stderr ===================================== @@ -4,7 +4,7 @@ T16859.bar: <1!A> T16859.baz: <1L><1!P(L)><1C(1,L)> T16859.buz: <1!P(L,L)> T16859.foo: <1L> -T16859.mkInternalName: <1!P(L)><1L><1L> +T16859.mkInternalName: <1!P(L)> T16859.n_loc: <1!P(A,A,A,1L)> T16859.n_occ: <1!P(A,1!P(L,L),A,A)> T16859.n_sort: <1!P(1L,A,A,A)> ===================================== testsuite/tests/ghci/should_run/T21052.stdout ===================================== @@ -5,7 +5,7 @@ BCO_toplevel :: GHC.Types.IO [GHC.Types.Any] {} \u [] let { sat :: [GHC.Types.Any] - [LclId] = + [LclId, Unf=OtherCon []] = :! [GHC.Tuple.() GHC.Types.[]]; } in GHC.Internal.Base.returnIO sat; ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -14,8 +14,8 @@ T23083.g = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> let { sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer - [LclId] - sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + [LclId, Unf=OtherCon []] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1, Dmd=SL] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in f sat -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/simplCore/should_run/T20749.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE UnliftedDatatypes #-} +import Data.Kind +import GHC.Exts + +type StrictPair :: Type -> Type -> UnliftedType +data StrictPair a b = SP !a !b + +f :: StrictPair Int Int -> StrictPair Int Int -> Int -> Bool +{-# OPAQUE f #-} +f (SP x _) (SP _ y) z = x < y + z + +g :: Int -> [Int] -> Int +{-# OPAQUE g #-} +g x ys = h ys + where + h [] = 0 + h (y:ys) = case SP x 27 of + u -> if f u u y then x else x + h ys + +main :: IO () +main = print (g undefined []) ===================================== testsuite/tests/simplCore/should_run/T20749.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/T24662.hs ===================================== @@ -0,0 +1,27 @@ +{-# LANGUAGE MagicHash #-} + +module T24662 where + +import GHC.Exts + +f1 :: a -> Int# -> Int -> Int +{-# OPAQUE f1 #-} +f1 _ x (I# y) = I# (x +# y) + +f2 :: Int# -> a -> Int -> Int +{-# OPAQUE f2 #-} +f2 x _ (I# y) = I# (x +# y) + +loopy :: Int -> Int# +loopy x | x>0 = loopy x + | otherwise = 0# + +-- Should either let or case-bind t (preferrably the latter), but we should do +-- it consistently in foo1 and foo2. +foo1 x = let t :: Int -> Int + t = f1 True (loopy x) in + t `seq` (x, t) + +foo2 x = let t :: Int -> Int + t = f2 True (loopy x) in + t `seq` (x, t) ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -107,6 +107,7 @@ test('UnliftedArgRule', normal, compile_and_run, ['']) test('T21229', normal, compile_and_run, ['-O']) test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) +test('T20749', normal, compile_and_run, ['']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) @@ -114,3 +115,4 @@ test('T23184', normal, compile_and_run, ['-O']) test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) test('T23289', normal, compile_and_run, ['']) test('T23056', [only_ways(['ghci-opt'])], ghci_script, ['T23056.script']) +test('T24662', normal, compile_and_run, ['']) ===================================== testsuite/tests/simplStg/should_compile/T19717.stderr ===================================== @@ -3,15 +3,15 @@ Foo.f :: forall {a}. a -> [GHC.Internal.Maybe.Maybe a] [GblId, Arity=1, Str=<1L>, Unf=OtherCon []] = {} \r [x] - case x of x1 { + case x of x1 [Dmd=SL] { __DEFAULT -> let { sat [Occ=Once1] :: GHC.Internal.Maybe.Maybe a - [LclId] = + [LclId, Unf=OtherCon []] = GHC.Internal.Maybe.Just! [x1]; } in let { sat [Occ=Once1] :: [GHC.Internal.Maybe.Maybe a] - [LclId] = + [LclId, Unf=OtherCon []] = :! [sat GHC.Types.[]]; } in : [sat sat]; }; ===================================== testsuite/tests/simplStg/should_compile/inferTags002.stderr ===================================== @@ -1,88 +1,30 @@ -==================== Output Cmm ==================== -[M.$WMkT_entry() { // [R3, R2] - { info_tbls: [(cym, - label: block_cym_info - rep: StackRep [False] - srt: Nothing), - (cyp, - label: M.$WMkT_info - rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } - srt: Nothing), - (cys, - label: block_cys_info - rep: StackRep [False] - srt: Nothing)] - stack_info: arg_space: 8 - } - {offset - cyp: // global - if ((Sp + -16) < SpLim) (likely: False) goto cyv; else goto cyw; - cyv: // global - R1 = M.$WMkT_closure; - call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - cyw: // global - I64[Sp - 16] = cym; - R1 = R2; - P64[Sp - 8] = R3; - Sp = Sp - 16; - if (R1 & 7 != 0) goto cym; else goto cyn; - cyn: // global - call (I64[R1])(R1) returns to cym, args: 8, res: 8, upd: 8; - cym: // global - I64[Sp] = cys; - _sy8::P64 = R1; - R1 = P64[Sp + 8]; - P64[Sp + 8] = _sy8::P64; - call stg_ap_0_fast(R1) returns to cys, args: 8, res: 8, upd: 8; - cys: // global - Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto cyA; else goto cyz; - cyA: // global - HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cys, args: 8, res: 8, upd: 8; - cyz: // global - I64[Hp - 16] = M.MkT_con_info; - P64[Hp - 8] = P64[Sp + 8]; - P64[Hp] = R1; - R1 = Hp - 15; - Sp = Sp + 16; - call (P64[Sp])(R1) args: 8, res: 0, upd: 8; - } - }, - section ""data" . M.$WMkT_closure" { - M.$WMkT_closure: - const M.$WMkT_info; - }] - - - ==================== Output Cmm ==================== [M.f_entry() { // [R2] - { info_tbls: [(cyK, - label: block_cyK_info + { info_tbls: [(cAs, + label: block_info rep: StackRep [] srt: Nothing), - (cyN, + (cAv, label: M.f_info rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} } srt: Nothing)] stack_info: arg_space: 8 } {offset - cyN: // global - if ((Sp + -8) < SpLim) (likely: False) goto cyO; else goto cyP; - cyO: // global + _lbl_: // global + if ((Sp + -8) < SpLim) (likely: False) goto cAw; else goto cAx; + _lbl_: // global R1 = M.f_closure; call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8; - cyP: // global - I64[Sp - 8] = cyK; + _lbl_: // global + I64[Sp - 8] = cAs; R1 = R2; Sp = Sp - 8; - if (R1 & 7 != 0) goto cyK; else goto cyL; - cyL: // global - call (I64[R1])(R1) returns to cyK, args: 8, res: 8, upd: 8; - cyK: // global + if (R1 & 7 != 0) goto cAs; else goto cAt; + _lbl_: // global + call (I64[R1])(R1) returns to cAs, args: 8, res: 8, upd: 8; + _lbl_: // global R1 = P64[R1 + 15]; Sp = Sp + 8; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; @@ -97,47 +39,47 @@ ==================== Output Cmm ==================== [M.MkT_entry() { // [R3, R2] - { info_tbls: [(cz1, - label: block_cz1_info + { info_tbls: [(cAJ, + label: block_info rep: StackRep [False] srt: Nothing), - (cz4, + (cAM, label: M.MkT_info rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} } srt: Nothing), - (cz7, - label: block_cz7_info + (cAP, + label: block_info rep: StackRep [False] srt: Nothing)] stack_info: arg_space: 8 } {offset - cz4: // global - if ((Sp + -16) < SpLim) (likely: False) goto cza; else goto czb; - cza: // global + _lbl_: // global + if ((Sp + -16) < SpLim) (likely: False) goto cAS; else goto cAT; + _lbl_: // global R1 = M.MkT_closure; call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8; - czb: // global - I64[Sp - 16] = cz1; + _lbl_: // global + I64[Sp - 16] = cAJ; R1 = R2; P64[Sp - 8] = R3; Sp = Sp - 16; - if (R1 & 7 != 0) goto cz1; else goto cz2; - cz2: // global - call (I64[R1])(R1) returns to cz1, args: 8, res: 8, upd: 8; - cz1: // global - I64[Sp] = cz7; - _tyf::P64 = R1; + if (R1 & 7 != 0) goto cAJ; else goto cAK; + _lbl_: // global + call (I64[R1])(R1) returns to cAJ, args: 8, res: 8, upd: 8; + _lbl_: // global + I64[Sp] = cAP; + __locVar_::P64 = R1; R1 = P64[Sp + 8]; - P64[Sp + 8] = _tyf::P64; - call stg_ap_0_fast(R1) returns to cz7, args: 8, res: 8, upd: 8; - cz7: // global + P64[Sp + 8] = __locVar_::P64; + call stg_ap_0_fast(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global Hp = Hp + 24; - if (Hp > HpLim) (likely: False) goto czf; else goto cze; - czf: // global + if (Hp > HpLim) (likely: False) goto cAX; else goto cAW; + _lbl_: // global HpAlloc = 24; - call stg_gc_unpt_r1(R1) returns to cz7, args: 8, res: 8, upd: 8; - cze: // global + call stg_gc_unpt_r1(R1) returns to cAP, args: 8, res: 8, upd: 8; + _lbl_: // global I64[Hp - 16] = M.MkT_con_info; P64[Hp - 8] = P64[Sp + 8]; P64[Hp] = R1; @@ -155,14 +97,14 @@ ==================== Output Cmm ==================== [M.MkT_con_entry() { // [] - { info_tbls: [(czl, + { info_tbls: [(cB3, label: M.MkT_con_info rep: HeapRep 2 ptrs { Con {tag: 0 descr:"main:M.MkT"} } srt: Nothing)] stack_info: arg_space: 8 } {offset - czl: // global + _lbl_: // global R1 = R1 + 1; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a471377446f7158fe14d9c781f62b50b1eb6b894...8dfbffed0dd87fea75a19f5a8d50d54fa4ced201 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a471377446f7158fe14d9c781f62b50b1eb6b894...8dfbffed0dd87fea75a19f5a8d50d54fa4ced201 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 12:09:26 2024 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 29 Apr 2024 08:09:26 -0400 Subject: [Git][ghc/ghc][wip/conf-hi-hadrian] Make interface files and object files depend on inplace .conf file Message-ID: <662f8df6a4299_a3e8f28ec7c6512b@gitlab.mail> Matthew Pickering pushed to branch wip/conf-hi-hadrian at Glasgow Haskell Compiler / GHC Commits: 0f8886f5 by Matthew Pickering at 2024-04-29T13:09:01+01:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 1 changed file: - hadrian/src/Rules/Compile.hs Changes: ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0f8886f5b77f9c17c2f21e77faa45af15a4f840a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0f8886f5b77f9c17c2f21e77faa45af15a4f840a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 13:26:29 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 29 Apr 2024 09:26:29 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] 46 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662fa005ba474_a3e8fd8791c83446@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - ac3d7052 by Andreas Klebinger at 2024-04-29T13:26:24+00:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - 53327d1e by Andreas Klebinger at 2024-04-29T13:26:24+00:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Settings.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ec9b439b8e34c798a06541c877bba9772907131...53327d1e7d829cc1bd911f9beccdb3ebd11e3fe9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ec9b439b8e34c798a06541c877bba9772907131...53327d1e7d829cc1bd911f9beccdb3ebd11e3fe9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 13:51:07 2024 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 29 Apr 2024 09:51:07 -0400 Subject: [Git][ghc/ghc][wip/andreask/arm_mem_model] 45 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <662fa5cb23981_a3e8f136dac0948a8@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/arm_mem_model at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 78b16a5f by Andreas Klebinger at 2024-04-29T15:50:42+02:00 NCG: AArch64 - Add -fhuge-code-sections. When enabled the arm backend will assume jumps to targets outside of the current module are further than 128MB away. This will allow for code to work if: * The current module results in less than 128MB of code. * The whole program is loaded within a 4GB memory region. We enable this by default on mac where the lack of split sections can sometimes cause us to go over this limit - see #24648. This works around #24648 for now. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CmmToAsm.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32c94235fff1438c9b4d11015c7df4a7c85e6c62...78b16a5fb82508add5a29a4e223cd1d69757f115 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32c94235fff1438c9b4d11015c7df4a7c85e6c62...78b16a5fb82508add5a29a4e223cd1d69757f115 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 14:16:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 10:16:00 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: EPA: Preserve comments in Match Pats Message-ID: <662faba0505b0_a3e8f174b750105484@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4f3e1a54 by Alan Zimmerman at 2024-04-29T10:14:44-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 3d4c2552 by Sylvain Henry at 2024-04-29T10:14:58-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - 28c3bccb by Cheng Shao at 2024-04-29T10:15:00-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 9 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c4bc82f5cc357a2bd7f6341c3bd35b5fb867337d...28c3bccb027ebdce7df6e9b2fd87f1298742e021 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c4bc82f5cc357a2bd7f6341c3bd35b5fb867337d...28c3bccb027ebdce7df6e9b2fd87f1298742e021 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 16:18:09 2024 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 29 Apr 2024 12:18:09 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv64-ncg] Move alignment check Message-ID: <662fc8417d491_360e11a10e0015880@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC Commits: cf6c224d by Sven Tennie at 2024-04-29T18:16:58+02:00 Move alignment check - - - - - 1 changed file: - compiler/GHC/CmmToAsm/RV64/CodeGen.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -478,11 +478,6 @@ getRegister' config plat (CmmMachOp (MO_Add w0) [x, CmmLit (CmmInt i w1)]) | i < getRegister' config plat (CmmMachOp (MO_Sub w0) [x, CmmLit (CmmInt i w1)]) | i < 0 = getRegister' config plat (CmmMachOp (MO_Add w0) [x, CmmLit (CmmInt (-i) w1)]) -getRegister' config platform (CmmMachOp (MO_AlignmentCheck align wordWidth) [e]) - = do - reg <- getRegister' config platform e - addAlignmentCheck align wordWidth reg - -- Generic case. getRegister' config plat expr = case expr of @@ -622,6 +617,9 @@ getRegister' config plat expr = -- Conversions MO_XX_Conv _from to -> swizzleRegisterRep (intFormat to) <$> getRegister e + MO_AlignmentCheck align wordWidth -> do + reg <- getRegister' config plat e + addAlignmentCheck align wordWidth reg _ -> pprPanic "getRegister' (monadic CmmMachOp):" (pdoc plat expr) where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf6c224dbd43d4eaf6d9c726214b275a9758f8d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf6c224dbd43d4eaf6d9c726214b275a9758f8d3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 17:25:27 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 29 Apr 2024 13:25:27 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] 148 commits: EPA: Fix FamDecl range Message-ID: <662fd807951d4_35c70789618868274@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: cd0fb82f by Alan Zimmerman at 2024-03-27T19:33:08+00:00 EPA: Fix FamDecl range The span was incorrect if opt_datafam_kind_sig was empty - - - - - f8f384a8 by Ben Gamari at 2024-03-29T01:23:03-04:00 Fix type of _get_osfhandle foreign import Fixes #24601. - - - - - 00d3ecf0 by Alan Zimmerman at 2024-03-29T12:19:10+00:00 EPA: Extend StringLiteral range to include trailing commas This goes slightly against the exact printing philosophy where trailing decorations should be in an annotation, but the practicalities of adding it to the WarningTxt environment, and the problems caused by deviating do not make a more principles approach worthwhile. - - - - - efab3649 by brandon s allbery kf8nh at 2024-03-31T20:04:01-04:00 clarify Note [Preproccesing invocations] - - - - - c8a4c050 by Ben Gamari at 2024-04-02T12:50:35-04:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. - - - - - e91dad93 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. - - - - - a9ab9455 by Cheng Shao at 2024-04-02T12:50:35-04:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library - - - - - 865bd717 by Cheng Shao at 2024-04-02T12:50:35-04:00 compiler: fix github link to __tsan_memory_order in a comment - - - - - 07cb627c by Cheng Shao at 2024-04-02T12:50:35-04:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. - - - - - a1c18c7b by Andrei Borzenkov at 2024-04-02T12:51:11-04:00 Merge tc_infer_hs_type and tc_hs_type into one function using ExpType philosophy (#24299, #23639) This patch implements refactoring which is a prerequisite to updating kind checking of type patterns. This is a huge simplification of the main worker that checks kind of HsType. It also fixes the issues caused by previous code duplication, e.g. that we didn't add module finalizers from splices in inference mode. - - - - - 817e8936 by Rodrigo Mesquita at 2024-04-02T20:13:05-04:00 th: Hide the Language.Haskell.TH.Lib.Internal module from haddock Fixes #24562 - - - - - b36ee57b by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: reenable h$appendToHsString optimization (#24495) The optimization introducing h$appendToHsString wasn't kicking in anymore (while it did in 9.8.1) because of the changes introduced in #23270 (7e0c8b3bab30). This patch reenables the optimization by matching on case-expression, as done in Cmm for unpackCString# standard thunks. The test is also T24495 added in the next commits (two commits for ease of backporting to 9.8). - - - - - 527616e9 by Sylvain Henry at 2024-04-02T20:13:46-04:00 JS: fix h$appendToHsString implementation (#24495) h$appendToHsString needs to wrap its argument in an updatable thunk to behave like unpackAppendCString#. Otherwise if a SingleEntry thunk is passed, it is stored as-is in a CONS cell, making the resulting list impossible to deepseq (forcing the thunk doesn't update the contents of the CONS cell)! The added test checks that the optimization kicks in and that h$appendToHsString works as intended. Fix #24495 - - - - - faa30b41 by Simon Peyton Jones at 2024-04-02T20:14:22-04:00 Deal with duplicate tyvars in type declarations GHC was outright crashing before this fix: #24604 - - - - - e0b0c717 by Simon Peyton Jones at 2024-04-02T20:14:58-04:00 Try using MCoercion in exprIsConApp_maybe This is just a simple refactor that makes exprIsConApp_maybe a little bit more direct, simple, and efficient. Metrics: compile_time/bytes allocated geo. mean -0.1% minimum -2.0% maximum -0.0% Not a big gain, but worthwhile given that the code is, if anything, easier to grok. - - - - - 15f4d867 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Initial ./configure support for selecting I/O managers In this patch we just define new CPP vars, but don't yet use them or replace the existing approach. That will follow. The intention here is that every I/O manager can be enabled/disabled at GHC build time (subject to some constraints). More than one I/O manager can be enabled to be built. At least one I/O manager supporting the non-threaded RTS must be enabled as well as at least one supporting the non-threaded RTS. The I/O managers enabled here will become the choices available at runtime at RTS startup (in later patches). The choice can be made with RTS flags. There are separate sets of choices for the threaded and non-threaded RTS ways, because most I/O managers are specific to these ways. Furthermore we must establish a default I/O manager for the threaded and non-threaded RTS. Most I/O managers are platform-specific so there are checks to ensure each one can be enabled on the platform. Such checks are also where (in future) any system dependencies (e.g. libraries) can be checked. The output is a set of CPP flags (in the mk/config.h file), with one flag per named I/O manager: * IOMGR_BUILD_<name> : which ones should be built (some) * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one) * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one) and a set of derived flags in IOManager.h * IOMGR_ENABLED_<name> : enabled for the current RTS way Note that IOMGR_BUILD_<name> just says that an I/O manager will be built for _some_ RTS way (i.e. threaded or non-threaded). The derived flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is enabled in the "current" RTS way. These are the ones that can be used for conditional compilation of the I/O manager code. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - 85b0f87a by Duncan Coutts at 2024-04-03T01:27:17-04:00 Change the handling of the RTS flag --io-manager= Now instead of it being just used on Windows to select between the WinIO vs the MIO or Win32-legacy I/O managers, it is now used on all platforms for selecting the I/O manager to use. Right now it remains the case that there is only an actual choice on Windows, but that will change later. Document the --io-manager flag in the user guide. This change is also reflected in the RTS flags types in the base library. Deprecate the export of IoSubSystem from GHC.RTS.Flags with a message to import it from GHC.IO.Subsystem. The way the 'IoSubSystem' is detected also changes. Instead of looking at the RTS flag, there is now a C bool global var in the RTS which gets set on startup when the I/O manager is selected. This bool var says whether the selected I/O manager classifies as "native" on Windows, which in practice means the WinIO I/O manager has been selected. Similarly, the is_io_mng_native_p RTS helper function is re-implemented in terms of the selected I/O manager, rather than based on the RTS flags. We do however remove the ./configure --native-io-manager flag because we're bringing the WinIO/MIO/Win32-legacy choice under the new general scheme for selecting I/O managers, and that new scheme involves no ./configure time user choices, just runtime RTS flag choices. - - - - - 1a8f020f by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert {init,stop,exit}IOManager to switch style Rather than ad-hoc cpp conitionals on THREADED_RTS and mingw32_HOST_OS, we use a style where we switch on the I/O manager impl, with cases for each I/O manager impl. - - - - - a5bad3d2 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Split up the CapIOManager content by I/O manager Using the new IOMGR_ENABLED_<name> CPP defines. - - - - - 1d36e609 by Duncan Coutts at 2024-04-03T01:27:17-04:00 Convert initIOManagerAfterFork and wakeupIOManager to switch style - - - - - c2f26f36 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of waitRead#/Write# from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. - - - - - 457705a8 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move most of the delay# impl from cmm to C Moves it into the IOManager.c where we can follow the new pattern of switching on the selected I/O manager. Uses a new IOManager API: syncDelay, following the naming convention of sync* for thread-synchronous I/O & timer/delay operations. As part of porting from cmm to C, we maintain the rule that the why_blocked gets accessed using load acquire and store release atomic memory operations. There was one exception to this rule: in the delay# primop cmm code on posix (not win32), the why_blocked was being updated using a store relaxed, not a store release. I've no idea why. In this convesion I'm playing it safe here and using store release consistently. - - - - - e93058e0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 insertIntoSleepingQueue is no longer public No longer defined in IOManager.h, just a private function in IOManager.c. Since it is no longer called from cmm code, just from syncDelay. It ought to get moved further into the select() I/O manager impl, rather than living in IOManager.c. On the other hand appendToIOBlockedQueue is still called from cmm code in the win32-legacy I/O manager primops async{Read,Write}#, and it is also used by the select() I/O manager. Update the CPP and comments to reflect this. - - - - - 60ce9910 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move anyPendingTimeoutsOrIO impl from .h to .c The implementation is eventually going to need to use more private things, which will drag in unwanted includes into IOManager.h, so it's better to move the impl out of the header file and into the .c file, at the slight cost of it no longer being inline. At the same time, change to the "switch (iomgr_type)" style. - - - - - f70b8108 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Take a simpler approach to gcc warnings in IOManager.c We have lots of functions with conditional implementations for different I/O managers. Some functions, for some I/O managers, naturally have implementations that do nothing or barf. When only one such I/O manager is enabled then the whole function implementation will have an implementation that does nothing or barfs. This then results in warnings from gcc that parameters are unused, or that the function should be marked with attribute noreturn (since barf does not return). The USED_IF_THREADS trick for fine-grained warning supression is fine for just two cases, but an equivalent here would need USED_IF_THE_ONLY_ENABLED_IOMGR_IS_X_OR_Y which would have combinitorial blowup. So we take a coarse grained approach and simply disable these two warnings for the whole file. So we use a GCC pragma, with its handy push/pop support: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" #pragma GCC diagnostic ignored "-Wunused-parameter" ... #pragma GCC diagnostic pop - - - - - b48805b9 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add a new trace class for the iomanager It makes sense now for it to be separate from the scheduler class of tracers. Enabled with +RTS -Do. Document the -Do debug flag in the user guide. - - - - - f0c1f862 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Have the throwTo impl go via (new) IOManager APIs rather than directly operating on the IO manager's data structures. Specifically, when thowing an async exception to a thread that is blocked waiting for I/O or waiting for a timer, then we want to cancel that I/O waiting or cancel the timer. Currently this is done directly in removeFromQueues() in RaiseAsync.c. We want it to go via proper APIs both for modularity but also to let us support multiple I/O managers. So add sync{IO,Delay}Cancel, which is the cancellation for the corresponding sync{IO,Delay}. The implementations of these use the usual "switch (iomgr_type)" style. - - - - - 4f9e9c4e by Duncan Coutts at 2024-04-03T01:27:18-04:00 Move awaitEvent into a proper IOManager API and have the scheduler use it. Previously the scheduler calls awaitEvent directly, and awaitEvent is implemented directly in the RTS I/O managers (select, win32). This relies on the old scheme where there's a single active I/O manager for each platform and RTS way. We want to move that to go via an API in IOManager.{h,c} which can then call out to the active I/O manager. Also take the opportunity to split awaitEvent into two. The existing awaitEvent has a bool wait parameter, to say if the call should be blocking or non-blocking. We split this into two separate functions: pollCompletedTimeoutsOrIO and awaitCompletedTimeoutsOrIO. We split them for a few reasons: they have different post-conditions (specifically the await version is supposed to guarantee that there are threads runnable when it completes). Secondly, it is also anticipated that in future I/O managers the implementations of the two cases will be simpler if they are separated. - - - - - 5ad4b30f by Duncan Coutts at 2024-04-03T01:27:18-04:00 Rename awaitEvent in select and win32 I/O managers These are now just called from IOManager.c and are the per-I/O manager backend impls (whereas previously awaitEvent was the entry point). Follow the new naming convention in the IOManager.{h,c} of awaitCompletedTimeoutsOrIO, with the I/O manager's name as a suffix: so awaitCompletedTimeoutsOrIO{Select,Win32}. - - - - - d30c6bc6 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Tidy up a couple things in Select.{h,c} Use the standard #include {Begin,End}Private.h style rather than RTS_PRIVATE on individual decls. And conditionally build the code for the select I/O manager based on the new CPP IOMGR_ENABLED_SELECT rather than on THREADED_RTS. - - - - - 4161f516 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add an IOManager API for scavenging TSO blocked_info When the GC scavenges a TSO it needs to scavenge the tso->blocked_info but the blocked_info is a big union and what lives there depends on the two->why_blocked, which for I/O-related reasons is something that in principle is the responsibility of the I/O manager and not the GC. So the right thing to do is for the GC to ask the I/O manager to sscavenge the blocked_info if it encounters any I/O-related why_blocked reasons. So we add scavengeTSOIOManager in IOManager.{h,c} with the usual style. Now as it happens, right now, there is no special scavenging to do, so the implementation of scavengeTSOIOManager is a fancy no-op. That's because the select I/O manager uses only the fd and target members, which are not GC pointers, and the win32-legacy I/O manager _ought_ to be using GC-managed heap objects for the StgAsyncIOResult but it is actually usingthe C heap, so again no GC pointers. If the win32-legacy were doing this more sensibly, then scavengeTSOIOManager would be the right place to do the GC magic. Future I/O managers will need GC heap objects in the tso->blocked_info and will make use of this functionality. - - - - - 94a87d21 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add I/O manager API notifyIOManagerCapabilitiesChanged Used in setNumCapabilities. It only does anything for MIO on Posix. Previously it always invoked Haskell code, but that code only did anything on non-Windows (and non-JS), and only threaded. That currently effectively means the MIO I/O manager on Posix. So now it only invokes it for the MIO Posix case. - - - - - 3be6d591 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Select an I/O manager early in RTS startup We need to select the I/O manager to use during startup before the per-cap I/O manager initialisation. - - - - - aaa294d0 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Make struct CapIOManager be fully opaque Provide an opaque (forward) definition in Capability.h (since the cap contains a *CapIOManager) and then only provide a full definition in a new file IOManagerInternals.h. This new file is only supposed to be included by the IOManager implementation, not by its users. So that means IOManager.c and individual I/O manager implementations. The posix/Signals.c still needs direct access, but that should be eliminated. Anything that needs direct access either needs to be clearly part of an I/O manager (e.g. the sleect() one) or go via a proper API. - - - - - 877a2a80 by Duncan Coutts at 2024-04-03T01:27:18-04:00 The select() I/O manager does have some global initialisation It's just to make sure an exception CAF is a GC root. - - - - - 9c51473b by Duncan Coutts at 2024-04-03T01:27:18-04:00 Add tracing for the main I/O manager actions Using the new tracer class. Note: The unconditional definition of showIOManager should be compatible with the debugTrace change in 7c7d1f6. Co-authored-by: Pi Delport <pi at well-typed.com> - - - - - c7d3e3a3 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Include the default I/O manager in the +RTS --info output Document the extra +RTS --info output in the user guide - - - - - 8023bad4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 waitRead# / waitWrite# do not work for win32-legacy I/O manager Previously it was unclear that they did not work because the code path was shared with other I/O managers (in particular select()). Following the code carefully shows that what actually happens is that the calling thread would block forever: the thread will be put into the blocked queue, but no other action is scheduled that will ever result in it getting unblocked. It's better to just fail loudly in case anyone accidentally calls it, also it's less confusing code. - - - - - 83a74d20 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Conditionally ignore some GCC warnings Some GCC versions don't know about some warnings, and they complain that we're ignoring unknown warnings. So we try to ignore the warning based on the GCC version. - - - - - 1adc6fa4 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept changes to base-exports All the changes are in fact not changes at all. Previously, the IoSubSystem data type was defined in GHC.RTS.Flags and exported from both GHC.RTS.Flags and GHC.IO.SubSystem. Now, the data type is defined in GHC.IO.SubSystem and still exported from both modules. Therefore, the same exports and same instances are still available from both modules. But the base-exports records only the defining module, and so it looks like a change when it is fully compatible. Related: we do add a deprecation to the export of the type via GHC.RTS.Flags, telling people to use the export from GHC.IO.SubSystem. Also the sort order for some unrelated Show instances changed. No idea why. The same changes apply in the other versions, with a few more changes due to sort order weirdness. - - - - - 8d950968 by Duncan Coutts at 2024-04-03T01:27:18-04:00 Accept metric decrease in T12227 I can't think of any good reason that anything in this MR should have changed the number of allocations, up or down. (Yes this is an empty commit.) Metric Decrease: T12227 - - - - - e869605e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Several improvements to the handling of coercions * Make `mkSymCo` and `mkInstCo` smarter Fixes #23642 * Fix return role of `SelCo` in the coercion optimiser. Fixes #23617 * Make the coercion optimiser `opt_trans_rule` work better for newtypes Fixes #23619 - - - - - 1efd0714 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 FloatOut: improve floating for join point See the new Note [Floating join point bindings]. * Completely get rid of the complicated join_ceiling nonsense, which I have never understood. * Do not float join points at all, except perhaps to top level. * Some refactoring around wantToFloat, to treat Rec and NonRec more uniformly - - - - - 9c00154d by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve eta-expansion through call stacks See Note [Eta expanding through CallStacks] in GHC.Core.Opt.Arity This is a one-line change, that fixes an inconsistency - || isCallStackPredTy ty + || isCallStackPredTy ty || isCallStackTy ty - - - - - 95a9a172 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Spelling, layout, pretty-printing only - - - - - bdf1660f by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Improve exprIsConApp_maybe a little Eliminate a redundant case at birth. This sometimes reduces Simplifier iterations. See Note [Case elim in exprIsConApp_maybe]. - - - - - 609cd32c by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Inline GHC.HsToCore.Pmc.Solver.Types.trvVarInfo When exploring compile-time regressions after meddling with the Simplifier, I discovered that GHC.HsToCore.Pmc.Solver.Types.trvVarInfo was very delicately balanced. It's a small, heavily used, overloaded function and it's important that it inlines. By a fluke it was before, but at various times in my journey it stopped doing so. So I just added an INLINE pragma to it; no sense in depending on a delicately-balanced fluke. - - - - - ae24c9bc by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Slight improvement in WorkWrap Ensure that WorkWrap preserves lambda binders, in case of join points. Sadly I have forgotten why I made this change (it was while I was doing a lot of meddling in the Simplifier, but * it does no harm, * it is slightly more efficient, and * presumably it made something better! Anyway I have kept it in a separate commit. - - - - - e9297181 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Use named record fields for the CastIt { ... } data constructor This is a pure refactor - - - - - b4581e23 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Remove a long-commented-out line Pure refactoring - - - - - e026bdf2 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Simplifier improvements This MR started as: allow the simplifer to do more in one pass, arising from places I could see the simplifier taking two iterations where one would do. But it turned into a larger project, because these changes unexpectedly made inlining blow up, especially join points in deeply-nested cases. The main changes are below. There are also many new or rewritten Notes. Avoiding simplifying repeatedly ~~~~~~~~~~~~~~~ See Note [Avoiding simplifying repeatedly] * The SimplEnv now has a seInlineDepth field, which says how deep in unfoldings we are. See Note [Inline depth] in Simplify.Env. Currently used only for the next point: avoiding repeatedly simplifying coercions. * Avoid repeatedly simplifying coercions. see Note [Avoid re-simplifying coercions] in Simplify.Iteration As you'll see from the Note, this makes use of the seInlineDepth. * Allow Simplify.Iteration.simplAuxBind to inline used-once things. This is another part of Note [Post-inline for single-use things], and is really good for reducing simplifier iterations in situations like case K e of { K x -> blah } wher x is used once in blah. * Make GHC.Core.SimpleOpt.exprIsConApp_maybe do some simple case elimination. Note [Case elim in exprIsConApp_maybe] * Improve the case-merge transformation: - Move the main code to `GHC.Core.Utils.mergeCaseAlts`, to join `filterAlts` and friends. See Note [Merge Nested Cases] in GHC.Core.Utils. - Add a new case for `tagToEnum#`; see wrinkle (MC3). - Add a new case to look through join points: see wrinkle (MC4) postInlineUnconditionally ~~~~~~~~~~~~~~~~~~~~~~~~~ * Allow Simplify.Utils.postInlineUnconditionally to inline variables that are used exactly once. See Note [Post-inline for single-use things]. * Do not postInlineUnconditionally join point, ever. Doing so does not reduce allocation, which is the main point, and with join points that are used a lot it can bloat code. See point (1) of Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration. * Do not postInlineUnconditionally a strict (demanded) binding. It will not allocate a thunk (it'll turn into a case instead) so again the main point of inlining it doesn't hold. Better to check per-call-site. * Improve occurrence analyis for bottoming function calls, to help postInlineUnconditionally. See Note [Bottoming function calls] in GHC.Core.Opt.OccurAnal Inlining generally ~~~~~~~~~~~~~~~~~~ * In GHC.Core.Opt.Simplify.Utils.interestingCallContext, use RhsCtxt NonRecursive (not BoringCtxt) for a plain-seq case. See Note [Seq is boring] Also, wrinkle (SB1), inline in that `seq` context only for INLINE functions (UnfWhen guidance). * In GHC.Core.Opt.Simplify.Utils.interestingArg, - return ValueArg for OtherCon [c1,c2, ...], but - return NonTrivArg for OtherCon [] This makes a function a little less likely to inline if all we know is that the argument is evaluated, but nothing else. * isConLikeUnfolding is no longer true for OtherCon {}. This propagates to exprIsConLike. Con-like-ness has /positive/ information. Join points ~~~~~~~~~~~ * Be very careful about inlining join points. See these two long Notes Note [Duplicating join points] in GHC.Core.Opt.Simplify.Iteration Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline * When making join points, don't do so if the join point is so small it will immediately be inlined; check uncondInlineJoin. * In GHC.Core.Opt.Simplify.Inline.tryUnfolding, improve the inlining heuristics for join points. In general we /do not/ want to inline join points /even if they are small/. See Note [Duplicating join points] GHC.Core.Opt.Simplify.Iteration. But sometimes we do: see Note [Inlining join points] in GHC.Core.Opt.Simplify.Inline; and the new `isBetterUnfoldingThan` function. * Do not add an unfolding to a join point at birth. This is a tricky one and has a long Note [Do not add unfoldings to join points at birth] It shows up in two places - In `mkDupableAlt` do not add an inlining - (trickier) In `simplLetUnfolding` don't add an unfolding for a fresh join point I am not fully satisifed with this, but it works and is well documented. * In GHC.Core.Unfold.sizeExpr, make jumps small, so that we don't penalise having a non-inlined join point. Performance changes ~~~~~~~~~~~~~~~~~~~ * Binary sizes fall by around 2.6%, according to nofib. * Compile times improve slightly. Here are the figures over 1%. I investiate the biggest differnce in T18304. It's a very small module, just a few hundred nodes. The large percentage difffence is due to a single function that didn't quite inline before, and does now, making code size a bit bigger. I decided gains outweighed the losses. Metrics: compile_time/bytes allocated (changes over +/- 1%) ------------------------------------------------ CoOpt_Singletons(normal) -9.2% GOOD LargeRecord(normal) -23.5% GOOD MultiComponentModulesRecomp(normal) +1.2% MultiLayerModulesTH_OneShot(normal) +4.1% BAD PmSeriesS(normal) -3.8% PmSeriesV(normal) -1.5% T11195(normal) -1.3% T12227(normal) -20.4% GOOD T12545(normal) -3.2% T12707(normal) -2.1% GOOD T13253(normal) -1.2% T13253-spj(normal) +8.1% BAD T13386(normal) -3.1% GOOD T14766(normal) -2.6% GOOD T15164(normal) -1.4% T15304(normal) +1.2% T15630(normal) -8.2% T15630a(normal) NEW T15703(normal) -14.7% GOOD T16577(normal) -2.3% GOOD T17516(normal) -39.7% GOOD T18140(normal) +1.2% T18223(normal) -17.1% GOOD T18282(normal) -5.0% GOOD T18304(normal) +10.8% BAD T18923(normal) -2.9% GOOD T1969(normal) +1.0% T19695(normal) -1.5% T20049(normal) -12.7% GOOD T21839c(normal) -4.1% GOOD T3064(normal) -1.5% T3294(normal) +1.2% BAD T4801(normal) +1.2% T5030(normal) -15.2% GOOD T5321Fun(normal) -2.2% GOOD T6048(optasm) -16.8% GOOD T783(normal) -1.2% T8095(normal) -6.0% GOOD T9630(normal) -4.7% GOOD T9961(normal) +1.9% BAD WWRec(normal) -1.4% info_table_map_perf(normal) -1.3% parsing001(normal) +1.5% geo. mean -2.0% minimum -39.7% maximum +10.8% * Runtimes generally improve. In the testsuite perf/should_run gives: Metrics: runtime/bytes allocated ------------------------------------------ Conversions(normal) -0.3% T13536a(optasm) -41.7% GOOD T4830(normal) -0.1% haddock.Cabal(normal) -0.1% haddock.base(normal) -0.1% haddock.compiler(normal) -0.1% geo. mean -0.8% minimum -41.7% maximum +0.0% * For runtime, nofib is a better test. The news is mostly good. Here are the number more than +/- 0.1%: # bytes allocated ==========================++========== imaginary/digits-of-e1 || -14.40% imaginary/digits-of-e2 || -4.41% imaginary/paraffins || -0.17% imaginary/rfib || -0.15% imaginary/wheel-sieve2 || -0.10% real/compress || -0.47% real/fluid || -0.10% real/fulsom || +0.14% real/gamteb || -1.47% real/gg || -0.20% real/infer || +0.24% real/pic || -0.23% real/prolog || -0.36% real/scs || -0.46% real/smallpt || +4.03% shootout/k-nucleotide || -20.23% shootout/n-body || -0.42% shootout/spectral-norm || -0.13% spectral/boyer2 || -3.80% spectral/constraints || -0.27% spectral/hartel/ida || -0.82% spectral/mate || -20.34% spectral/para || +0.46% spectral/rewrite || +1.30% spectral/sphere || -0.14% ==========================++========== geom mean || -0.59% real/smallpt has a huge nest of local definitions, and I could not pin down a reason for a regression. But there are three big wins! Metric Decrease: CoOpt_Singletons LargeRecord T12227 T12707 T13386 T13536a T14766 T15703 T16577 T17516 T18223 T18282 T18923 T21839c T20049 T5321Fun T5030 T6048 T8095 T9630 T783 Metric Increase: MultiLayerModulesTH_OneShot T13253-spj T18304 T18698a T9961 T3294 - - - - - 27db3c5e by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Testsuite message changes from simplifier improvements - - - - - 271a7812 by Simon Peyton Jones at 2024-04-03T01:27:55-04:00 Account for bottoming functions in OccurAnal This fixes #24582, a small but long-standing bug - - - - - 0fde229f by Ben Gamari at 2024-04-04T07:04:58-04:00 testsuite: Introduce template-haskell-exports test - - - - - 0c4a9686 by Luite Stegeman at 2024-04-04T07:05:39-04:00 Update correct counter in bumpTickyAllocd - - - - - 5f085d3a by Fendor at 2024-04-04T14:47:33-04:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. - - - - - 82cfe10c by Fendor at 2024-04-04T14:47:33-04:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. - - - - - 36a75b80 by Andrei Borzenkov at 2024-04-04T14:48:10-04:00 Change how invisible patterns represented in haskell syntax and TH AST (#24557) Before this patch: data ArgPat p = InvisPat (LHsType p) | VisPat (LPat p) With this patch: data Pat p = ... | InvisPat (LHsType p) ... And the same transformation in the TH land. The rest of the changes is just updating code to handle new AST and writing tests to check if it is possible to create invalid states using TH. Metric Increase: MultiLayerModulesTH_OneShot - - - - - 28009fbc by Matthew Pickering at 2024-04-04T14:48:46-04:00 Fix off by one error in seekBinNoExpand and seekBin - - - - - 9b9e031b by Ben Gamari at 2024-04-04T21:30:08-04:00 compiler: Allow more types in GHCForeignImportPrim For many, many years `GHCForeignImportPrim` has suffered from the rather restrictive limitation of not allowing any non-trivial types in arguments or results. This limitation was justified by the code generator allegely barfing in the presence of such types. However, this restriction appears to originate well before the NCG rewrite and the new NCG does not appear to have any trouble with such types (see the added `T24598` test). Lift this restriction. Fixes #24598. - - - - - 1324b862 by Alan Zimmerman at 2024-04-04T21:30:44-04:00 EPA: Use EpaLocation not SrcSpan in ForeignDecls This allows us to update them for makeDeltaAst in ghc-exactprint - - - - - 19883a23 by Alan Zimmerman at 2024-04-05T16:58:17-04:00 EPA: Use EpaLocation for RecFieldsDotDot So we can update it to a delta position in makeDeltaAst if needed. - - - - - e8724327 by Matthew Pickering at 2024-04-05T16:58:53-04:00 Remove accidentally committed test.hs - - - - - 88cb3e10 by Fendor at 2024-04-08T09:03:34-04:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. - - - - - f2cc1107 by Fendor at 2024-04-08T09:04:11-04:00 Never UNPACK `FastMutInt` for counting z-encoded `FastString`s In `FastStringTable`, we count the number of z-encoded FastStrings that exist in a GHC session. We used to UNPACK the counters to not waste memory, but live retainer analysis showed that we allocate a lot of `FastMutInt`s, retained by `mkFastZString`. We lazily compute the `FastZString`, only incrementing the counter when the `FastZString` is forced. The function `mkFastStringWith` calls `mkZFastString` and boxes the `FastMutInt`, leading to the following core: mkFastStringWith = \ mk_fs _ -> = case stringTable of { FastStringTable _ n_zencs segments# _ -> ... case ((mk_fs (I# ...) (FastMutInt n_zencs)) `cast` <Co:2> :: ...) ... Marking this field as `NOUNPACK` avoids this reboxing, eliminating the allocation of a fresh `FastMutInt` on every `FastString` allocation. - - - - - c6def949 by Matthew Pickering at 2024-04-08T16:06:51-04:00 Force in_multi to avoid retaining entire hsc_env - - - - - fbb91a63 by Fendor at 2024-04-08T16:06:51-04:00 Eliminate name thunk in declaration fingerprinting Thunk analysis showed that we have about 100_000 thunks (in agda and `-fwrite-simplified-core`) pointing to the name of the name decl. Forcing this thunk fixes this issue. The thunk created here is retained by the thunk created by forkM, it is better to eagerly force this because the result (a `Name`) is already retained indirectly via the `IfaceDecl`. - - - - - 3b7b0c1c by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Use EpaLocation in WarningTxt This allows us to use an EpDelta if needed when using makeDeltaAst. - - - - - 12b997df by Alan Zimmerman at 2024-04-08T16:07:27-04:00 EPA: Move DeltaPos and EpaLocation' into GHC.Types.SrcLoc This allows us to use a NoCommentsLocation for the possibly trailing comma location in a StringLiteral. This in turn allows us to correctly roundtrip via makeDeltaAst. - - - - - 868c8a78 by Fendor at 2024-04-09T08:51:50-04:00 Prefer packed representation for CompiledByteCode As there are many 'CompiledByteCode' objects alive during a GHCi session, representing its element in a more packed manner improves space behaviour at a minimal cost. When running GHCi on the agda codebase, we find around 380 live 'CompiledByteCode' objects. Packing their respective 'UnlinkedByteCode' can save quite some pointers. - - - - - be3bddde by Alan Zimmerman at 2024-04-09T08:52:26-04:00 EPA: Capture all comments in a ClassDecl Hopefully the final fix needed for #24533 - - - - - 3d0806fc by Jade at 2024-04-10T05:39:53-04:00 Validate -main-is flag using parseIdentifier Fixes #24368 - - - - - dd530bb7 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c - - - - - e008a19a by Alexis King at 2024-04-10T05:40:29-04:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) - - - - - dcfaa190 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. - - - - - 12931698 by Rodrigo Mesquita at 2024-04-10T05:40:29-04:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. - - - - - dccd3ea1 by Ben Gamari at 2024-04-10T05:40:29-04:00 testsuite: Add test for lookupSymbolInNativeObj - - - - - 1b1a92bd by Alan Zimmerman at 2024-04-10T05:41:05-04:00 EPA: Remove unnecessary XRec in CompleteMatchSig The XRec for [LIdP pass] is not needed for exact printing, remove it. - - - - - 6e18ce2b by Ben Gamari at 2024-04-12T08:16:09-04:00 users-guide: Clarify language extension documentation Over the years the users guide's language extension documentation has gone through quite a few refactorings. In the process some of the descriptions have been rendered non-sensical. For instance, the description of `NoImplicitPrelude` actually describes the semantics of `ImplicitPrelude`. To fix this we: * ensure that all extensions are named in their "positive" sense (e.g. `ImplicitPrelude` rather than `NoImplicitPrelude`). * rework the documentation to avoid flag-oriented wording like "enable" and "disable" * ensure that the polarity of the documentation is consistent with reality. Fixes #23895. - - - - - a933aff3 by Zubin Duggal at 2024-04-12T08:16:45-04:00 driver: Make `checkHomeUnitsClosed` faster The implementation of `checkHomeUnitsClosed` was traversing every single path in the unit dependency graph - this grows exponentially and quickly grows to be infeasible on larger unit dependency graphs. Instead we replace this with a faster implementation which follows from the specificiation of the closure property - there is a closure error if there are units which are both are both (transitively) depended upon by home units and (transitively) depend on home units, but are not themselves home units. To compute the set of units required for closure, we first compute the closure of the unit dependency graph, then the transpose of this closure, and find all units that are reachable from the home units in the transpose of the closure. - - - - - 23c3e624 by Andreas Klebinger at 2024-04-12T08:17:21-04:00 RTS: Emit warning when -M < -H Fixes #24487 - - - - - d23afb8c by Ben Gamari at 2024-04-12T08:17:56-04:00 testsuite: Add broken test for CApiFFI with -fprefer-bytecode See #24634. - - - - - a4bb3a51 by Ben Gamari at 2024-04-12T08:18:32-04:00 base: Deprecate GHC.Pack As proposed in #21461. Closes #21540. - - - - - 55eb8c98 by Ben Gamari at 2024-04-12T08:19:08-04:00 ghc-internal: Fix mentions of ghc-internal in deprecation warnings Closes #24609. - - - - - b0fbd181 by Ben Gamari at 2024-04-12T08:19:44-04:00 rts: Implement set_initial_registers for AArch64 Fixes #23680. - - - - - 14c9ec62 by Ben Gamari at 2024-04-12T08:20:20-04:00 ghcup-metadata: Use Debian 9 binaries on Ubuntu 16, 17 Closes #24646. - - - - - 35a1621e by Ben Gamari at 2024-04-12T08:20:55-04:00 Bump unix submodule to 2.8.5.1 Closes #24640. - - - - - a1c24df0 by Finley McIlwaine at 2024-04-12T08:21:31-04:00 Correct default -funfolding-use-threshold in docs - - - - - 0255d03c by Oleg Grenrus at 2024-04-12T08:22:07-04:00 FastString is a __Modified__ UTF-8 - - - - - c3489547 by Matthew Pickering at 2024-04-12T13:13:44-04:00 rts: Improve tracing message when nursery is resized It is sometimes more useful to know how much bigger or smaller the nursery got when it is resized. In particular I am trying to investigate situations where we end up with fragmentation due to the nursery (#24577) - - - - - 5e4f4ba8 by Simon Peyton Jones at 2024-04-12T13:14:20-04:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - 21f7be15 by Jade at 2024-04-29T19:30:13+02:00 Add four way merge to Data.List.sort(By) This patch aims to implement an improved version of Data.List.sortBy and therefore Data.List.sort which increases performance by up to 40% on larger lists, but also ~20% on lists of size 100 and smaller. This approach implements a four-way merge which also reuses comparisons. Fixes #24280 ------------------------- Metric Decrease: MultiLayerModulesTH_Make T10421 T13719 T15164 T18698a T18698b T1969 T9872a T9961 WWRec ------------------------- - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/Core.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ac6d7a2c60118e25373cd78413ec887c212d2a7...21f7be15e51650b6ad558db83ce7ec7ce5d85501 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ac6d7a2c60118e25373cd78413ec887c212d2a7...21f7be15e51650b6ad558db83ce7ec7ce5d85501 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 19:03:17 2024 From: gitlab at gitlab.haskell.org (Jade (@Jade)) Date: Mon, 29 Apr 2024 15:03:17 -0400 Subject: [Git][ghc/ghc][wip/three-way-merge-sort] Add four way merge to Data.List.sort(By) Message-ID: <662feef51c106_35c70715827fc80455@gitlab.mail> Jade pushed to branch wip/three-way-merge-sort at Glasgow Haskell Compiler / GHC Commits: 8dfe353c by Jade at 2024-04-29T21:08:08+02:00 Add four way merge to Data.List.sort(By) This patch aims to implement an improved version of Data.List.sortBy and therefore Data.List.sort which increases performance by up to 40% on larger lists, but also ~20% on lists of size 100 and smaller. This approach implements a four-way merge which also reuses comparisons. Fixes #24280 ------------------------- Metric Decrease: MultiLayerModulesTH_Make T10421 T13719 T15164 T18698a T18698b T1969 T9872a T9961 T18730 WWRec ------------------------- - - - - - 4 changed files: - libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs - + testsuite/tests/lib/base/Sort.hs - + testsuite/tests/lib/base/Sort.stdout - testsuite/tests/lib/base/all.T Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs ===================================== @@ -1640,37 +1640,98 @@ and possibly to bear similarities to a 1982 paper by Richard O'Keefe: Benchmarks show it to be often 2x the speed of the previous implementation. Fixes ticket https://gitlab.haskell.org/ghc/ghc/issues/2143 + +Further improved using a four-way merge, with an additional performance increase of ~20% +https://gitlab.haskell.org/ghc/ghc/issues/24280 -} -sort = sortBy compare -sortBy cmp = mergeAll . sequences +{-# INLINEABLE sort #-} -- allows specialization for the ord instance +sort = actualSort (>) + +{-# INLINEABLE sortBy #-} +sortBy cmp = actualSort (\x y -> cmp x y == GT) + +actualSort :: (a -> a -> Bool) -> [a] -> [a] +actualSort gt ns + | [] <- ns = [] + | [a] <- ns = [a] + | [a,b] <- ns = merge [a] [b] + | [a,b,c] <- ns = merge3 [a] [b] [c] + | [a,b,c,d] <- ns = merge4 [a] [b] [c] [d] + | otherwise = merge_all (sequences ns) where sequences (a:b:xs) - | a `cmp` b == GT = descending b [a] xs - | otherwise = ascending b (a:) xs + | a `gt` b = descending b [a] xs + | otherwise = ascending b (a:) xs sequences xs = [xs] descending a as (b:bs) - | a `cmp` b == GT = descending b (a:as) bs - descending a as bs = (a:as): sequences bs + | a `gt` b = descending b (a:as) bs + descending a as bs = (a:as): sequences bs ascending a as (b:bs) - | a `cmp` b /= GT = ascending b (\ys -> as (a:ys)) bs - ascending a as bs = let !x = as [a] - in x : sequences bs - - mergeAll [x] = x - mergeAll xs = mergeAll (mergePairs xs) - - mergePairs (a:b:xs) = let !x = merge a b - in x : mergePairs xs - mergePairs xs = xs + | not (a `gt` b) = ascending b (\ys -> as (a:ys)) bs + ascending a as bs = let !x = as [a] + in x : sequences bs + + merge_all [x] = x + merge_all xs = merge_all (reduce_once xs) + + reduce_once [] = [] + reduce_once [a] = [a] + reduce_once [a,b] = [merge a b] + reduce_once [a,b,c] = [merge3 a b c] + reduce_once [a,b,c,d,e] = [merge a b, merge3 c d e] + reduce_once [a,b,c,d,e,f] = [merge3 a b c, merge3 d e f] + reduce_once (a:b:c:d:xs) = let !x = merge4 a b c d + in x : reduce_once xs merge as@(a:as') bs@(b:bs') - | a `cmp` b == GT = b:merge as bs' - | otherwise = a:merge as' bs - merge [] bs = bs - merge as [] = as + | a `gt` b = b : merge as bs' + | otherwise = a : merge as' bs + merge [] bs = bs + merge as [] = as + + -- `merge3` is a manually fused version of `merge (merge as bs) cs` + merge3 as@(a:as') bs@(b:bs') cs + | a `gt` b = merge3X b as bs' cs + | otherwise = merge3X a as' bs cs + merge3 [] bs cs = merge bs cs + merge3 as [] cs = merge as cs + + merge3X x as bs cs@(c:cs') + | x `gt` c = c : merge3X x as bs cs' + | otherwise = x : merge3 as bs cs + merge3X x as bs [] = x : merge as bs + + merge3Y as@(a:as') y bs cs + | a `gt` y = y : merge3 as bs cs + | otherwise = a : merge3Y as' y bs cs + merge3Y [] x bs cs = x : merge bs cs + + -- `merge4 as bs cs ds` is (essentially) a manually fused version of + -- `merge (merge as bs) (merge cs ds)` + merge4 as@(a:as') bs@(b:bs') cs ds + | a `gt` b = merge4X b as bs' cs ds + | otherwise = merge4X a as' bs cs ds + merge4 [] bs cs ds = merge3 bs cs ds + merge4 as [] cs ds = merge3 as cs ds + + merge4X x as bs cs@(c:cs') ds@(d:ds') + | c `gt` d = merge4XY x as bs d cs ds' + | otherwise = merge4XY x as bs c cs' ds + merge4X x as bs [] ds = merge3X x as bs ds + merge4X x as bs cs [] = merge3X x as bs cs + + merge4Y as@(a:as') bs@(b:bs') y cs ds + | a `gt` b = merge4XY b as bs' y cs ds + | otherwise = merge4XY a as' bs y cs ds + merge4Y as [] y cs ds = merge3Y as y cs ds + merge4Y [] bs y cs ds = merge3Y bs y cs ds + + merge4XY x as bs y cs ds + | x `gt` y = y : merge4X x as bs cs ds + | otherwise = x : merge4Y as bs y cs ds {- sortBy cmp l = mergesort cmp l ===================================== testsuite/tests/lib/base/Sort.hs ===================================== @@ -0,0 +1,18 @@ +module Main where + +import Data.List (sort) +import Data.Semigroup (Arg(..)) + +main :: IO () +main = do + -- correctness + test @Int [] + test [0] + test [8, 0, 2, 3, 6, 1, 5, 10, 4, 7, 9] + + -- stability + test [Arg 1 0, Arg 0 0, Arg 0 1, Arg 1 1, Arg 0 2] + test [Arg 0 0, Arg 0 1, Arg 0 2] + +test :: (Ord a, Show a) => [a] -> IO () +test = print . sort ===================================== testsuite/tests/lib/base/Sort.stdout ===================================== @@ -0,0 +1,5 @@ +[] +[0] +[0,1,2,3,4,5,6,7,8,9,10] +[Arg 0 0,Arg 0 1,Arg 0 2,Arg 1 0,Arg 1 1] +[Arg 0 0,Arg 0 1,Arg 0 2] ===================================== testsuite/tests/lib/base/all.T ===================================== @@ -11,3 +11,4 @@ test('Monoid_ByteArray', normal, compile_and_run, ['']) test('Unsnoc', normal, compile_and_run, ['']) test('First-Semigroup-sconcat', normal, compile_and_run, ['']) test('First-Monoid-sconcat', normal, compile_and_run, ['']) +test('Sort', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8dfe353c46cd5e4d27ba646d3b9e077308d0deb9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8dfe353c46cd5e4d27ba646d3b9e077308d0deb9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 19:36:28 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 15:36:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: EPA: Preserve comments in Match Pats Message-ID: <662ff6bcb61c3_35c7071b6cfa09464@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 45c80351 by Alan Zimmerman at 2024-04-29T15:35:52-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - c79a3b65 by Sylvain Henry at 2024-04-29T15:36:05-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - 1e0d49a6 by Cheng Shao at 2024-04-29T15:36:08-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - d9a38ef8 by Matthew Pickering at 2024-04-29T15:36:08-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 10 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - hadrian/src/Rules/Compile.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28c3bccb027ebdce7df6e9b2fd87f1298742e021...d9a38ef82b4dc7c2ba64a21148c9d952950a15ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28c3bccb027ebdce7df6e9b2fd87f1298742e021...d9a38ef82b4dc7c2ba64a21148c9d952950a15ef You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 20:53:01 2024 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 29 Apr 2024 16:53:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T24741 Message-ID: <663008acf3916_35c7072572fe0115948@gitlab.mail> Ben Gamari pushed new branch wip/T24741 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24741 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 29 22:45:06 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 29 Apr 2024 18:45:06 -0400 Subject: [Git][ghc/ghc][wip/T24676] Small wibbles Message-ID: <663022f28819b_35c70732ecc201325d9@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: ac999ca4 by Simon Peyton Jones at 2024-04-29T23:44:12+01:00 Small wibbles - - - - - 3 changed files: - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -230,6 +230,17 @@ then we won't look at it at all. If it is free, then all the variables free in i kind are free -- regardless of whether some local variable has the same Unique. So if we're looking at a variable occurrence at all, then all variables in its kind are free. + +Note [Free vars and synonyms] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When finding free variables we generally do not expand synonyms. So given + type T a = Int +the type (T [b]) will return `b` as a free variable, even though expanding the +synonym would get rid of it. Expanding synonyms might lead to types that look +ill-scoped; an alternative we have not explored. + +But see `occCheckExpand` in this module for a function that does, selectively, +expand synonyms to reduce free-var occurences. -} {- ********************************************************************* @@ -319,7 +330,7 @@ deep_cos :: [Coercion] -> Endo TyCoVarSet (deep_ty, deep_tys, deep_co, deep_cos) = foldTyCo deepTcvFolder emptyVarSet deepTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet) -deepTcvFolder = TyCoFolder { tcf_view = noView +deepTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms] , tcf_tyvar = do_tcv, tcf_covar = do_tcv , tcf_hole = do_hole, tcf_tycobinder = do_bndr } where @@ -377,7 +388,7 @@ shallow_cos :: [Coercion] -> Endo TyCoVarSet (shallow_ty, shallow_tys, shallow_co, shallow_cos) = foldTyCo shallowTcvFolder emptyVarSet shallowTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet) -shallowTcvFolder = TyCoFolder { tcf_view = noView +shallowTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms] , tcf_tyvar = do_tcv, tcf_covar = do_tcv , tcf_hole = do_hole, tcf_tycobinder = do_bndr } where @@ -587,6 +598,7 @@ tyCoFVsOfType (TyVarTy v) f bound_vars (acc_list, acc_set) emptyVarSet -- See Note [Closing over free variable kinds] (v:acc_list, extendVarSet acc_set v) tyCoFVsOfType (TyConApp _ tys) f bound_vars acc = tyCoFVsOfTypes tys f bound_vars acc + -- See Note [Free vars and synonyms] tyCoFVsOfType (LitTy {}) f bound_vars acc = emptyFV f bound_vars acc tyCoFVsOfType (AppTy fun arg) f bound_vars acc = (tyCoFVsOfType fun `unionFV` tyCoFVsOfType arg) f bound_vars acc tyCoFVsOfType (FunTy _ w arg res) f bound_vars acc = (tyCoFVsOfType w `unionFV` tyCoFVsOfType arg `unionFV` tyCoFVsOfType res) f bound_vars acc @@ -944,7 +956,9 @@ invisibleVarsOfTypes = mapUnionFV invisibleVarsOfType {-# INLINE afvFolder #-} -- so that specialization to (const True) works afvFolder :: (TyCoVar -> Bool) -> TyCoFolder TyCoVarSet DM.Any -afvFolder check_fv = TyCoFolder { tcf_view = noView +-- 'afvFolder' is short for "any-free-var folder", good for checking +-- if any free var of a type satisfies a predicate `check_fv` +afvFolder check_fv = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms] , tcf_tyvar = do_tcv, tcf_covar = do_tcv , tcf_hole = do_hole, tcf_tycobinder = do_bndr } where @@ -993,12 +1007,13 @@ instance Monad m => Monoid (AnyM m) where {-# INLINE afvFolderM #-} -- so that specialization to (const True) works afvFolderM :: Monad m => (TyCoVar -> m Bool) -> TyCoFolder TyCoVarSet (AnyM m) -afvFolderM check_fv = TyCoFolder { tcf_view = noView +-- A monadic variant of `afvFolder` where the predicate is monadic +afvFolderM check_fv = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms] , tcf_tyvar = do_tv, tcf_covar = mempty , tcf_hole = mempty, tcf_tycobinder = do_bndr } where do_bndr is tcv _ = extendVarSet is tcv - do_tv is tv | tv `elemVarSet` is = AM (return False) + do_tv is tv | tv `elemVarSet` is = mempty | otherwise = AM (check_fv tv) anyFreeVarsOfTypeM :: Monad m => (TyCoVar -> m Bool) -> Type -> m Bool ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1515,7 +1515,7 @@ This turned out to be more subtle than I expected. Wrinkles: (QLA1) We avoid zonking, so quickLookArg thereby sees the argument type /before/ the QL substitution Theta is applied to it. So we achieve argument-order - independence for free (see 5.7 in the paper). See the `guarded` predictate + independence for free (see 5.7 in the paper). See the `guarded` predicate in `quickLookArg`. (QLA2) `quickLookArg` decides whether or not premises (A) and (B) of the @@ -1544,7 +1544,7 @@ This turned out to be more subtle than I expected. Wrinkles: (QLA4) When we resume typechecking an argument, in `tcValArg`, it's fairly easy if eaql_status=QLUnified (see (QLA2)). But for QLIndependent things - are a bit tricky; see function `resume_ql-arg`: + are a bit tricky; see function `resume_ql_arg`: - quickLookArg has not yet done `qlUnify` with the calling context. We must do so now. Example: choose [] ids, @@ -1565,7 +1565,7 @@ This turned out to be more subtle than I expected. Wrinkles: EValArgQL. We carefully kept those kappas, and we now /demote/ them to the ambient level with `demoteQLDelta`. - The demotion seems right butis not very beautiful; e.g. `demoteDeltaTyVarTo` + The demotion seems right but is not very beautiful; e.g. `demoteDeltaTyVarTo` deliberately disobeys a sanity check otherwise enforced by writeMetaTyVar. -} ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -2465,17 +2465,15 @@ demoteQLDelta :: TcTyVarSet -> TcM () -- See Note [Quick Look at value arguments] wrinkle (QLA4) -- in GHC.Tc.Gen.App demoteQLDelta delta - | null tvs - = return () - | otherwise - = do { tclvl <- getTcLevel - ; assertPpr (isMetaTyVar tv1) (ppr delta) $ - when (tclvl `strictlyDeeperThan` tcTyVarLevel tv1) $ - mapM_ (demoteDeltaTyVarTo tclvl) tvs } + = case tvs of + [] -> return () + (tv1:_) -> do { tclvl <- getTcLevel + ; assertPpr (isMetaTyVar tv1) (ppr delta) $ + when (tclvl `strictlyDeeperThan` tcTyVarLevel tv1) $ + mapM_ (demoteDeltaTyVarTo tclvl) tvs } where - tv1 = head tvs tvs = nonDetEltsUniqSet delta - -- Non-determinism is OK because order of promotion doesn't matter + -- Non-determinism is OK because order of demotion doesn't matter {- %************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ac999ca4e4ecda1bd6e8077ccfff4fdbca50b0b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ac999ca4e4ecda1bd6e8077ccfff4fdbca50b0b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:16:52 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:16:52 -0400 Subject: [Git][ghc/ghc][master] Make read accepts binary integer formats Message-ID: <663062a47cb1b_35c70752997801449f9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 7 changed files: - docs/users_guide/bugs.rst - libraries/base/changelog.md - libraries/base/tests/char001.hs - libraries/base/tests/char001.stdout - libraries/base/tests/lex001.hs - libraries/base/tests/lex001.stdout - libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs Changes: ===================================== docs/users_guide/bugs.rst ===================================== @@ -445,15 +445,15 @@ In ``Prelude`` support ``Read``\ ing integers GHC's implementation of the ``Read`` class for integral types - accepts hexadecimal and octal literals (the code in the Haskell 98 + accepts hexadecimal, octal and binary literals (the code in the Haskell 98 report doesn't). So, for example, :: read "0xf00" :: Int works in GHC. - A possible reason for this is that ``readLitChar`` accepts hex and - octal escapes, so it seems inconsistent not to do so for integers + This is to maintain consistency with the language's syntax. Haskell98 + accepts hexadecimal and octal formats, and GHC2021 accepts binary formats too. ``isAlpha`` ===================================== libraries/base/changelog.md ===================================== @@ -3,6 +3,7 @@ ## 4.21.0.0 *TBA* * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) + * Make `read` accept binary integer notation ([CLC proposal #177](https://github.com/haskell/core-libraries-committee/issues/177)) ## 4.20.0.0 *TBA* * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) ===================================== libraries/base/tests/char001.hs ===================================== @@ -1,7 +1,8 @@ -- !!! Testing the behaviour of Char.lexLitChar a little.. --- [March 2003] We now allow \X and \O as escapes although the --- spec only permits \x and \o. Seems more consistent. +-- [March 2003] We now allow \X and \O as escapes although the +-- spec only permits \x and \o. Seems more consistent. +-- [January 2024] Binary character literals, something like '\b100' are not permitted. module Main where @@ -33,9 +34,15 @@ octs = do lex' "'\\o14b'" lex' "'\\0a4bg'" +-- Binaries are NOT supported. '\b' stands for backspace. +bins = do + lex' "'\\b'" + lex' "'\\b00'" + main = do hexes octs + bins ===================================== libraries/base/tests/char001.stdout ===================================== @@ -16,3 +16,5 @@ lex '\O000024' = [("'\\O000024'","")] lex '\024b' = [] lex '\o14b' = [] lex '\0a4bg' = [] +lex '\b' = [("'\\b'","")] +lex '\b00' = [] ===================================== libraries/base/tests/lex001.hs ===================================== @@ -27,7 +27,23 @@ testStrings "035e-3x", "35e+3y", "83.3e-22", - "083.3e-22" + "083.3e-22", + + "0b001", + "0b100", + "0b110", + "0B001", + "0B100", + "0B110", + + "78_91", + "678_346", + "0x23d_fa4", + "0X23d_fa4", + "0o01_253", + "0O304_367", + "0b0101_0110", + "0B11_010_0110" ] main = mapM test testStrings ===================================== libraries/base/tests/lex001.stdout ===================================== @@ -82,3 +82,58 @@ [("083.3e-22","")] [(Number (MkDecimal [0,8,3] (Just [3]) (Just (-22))),"")] +"0b001" +[("0b001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0b100" +[("0b100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0b110" +[("0b110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"0B001" +[("0B001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0B100" +[("0B100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0B110" +[("0B110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"78_91" +[("78","_91")] +[(Number (MkDecimal [7,8] Nothing Nothing),"_91")] + +"678_346" +[("678","_346")] +[(Number (MkDecimal [6,7,8] Nothing Nothing),"_346")] + +"0x23d_fa4" +[("0x23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0X23d_fa4" +[("0X23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0o01_253" +[("0o01","_253")] +[(Number (MkNumber 8 [0,1]),"_253")] + +"0O304_367" +[("0O304","_367")] +[(Number (MkNumber 8 [3,0,4]),"_367")] + +"0b0101_0110" +[("0b0101","_0110")] +[(Number (MkNumber 2 [0,1,0,1]),"_0110")] + +"0B11_010_0110" +[("0B11","_010_0110")] +[(Number (MkNumber 2 [1,1]),"_010_0110")] ===================================== libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs ===================================== @@ -300,6 +300,17 @@ lexCharE = n <- lexInteger base guard (n <= toInteger (ord maxBound)) return (chr (fromInteger n)) + where + -- Slightly different variant of lexBaseChar that denies binary format. + -- Binary formats are not allowed for character/string literal. + lexBaseChar = do + c <- get + case c of + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexCntrlChar = do _ <- char '^' @@ -415,27 +426,28 @@ type Digits = [Int] lexNumber :: ReadP Lexeme lexNumber - = lexHexOct <++ -- First try for hex or octal 0x, 0o etc + = lexHexOctBin <++ -- First try for hex, octal or binary 0x, 0o, 0b etc -- If that fails, try for a decimal number lexDecNumber -- Start with ordinary digits -lexHexOct :: ReadP Lexeme -lexHexOct +lexHexOctBin :: ReadP Lexeme +lexHexOctBin = do _ <- char '0' base <- lexBaseChar digits <- lexDigits base return (Number (MkNumber base digits)) - -lexBaseChar :: ReadP Int --- Lex a single character indicating the base; fail if not there -lexBaseChar = do - c <- get - case c of - 'o' -> return 8 - 'O' -> return 8 - 'x' -> return 16 - 'X' -> return 16 - _ -> pfail + where + -- Lex a single character indicating the base; fail if not there + lexBaseChar = do + c <- get + case c of + 'b' -> return 2 + 'B' -> return 2 + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexDecNumber :: ReadP Lexeme lexDecNumber = View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2094df3ff64fa043d990d33592982cf61330c27 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2094df3ff64fa043d990d33592982cf61330c27 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:17:46 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:17:46 -0400 Subject: [Git][ghc/ghc][master] EPA: Preserve comments in Match Pats Message-ID: <663062da3e0d4_35c707545dfd015215c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 6 changed files: - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c2fd963d6fd78d1c752a21348c7db85f5d64df2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c2fd963d6fd78d1c752a21348c7db85f5d64df2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:18:45 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:18:45 -0400 Subject: [Git][ghc/ghc][master] LLVM: better unreachable default destination in Switch (#24717) Message-ID: <66306315e2cc8_35c70755bffb8157882@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - 1 changed file: - compiler/GHC/CmmToLlvm/CodeGen.hs Changes: ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4189d17e45ceb9ae9be000894f0b4ea20d4ae372 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4189d17e45ceb9ae9be000894f0b4ea20d4ae372 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:19:44 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:19:44 -0400 Subject: [Git][ghc/ghc][master] ci: enable wasm jobs for MRs with wasm label Message-ID: <663063504b243_35c7075931b8816087e@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 2 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3725c88c109641dd4249b9b178c997483c0a760 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3725c88c109641dd4249b9b178c997483c0a760 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:20:04 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:20:04 -0400 Subject: [Git][ghc/ghc][master] Make interface files and object files depend on inplace .conf file Message-ID: <663063642f49d_35c70759c85601610e7@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 1 changed file: - hadrian/src/Rules/Compile.hs Changes: ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/702f7964373d9ffb1d550ee714bd723d8bb0c1a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/702f7964373d9ffb1d550ee714bd723d8bb0c1a3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 03:50:56 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 29 Apr 2024 23:50:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: EPA: Preserve comments in Match Pats Message-ID: <66306aa0e8a8c_35c7075f7e5f41666f2@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 51385b33 by Cheng Shao at 2024-04-29T23:50:10-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 2b0c0ee4 by Cheng Shao at 2024-04-29T23:50:11-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - 0ef9a788 by Ben Gamari at 2024-04-29T23:50:12-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 15 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - config.guess - config.sub - hadrian/src/Rules/Compile.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs - − utils/vagrant/bootstrap-deb.sh - − utils/vagrant/bootstrap-rhel.sh Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== config.guess ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-05-25' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +910,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +972,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1068,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1191,7 +1232,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1373,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1554,6 +1595,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? ===================================== config.sub ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1190,7 +1191,7 @@ case $cpu-$vendor in | arc | arceb | arc32 | arc64 \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ - | asmjs | javascript \ + | asmjs \ | ba \ | be32 | be64 \ | bfin | bpf | bs2000 \ @@ -1199,50 +1200,29 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64eb | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r3 | mipsisa32r3el \ - | mipsisa32r5 | mipsisa32r5el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r3 | mipsisa64r3el \ - | mipsisa64r5 | mipsisa64r5el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ + | nanomips* \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ @@ -1274,6 +1254,7 @@ case $cpu-$vendor in | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ + | vc4 \ | visium \ | w65 \ | wasm32 | wasm64 \ @@ -1285,7 +1266,7 @@ case $cpu-$vendor in ;; *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1287,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1323,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1492,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; esac ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; *) # No normalization, but not necessarily accepted, that comes below. ;; @@ -1528,12 +1520,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1538,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1588,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; - mips*-*) - os=elf + mips*-*|nanomips*-*) + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1614,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1696,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,14 +1719,11 @@ esac fi -# Now, validate our (potentially fixed-up) OS. -case $os in - # GHC specific: added for JS backend support - js | ghcjs) - ;; +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - # Sometimes we do "kernel-abi", so those need to count as OSes. - musl* | newlib* | relibc* | uclibc*) +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) ;; # Likewise for "kernel-abi" eabi* | gnueabi*) @@ -1724,6 +1731,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. @@ -1732,7 +1742,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1741,11 +1751,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1758,49 +1768,116 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; none) ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1883,7 +1960,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing ===================================== utils/vagrant/bootstrap-deb.sh deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -apt-get update -apt-get build-dep -y ghc ===================================== utils/vagrant/bootstrap-rhel.sh deleted ===================================== @@ -1,4 +0,0 @@ -#!/bin/sh -yum update -y -yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool \ - gcc make python ghc git View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d9a38ef82b4dc7c2ba64a21148c9d952950a15ef...0ef9a788561644ee458075c200c0d45a57c68ef6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d9a38ef82b4dc7c2ba64a21148c9d952950a15ef...0ef9a788561644ee458075c200c0d45a57c68ef6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 05:46:53 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Tue, 30 Apr 2024 01:46:53 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/mksolo-hash] Rename Solo# data constructor to MkSolo# (#24673) Message-ID: <663085cd73067_35c7076cad374170761@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/mksolo-hash at Glasgow Haskell Compiler / GHC Commits: e5c67ff7 by Andrei Borzenkov at 2024-04-30T09:46:28+04:00 Rename Solo# data constructor to MkSolo# (#24673) - data Solo# a = (# a #) + data Solo# a = MkSolo# a And `(# foo #)` syntax now becomes just a syntactic sugar for `MkSolo# a`. - - - - - 14 changed files: - compiler/GHC/Builtin/Types.hs - libraries/ghc-boot/GHC/Utils/Encoding.hs - libraries/ghc-experimental/src/Data/Tuple/Experimental.hs - libraries/ghc-prim/GHC/Types.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghci/scripts/ListTuplePunsPpr.script - testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - + testsuite/tests/rename/should_fail/T24673.hs - + testsuite/tests/rename/should_fail/T24673.stderr - testsuite/tests/rename/should_fail/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/th/TH_tuple1.stdout Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -1015,7 +1015,7 @@ mkUnboxedTupleStr ns 0 | isDataConNameSpace ns = "(##)" | otherwise = "Unit#" mkUnboxedTupleStr ns 1 - | isDataConNameSpace ns = "(# #)" -- See Note [One-tuples] + | isDataConNameSpace ns = "MkSolo#" -- See Note [One-tuples] | otherwise = "Solo#" mkUnboxedTupleStr ns ar | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)" ===================================== libraries/ghc-boot/GHC/Utils/Encoding.hs ===================================== @@ -79,7 +79,7 @@ The basic encoding scheme is this. :+ ZCzp () Z0T 0-tuple (,,,,) Z5T 5-tuple - (# #) Z1H unboxed 1-tuple (note the space) + (##) Z0H unboxed 0-tuple (#,,,,#) Z5H unboxed 5-tuple -} @@ -212,7 +212,6 @@ decode_tuple d rest go n (c : rest) | isDigit c = go (10*n + digitToInt c) rest go 0 ('T':rest) = "()" ++ zDecodeString rest go n ('T':rest) = '(' : replicate (n-1) ',' ++ ")" ++ zDecodeString rest - go 1 ('H':rest) = "(# #)" ++ zDecodeString rest go n ('H':rest) = '(' : '#' : replicate (n-1) ',' ++ "#)" ++ zDecodeString rest go n other = error ("decode_tuple: " ++ show n ++ ' ':other) @@ -223,15 +222,13 @@ for 3-tuples or unboxed 3-tuples respectively. No other encoding starts Z * "(##)" is the tycon for an unboxed 0-tuple -* "(# #)" is the tycon for an unboxed 1-tuple -* "()" is the tycon for a boxed 0-tuple. +* "()" is the tycon for a boxed 0-tuple -} maybe_tuple :: UserString -> Maybe EncodedString maybe_tuple "(##)" = Just("Z0H") -maybe_tuple "(# #)" = Just("Z1H") maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H") _ -> Nothing ===================================== libraries/ghc-experimental/src/Data/Tuple/Experimental.hs ===================================== @@ -21,7 +21,7 @@ module Data.Tuple.Experimental ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -65,7 +65,7 @@ module GHC.Types ( -- * Unboxed tuples Unit#, - Solo#, + Solo#(..), Tuple0#, Tuple1#, Tuple2#, @@ -889,7 +889,7 @@ type Unit# :: TYPE (TupleRep '[]) data Unit# = (# #) type Solo# :: TYPE rep -> TYPE (TupleRep '[rep]) -data Solo# a = (# a #) +data Solo# a = MkSolo# a type Tuple0# = Unit# type Tuple1# = Solo# ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -1938,10 +1938,7 @@ mk_tup_name n space boxed solo | space == DataName = "MkSolo" | otherwise = "Solo" - - unboxed_solo - | space == DataName = "(# #)" - | otherwise = "Solo#" + unboxed_solo = solo ++ "#" -- Unboxed sum data and type constructors -- | Unboxed sum data constructor ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -24,7 +24,7 @@ T15226b.testFun1 case y of conrep { __DEFAULT -> case T15226b.MkStrictPair [sat conrep] of sat { - __DEFAULT -> (# #) [sat]; + __DEFAULT -> MkSolo# [sat]; }; }; }; ===================================== testsuite/tests/ghci/scripts/ListTuplePunsPpr.script ===================================== @@ -1,6 +1,7 @@ -:set -XUnboxedTuples -XNoListTuplePuns -XDataKinds +:set -XUnboxedTuples -XMagicHash -XNoListTuplePuns -XDataKinds import GHC.Tuple (Solo (MkSolo)) +import Data.Tuple.Experimental (Solo# (MkSolo#)) :i () :i (##) @@ -26,3 +27,5 @@ f i (j, k) = i + j + k :: Int :t f :t (\ (_, _) -> ()) :t (\ (MkSolo _) -> ()) +:i Solo# +:t MkSolo# ===================================== testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout ===================================== @@ -75,13 +75,18 @@ data Tuple2# a b = (#,#) a b (Int, Int) :: Tuple2 (*) (*) type T :: Tuple2 (*) (*) type T = (Int, Int) :: Tuple2 (*) (*) - -- Defined at :18:1 + -- Defined at :19:1 type S :: Solo (*) type S = MkSolo Int :: Solo (*) - -- Defined at :19:1 + -- Defined at :20:1 type L :: List (*) type L = [Int] :: List (*) - -- Defined at :20:1 + -- Defined at :21:1 f :: Int -> Tuple2 Int Int -> Int (\ (_, _) -> ()) :: Tuple2 a b -> Unit (\ (MkSolo _) -> ()) :: Solo a -> Unit +type Solo# :: * -> TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) +data Solo# a = MkSolo# a + -- Defined in ‘GHC.Types’ + +MkSolo# :: a -> Solo# a ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -2633,7 +2633,7 @@ module Data.Tuple.Experimental where type Solo :: * -> * data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) - data Solo# a = ... + data Solo# a = MkSolo# a type Tuple0 :: * type Tuple0 = () type Tuple0# :: GHC.Types.ZeroBitType ===================================== testsuite/tests/rename/should_fail/T24673.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE UnboxedTuples, MagicHash, NoListTuplePuns #-} + +module T24673 where + +import Data.Tuple.Experimental + + +f = (# 42 #) + MkSolo# 42 ===================================== testsuite/tests/rename/should_fail/T24673.stderr ===================================== @@ -0,0 +1,20 @@ + +T24673.hs:8:5: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a0 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the first argument of ‘(+)’, namely ‘(# 42 #)’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) + +T24673.hs:8:16: error: [GHC-18872] + • Couldn't match a lifted type with an unlifted type + When matching types + a :: * + (# a1 #) :: TYPE (GHC.Types.TupleRep [GHC.Types.LiftedRep]) + • In the second argument of ‘(+)’, namely ‘MkSolo# 42’ + In the expression: (# 42 #) + MkSolo# 42 + In an equation for ‘f’: f = (# 42 #) + MkSolo# 42 + • Relevant bindings include f :: a (bound at T24673.hs:8:1) ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -227,3 +227,4 @@ test('T23570b', [extra_files(['T23570_aux.hs'])], multimod_compile, ['T23570b', test('T17594b', req_th, compile_fail, ['']) test('T14032c', normal, compile_fail, ['']) test('T14032f', normal, compile_fail, ['']) +test('T24673', normal, compile_fail, ['']) ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -20,7 +20,7 @@ T15226b.bar1 sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId] = T15226b.Str! [sat]; - } in (# #) [sat]; + } in MkSolo# [sat]; }; T15226b.bar ===================================== testsuite/tests/th/TH_tuple1.stdout ===================================== @@ -6,5 +6,5 @@ GHC.Tuple.MkSolo 1 :: GHC.Tuple.Solo GHC.Num.Integer.Integer SigE (AppE (AppE (ConE GHC.Types.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Types.Tuple2#) (ConT GHC.Num.Integer.Integer)) (ConT GHC.Num.Integer.Integer)) GHC.Types.(#,#) 1 2 :: GHC.Types.Tuple2# GHC.Num.Integer.Integer GHC.Num.Integer.Integer -SigE (AppE (ConE GHC.Types.(# #)) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) -GHC.Types.(# #) 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer +SigE (AppE (ConE GHC.Types.MkSolo#) (LitE (IntegerL 1))) (AppT (ConT GHC.Types.Solo#) (ConT GHC.Num.Integer.Integer)) +GHC.Types.MkSolo# 1 :: GHC.Types.Solo# GHC.Num.Integer.Integer View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5c67ff742b8dfdce1fbd6db540d2fb8da0cb5f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5c67ff742b8dfdce1fbd6db540d2fb8da0cb5f1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 06:35:23 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Tue, 30 Apr 2024 02:35:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sand-witch/pun-occ-doc Message-ID: <6630912b3d0c_35c707726eb781725c0@gitlab.mail> Andrei Borzenkov pushed new branch wip/sand-witch/pun-occ-doc at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sand-witch/pun-occ-doc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 06:38:19 2024 From: gitlab at gitlab.haskell.org (Andrei Borzenkov (@sand-witch)) Date: Tue, 30 Apr 2024 02:38:19 -0400 Subject: [Git][ghc/ghc][wip/sand-witch/pun-occ-doc] Doccumenting difference between isPunOcc_maybe and isBuiltInOcc_maybe Message-ID: <663091db5d193_35c70772eab101727e9@gitlab.mail> Andrei Borzenkov pushed to branch wip/sand-witch/pun-occ-doc at Glasgow Haskell Compiler / GHC Commits: 38ab4b47 by Andrei Borzenkov at 2024-04-30T10:38:06+04:00 Doccumenting difference between isPunOcc_maybe and isBuiltInOcc_maybe - - - - - 1 changed file: - compiler/GHC/Builtin/Types.hs Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -820,6 +820,8 @@ known-key is the next-best way to teach the internals of the compiler about it. -- -- Moreover, there is no need to include names of things that the user can't -- write (e.g. type representation bindings like $tc(,,,)). +-- +-- Want to add a new case? See Note [isBuiltInOcc_maybe and isPunOcc_maybe] first! isBuiltInOcc_maybe :: OccName -> Maybe Name isBuiltInOcc_maybe occ = case name of @@ -964,6 +966,45 @@ To parse strings of length 1 and 2 more efficiently, we can utilize an ad-hoc solution that matches their characters. This results in a speedup of up to 40 times compared to using `readMaybe @Int` on my machine. + +Note [isBuiltInOcc_maybe and isPunOcc_maybe] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some OccNames are special: + +* `isBuiltInOcc_maybe` is true of OccNames that are built-in + syntax, such as `[]`, `->`, `()`, `(,,)`, etc. These are OccNames, + but because they are built-in syntax they behaved specially: + * They stand for a unique thing. E.g. `[]` denotes the + empty-list data constructor, defined in a single, unique + place known to GHC. + + * They are always in scope. So `[]` stands for the empty + list, always and everywhere. + + * They cannot be imported or exported; nor can they be redefined + in other modules. + + * They get special errors in some cases, e.g. see `guard_builtin_syntax` in + `GHC.Rename.Env.lookupLocalTcName` + + * Some of them form an infinite family, such as `(,)`, `(,,)`, `(,,,)`, ..etc.. + We do not populate the Original Name Cache (see Note + [Built-in syntax and the OrigNameCache]) with these OccNames, + partly because the family is infinite, but also just to avoid + unncessarily bloating the cache. Instead, when looking up in + the Original Name Cache we check for `isBuiltInOcc_maybe` + first (see `lookupOrigNameCache`). + +* `isPunOcc_maybe` is used for a few infinite families of OccNames, + simply to avoid bloating the Original Name Cache. + * Examples: `Tuple3`, `Tuple4` etc + + * Unlike `isBuiltInOcc_maybe`, these OccNames are not built-in syntax: + they can be imported, exported, and even redefined in other modules e.g. + module MyMod where { type Tuple4 = Int } + + * The /only/ special thing about `isPunOcc_maybe` OccNames is that they + don't pollute the Original Name Cache. -} -- When resolving names produced by Template Haskell (see thOrigRdrName @@ -975,6 +1016,7 @@ This results in a speedup of up to 40 times compared to using -- -- Test case: th/T13776 -- +-- Want to add a new case? See Note [isBuiltInOcc_maybe and isPunOcc_maybe] first! isPunOcc_maybe :: Module -> OccName -> Maybe Name isPunOcc_maybe mod occ | mod == gHC_TYPES, occ == occName listTyConName View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/38ab4b4778478b7cc75a5f2f2277a3911f185adf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/38ab4b4778478b7cc75a5f2f2277a3911f185adf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 07:48:07 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 30 Apr 2024 03:48:07 -0400 Subject: [Git][ghc/ghc][wip/az/T24714-GADT-sig-only-span] 6 commits: Make read accepts binary integer formats Message-ID: <6630a23766c5b_35c7077b00a201806a8@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T24714-GADT-sig-only-span at Glasgow Haskell Compiler / GHC Commits: e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - b62b36b4 by Alan Zimmerman at 2024-04-30T08:45:58+01:00 EPA: Fix range for GADT decl with sig only Closes #24714 - - - - - 19 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - docs/users_guide/bugs.rst - hadrian/src/Rules/Compile.hs - libraries/base/changelog.md - libraries/base/tests/char001.hs - libraries/base/tests/char001.stdout - libraries/base/tests/lex001.hs - libraries/base/tests/lex001.stdout - libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs - + testsuite/tests/printer/DataDeclShort.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - utils/check-exact/Main.hs Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Parser.y ===================================== @@ -1303,7 +1303,7 @@ ty_decl :: { LTyClDecl GhcPs } | type_data_or_newtype capi_ctype tycl_hdr opt_kind_sig gadt_constrlist maybe_derivings - {% mkTyData (comb4 $1 $3 $5 $6) (sndOf3 $ unLoc $1) (thdOf3 $ unLoc $1) $2 $3 + {% mkTyData (comb5 $1 $3 $4 $5 $6) (sndOf3 $ unLoc $1) (thdOf3 $ unLoc $1) $2 $3 (snd $ unLoc $4) (snd $ unLoc $5) (fmap reverse $6) ((fstOf3 $ unLoc $1)++(fst $ unLoc $4)++(fst $ unLoc $5)) } ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== docs/users_guide/bugs.rst ===================================== @@ -445,15 +445,15 @@ In ``Prelude`` support ``Read``\ ing integers GHC's implementation of the ``Read`` class for integral types - accepts hexadecimal and octal literals (the code in the Haskell 98 + accepts hexadecimal, octal and binary literals (the code in the Haskell 98 report doesn't). So, for example, :: read "0xf00" :: Int works in GHC. - A possible reason for this is that ``readLitChar`` accepts hex and - octal escapes, so it seems inconsistent not to do so for integers + This is to maintain consistency with the language's syntax. Haskell98 + accepts hexadecimal and octal formats, and GHC2021 accepts binary formats too. ``isAlpha`` ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). ===================================== libraries/base/changelog.md ===================================== @@ -3,6 +3,7 @@ ## 4.21.0.0 *TBA* * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) + * Make `read` accept binary integer notation ([CLC proposal #177](https://github.com/haskell/core-libraries-committee/issues/177)) ## 4.20.0.0 *TBA* * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) ===================================== libraries/base/tests/char001.hs ===================================== @@ -1,7 +1,8 @@ -- !!! Testing the behaviour of Char.lexLitChar a little.. --- [March 2003] We now allow \X and \O as escapes although the --- spec only permits \x and \o. Seems more consistent. +-- [March 2003] We now allow \X and \O as escapes although the +-- spec only permits \x and \o. Seems more consistent. +-- [January 2024] Binary character literals, something like '\b100' are not permitted. module Main where @@ -33,9 +34,15 @@ octs = do lex' "'\\o14b'" lex' "'\\0a4bg'" +-- Binaries are NOT supported. '\b' stands for backspace. +bins = do + lex' "'\\b'" + lex' "'\\b00'" + main = do hexes octs + bins ===================================== libraries/base/tests/char001.stdout ===================================== @@ -16,3 +16,5 @@ lex '\O000024' = [("'\\O000024'","")] lex '\024b' = [] lex '\o14b' = [] lex '\0a4bg' = [] +lex '\b' = [("'\\b'","")] +lex '\b00' = [] ===================================== libraries/base/tests/lex001.hs ===================================== @@ -27,7 +27,23 @@ testStrings "035e-3x", "35e+3y", "83.3e-22", - "083.3e-22" + "083.3e-22", + + "0b001", + "0b100", + "0b110", + "0B001", + "0B100", + "0B110", + + "78_91", + "678_346", + "0x23d_fa4", + "0X23d_fa4", + "0o01_253", + "0O304_367", + "0b0101_0110", + "0B11_010_0110" ] main = mapM test testStrings ===================================== libraries/base/tests/lex001.stdout ===================================== @@ -82,3 +82,58 @@ [("083.3e-22","")] [(Number (MkDecimal [0,8,3] (Just [3]) (Just (-22))),"")] +"0b001" +[("0b001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0b100" +[("0b100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0b110" +[("0b110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"0B001" +[("0B001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0B100" +[("0B100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0B110" +[("0B110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"78_91" +[("78","_91")] +[(Number (MkDecimal [7,8] Nothing Nothing),"_91")] + +"678_346" +[("678","_346")] +[(Number (MkDecimal [6,7,8] Nothing Nothing),"_346")] + +"0x23d_fa4" +[("0x23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0X23d_fa4" +[("0X23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0o01_253" +[("0o01","_253")] +[(Number (MkNumber 8 [0,1]),"_253")] + +"0O304_367" +[("0O304","_367")] +[(Number (MkNumber 8 [3,0,4]),"_367")] + +"0b0101_0110" +[("0b0101","_0110")] +[(Number (MkNumber 2 [0,1,0,1]),"_0110")] + +"0B11_010_0110" +[("0B11","_010_0110")] +[(Number (MkNumber 2 [1,1]),"_010_0110")] ===================================== libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs ===================================== @@ -300,6 +300,17 @@ lexCharE = n <- lexInteger base guard (n <= toInteger (ord maxBound)) return (chr (fromInteger n)) + where + -- Slightly different variant of lexBaseChar that denies binary format. + -- Binary formats are not allowed for character/string literal. + lexBaseChar = do + c <- get + case c of + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexCntrlChar = do _ <- char '^' @@ -415,27 +426,28 @@ type Digits = [Int] lexNumber :: ReadP Lexeme lexNumber - = lexHexOct <++ -- First try for hex or octal 0x, 0o etc + = lexHexOctBin <++ -- First try for hex, octal or binary 0x, 0o, 0b etc -- If that fails, try for a decimal number lexDecNumber -- Start with ordinary digits -lexHexOct :: ReadP Lexeme -lexHexOct +lexHexOctBin :: ReadP Lexeme +lexHexOctBin = do _ <- char '0' base <- lexBaseChar digits <- lexDigits base return (Number (MkNumber base digits)) - -lexBaseChar :: ReadP Int --- Lex a single character indicating the base; fail if not there -lexBaseChar = do - c <- get - case c of - 'o' -> return 8 - 'O' -> return 8 - 'x' -> return 16 - 'X' -> return 16 - _ -> pfail + where + -- Lex a single character indicating the base; fail if not there + lexBaseChar = do + c <- get + case c of + 'b' -> return 2 + 'B' -> return 2 + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexDecNumber :: ReadP Lexeme lexDecNumber = ===================================== testsuite/tests/printer/DataDeclShort.hs ===================================== @@ -0,0 +1,8 @@ +module DataDeclShort where + +data GenericOptions + :: fieldLabelModifier + -> tagSingleConstructors + -> Type + +x = 1 ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,13 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs + +.PHONY: DataDeclShort +DataDeclShort: + $(CHECK_PPR) $(LIBDIR) DataDeclShort.hs + $(CHECK_EXACT) $(LIBDIR) DataDeclShort.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,5 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) +test('DataDeclShort', [ignore_stderr, req_ppr_deps], makefile_test, ['DataDeclShort']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/424d88298893756dc3c18796e43807bfcb5e82a2...b62b36b4544b0c3a4266280285461aaf59b158e7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/424d88298893756dc3c18796e43807bfcb5e82a2...b62b36b4544b0c3a4266280285461aaf59b158e7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:02:46 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 05:02:46 -0400 Subject: [Git][ghc/ghc][wip/T24726] 10 commits: ghc-internal: add MonadFix instance for (,) Message-ID: <6630b3b6cf9a3_574539fc2d435123@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24726 at Glasgow Haskell Compiler / GHC Commits: a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 8b3508d7 by Simon Peyton Jones at 2024-04-30T10:02:16+01:00 Track in-scope variables in ruleCheckProgram This small patch fixes #24726, by tracking in-scope variables properly in -drule-check. Not hard to do! - - - - - 125f97e2 by Simon Peyton Jones at 2024-04-30T10:02:16+01:00 Add a couple more HasCallStack constraints in SimpleOpt Just for debugging, no effect on normal code - - - - - d5d664bd by Simon Peyton Jones at 2024-04-30T10:02:16+01:00 Add comments to Prep.hs This documentation patch fixes a TODO left over from !12364 - - - - - 29 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - distrib/configure.ac.in - docs/users_guide/bugs.rst - hadrian/src/Rules/Compile.hs - libraries/base/changelog.md - libraries/base/tests/char001.hs - libraries/base/tests/char001.stdout - libraries/base/tests/lex001.hs - libraries/base/tests/lex001.stdout - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - + testsuite/tests/simplCore/should_compile/T24726.hs - + testsuite/tests/simplCore/should_compile/T24726.stderr - testsuite/tests/simplCore/should_compile/all.T - utils/check-exact/Main.hs Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -47,7 +47,7 @@ import GHC.Driver.Ppr( showSDoc ) import GHC.Core -- All of it import GHC.Core.Subst import GHC.Core.SimpleOpt ( exprIsLambda_maybe ) -import GHC.Core.FVs ( exprFreeVars, exprsFreeVars, bindFreeVars +import GHC.Core.FVs ( exprFreeVars, bindFreeVars , rulesFreeVarsDSet, exprsOrphNames ) import GHC.Core.Utils ( exprType, mkTick, mkTicks , stripTicksTopT, stripTicksTopE @@ -1887,41 +1887,59 @@ ruleCheckProgram ropts phase rule_pat rules binds vcat [ p $$ line | p <- bagToList results ] ] where + line = text (replicate 20 '-') env = RuleCheckEnv { rc_is_active = isActive phase , rc_id_unf = idUnfolding -- Not quite right -- Should use activeUnfolding , rc_pattern = rule_pat , rc_rules = rules , rc_ropts = ropts - } - results = unionManyBags (map (ruleCheckBind env) binds) - line = text (replicate 20 '-') + , rc_in_scope = emptyInScopeSet } + + results = go env binds + + go _ [] = emptyBag + go env (bind:binds) = let (env', ds) = ruleCheckBind env bind + in ds `unionBags` go env' binds + +data RuleCheckEnv = RuleCheckEnv + { rc_is_active :: Activation -> Bool + , rc_id_unf :: IdUnfoldingFun + , rc_pattern :: String + , rc_rules :: Id -> [CoreRule] + , rc_ropts :: RuleOpts + , rc_in_scope :: InScopeSet } + +extendInScopeRC :: RuleCheckEnv -> Var -> RuleCheckEnv +extendInScopeRC env@(RuleCheckEnv { rc_in_scope = in_scope }) v + = env { rc_in_scope = in_scope `extendInScopeSet` v } -data RuleCheckEnv = RuleCheckEnv { - rc_is_active :: Activation -> Bool, - rc_id_unf :: IdUnfoldingFun, - rc_pattern :: String, - rc_rules :: Id -> [CoreRule], - rc_ropts :: RuleOpts -} +extendInScopeListRC :: RuleCheckEnv -> [Var] -> RuleCheckEnv +extendInScopeListRC env@(RuleCheckEnv { rc_in_scope = in_scope }) vs + = env { rc_in_scope = in_scope `extendInScopeSetList` vs } -ruleCheckBind :: RuleCheckEnv -> CoreBind -> Bag SDoc +ruleCheckBind :: RuleCheckEnv -> CoreBind -> (RuleCheckEnv, Bag SDoc) -- The Bag returned has one SDoc for each call site found -ruleCheckBind env (NonRec _ r) = ruleCheck env r -ruleCheckBind env (Rec prs) = unionManyBags [ruleCheck env r | (_,r) <- prs] +ruleCheckBind env (NonRec b r) = (env `extendInScopeRC` b, ruleCheck env r) +ruleCheckBind env (Rec prs) = (env', unionManyBags (map (ruleCheck env') rhss)) + where + (bs, rhss) = unzip prs + env' = env `extendInScopeListRC` bs ruleCheck :: RuleCheckEnv -> CoreExpr -> Bag SDoc -ruleCheck _ (Var _) = emptyBag -ruleCheck _ (Lit _) = emptyBag -ruleCheck _ (Type _) = emptyBag -ruleCheck _ (Coercion _) = emptyBag -ruleCheck env (App f a) = ruleCheckApp env (App f a) [] -ruleCheck env (Tick _ e) = ruleCheck env e -ruleCheck env (Cast e _) = ruleCheck env e -ruleCheck env (Let bd e) = ruleCheckBind env bd `unionBags` ruleCheck env e -ruleCheck env (Lam _ e) = ruleCheck env e -ruleCheck env (Case e _ _ as) = ruleCheck env e `unionBags` - unionManyBags [ruleCheck env r | Alt _ _ r <- as] +ruleCheck _ (Var _) = emptyBag +ruleCheck _ (Lit _) = emptyBag +ruleCheck _ (Type _) = emptyBag +ruleCheck _ (Coercion _) = emptyBag +ruleCheck env (App f a) = ruleCheckApp env (App f a) [] +ruleCheck env (Tick _ e) = ruleCheck env e +ruleCheck env (Cast e _) = ruleCheck env e +ruleCheck env (Let bd e) = let (env', ds) = ruleCheckBind env bd + in ds `unionBags` ruleCheck env' e +ruleCheck env (Lam b e) = ruleCheck (env `extendInScopeRC` b) e +ruleCheck env (Case e b _ as) = ruleCheck env e `unionBags` + unionManyBags [ruleCheck (env `extendInScopeListRC` (b:bs)) r + | Alt _ bs r <- as] ruleCheckApp :: RuleCheckEnv -> Expr CoreBndr -> [Arg CoreBndr] -> Bag SDoc ruleCheckApp env (App f a) as = ruleCheck env a `unionBags` ruleCheckApp env f (a:as) @@ -1945,8 +1963,9 @@ ruleAppCheck_help env fn args rules vcat [text "Expression:" <+> ppr (mkApps (Var fn) args), vcat (map check_rule rules)] where - n_args = length args - i_args = args `zip` [1::Int ..] + in_scope = rc_in_scope env + n_args = length args + i_args = args `zip` [1::Int ..] rough_args = map roughTopName args check_rule rule = rule_herald rule <> colon <+> rule_info (rc_ropts env) rule @@ -1976,10 +1995,8 @@ ruleAppCheck_help env fn args rules mismatches = [i | (rule_arg, (arg,i)) <- rule_args `zip` i_args, not (isJust (match_fn rule_arg arg))] - lhs_fvs = exprsFreeVars rule_args -- Includes template tyvars match_fn rule_arg arg = match renv emptyRuleSubst rule_arg arg MRefl where - in_scope = mkInScopeSet (lhs_fvs `unionVarSet` exprFreeVars arg) renv = RV { rv_lcl = mkRnEnv2 in_scope , rv_tmpls = mkVarSet rule_bndrs , rv_fltR = mkEmptySubst in_scope ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -228,7 +228,8 @@ enterRecGroupRHSs env bndrs k (env', r) = k env{soe_rec_ids = extendUnVarSetList bndrs (soe_rec_ids env)} --------------- -simple_opt_clo :: InScopeSet +simple_opt_clo :: HasCallStack + => InScopeSet -> SimpleClo -> OutExpr simple_opt_clo in_scope (e_env, e) @@ -397,7 +398,8 @@ simple_app env (Let bind body) args simple_app env e as = finish_app env (simple_opt_expr env e) as -finish_app :: SimpleOptEnv -> OutExpr -> [SimpleClo] -> OutExpr +finish_app :: HasCallStack + => SimpleOptEnv -> OutExpr -> [SimpleClo] -> OutExpr -- See Note [Eliminate casts in function position] finish_app env (Cast (Lam x e) co) as@(_:_) | not (isTyVar x) && not (isCoVar x) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2354,45 +2354,49 @@ we are optimizing away 'lazy' (see Note [lazyId magic], and also 'cpeRhsE'.) Then, we could have started with: let x :: () - x = lazy @ () y + x = lazy @() y -which is a perfectly fine, non-trivial thunk, but then CorePrep will -drop 'lazy', giving us 'x = y' which is trivial and impermissible. -The solution is CorePrep to have a miniature inlining pass which deals -with cases like this. We can then drop the let-binding altogether. +which is a perfectly fine, non-trivial thunk, but then CorePrep will drop +'lazy', giving us 'x = y' which is trivial and impermissible. The solution is +CorePrep to have a miniature inlining pass which deals with cases like this. +We can then drop the let-binding altogether. -Why does the removal of 'lazy' have to occur in CorePrep? -The gory details are in Note [lazyId magic] in GHC.Types.Id.Make, but the -main reason is that lazy must appear in unfoldings (optimizer -output) and it must prevent call-by-value for catch# (which -is implemented by CorePrep.) +Why does the removal of 'lazy' have to occur in CorePrep? The gory details +are in Note [lazyId magic] in GHC.Types.Id.Make, but the main reason is that +lazy must appear in unfoldings (optimizer output) and it must prevent +call-by-value for catch# (which is implemented by CorePrep.) -An alternate strategy for solving this problem is to have the -inliner treat 'lazy e' as a trivial expression if 'e' is trivial. -We decided not to adopt this solution to keep the definition -of 'exprIsTrivial' simple. +An alternate strategy for solving this problem is to have the inliner treat +'lazy e' as a trivial expression if 'e' is trivial. We decided not to adopt +this solution to keep the definition of 'exprIsTrivial' simple. There is ONE caveat however: for top-level bindings we have to preserve the binding so that we float the (hacky) non-recursive binding for data constructors; see Note [Data constructor workers]. -Note [CorePrep inlines trivial CoreExpr not Id] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -TODO -Why does cpe_env need to be an IdEnv CoreExpr, as opposed to an -IdEnv Id? Naively, we might conjecture that trivial updatable thunks -as per Note [Inlining in CorePrep] always have the form -'lazy @ SomeType gbl_id'. But this is not true: the following is -perfectly reasonable Core: +Note [CorePrepEnv: cpe_subst] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CorePrepEnv carries a substitution `Subst` in the `cpe_subst1 field, +for these reasons: - let x :: () - x = lazy @ (forall a. a) y @ Bool +1. To support cloning of local Ids so that they are + all unique (see Note [Cloning in CorePrep]) + +2. To support beta-reduction of runRW, see Note [runRW magic] and + Note [runRW arg]. + +3. To let us inline trivial RHSs of non top-level let-bindings, + see Note [lazyId magic], Note [Inlining in CorePrep] (#12076) -When we inline 'x' after eliminating 'lazy', we need to replace -occurrences of 'x' with 'y @ bool', not just 'y'. Situations like -this can easily arise with higher-rank types; thus, cpe_env must -map to CoreExprs, not Ids. + Note that, if (y::forall a. a->a), we could get + x = lazy @(forall a.a) y @Bool + so after eliminating `lazy`, we need to replace occurrences of `x` with + `y @Bool`, not just `y`. Situations like this can easily arise with + higher-rank types; thus, `cpe_subst` must map to CoreExprs, not Ids, which + oc course it does +4. The TyCoVar part of the substitution is used only for + Note [Cloning CoVars and TyVars] -} data CorePrepConfig = CorePrepConfig @@ -2418,23 +2422,9 @@ data CorePrepEnv -- the case where a function we think should bottom -- unexpectedly returns. - , cpe_subst :: Subst - -- ^ The IdEnv part of the substitution is used for three operations: - -- - -- 1. To support cloning of local Ids so that they are - -- all unique (see Note [Cloning in CorePrep]) - -- - -- 2. To support beta-reduction of runRW, see - -- Note [runRW magic] and Note [runRW arg]. - -- - -- 3. To let us inline trivial RHSs of non top-level let-bindings, - -- see Note [lazyId magic], Note [Inlining in CorePrep] - -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) - -- - -- The TyCoVar part of the substitution is used only for - -- Note [Cloning CoVars and TyVars] + , cpe_subst :: Subst -- ^ See Note [CorePrepEnv: cpe_subst] - , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] + , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== distrib/configure.ac.in ===================================== @@ -114,16 +114,16 @@ if test "$HostOS" = "darwin"; then # The following is the work around suggested by @carter in #17418 during # install time. This should help us with code signing issues by removing # extended attributes from all files. - XATTR=${XATTR:-/usr/bin/xattr} + XATTR="${XATTR:-/usr/bin/xattr}" - if [ -e "${XATTR}" ]; then + if test -e "${XATTR}"; then # Instead of cleaning the attributes of the ghc-toolchain binary only, # we clean them from all files in the bin/ and lib/ directories, as it additionally future # proofs running executables from the bindist besides ghc-toolchain at configure time, and # we can avoid figuring out the path to the ghc-toolchain dynlib specifically. - /usr/bin/xattr -rc bin/ - /usr/bin/xattr -rc lib/ + "$XATTR" -rc bin/ + "$XATTR" -rc lib/ fi fi ===================================== docs/users_guide/bugs.rst ===================================== @@ -445,15 +445,15 @@ In ``Prelude`` support ``Read``\ ing integers GHC's implementation of the ``Read`` class for integral types - accepts hexadecimal and octal literals (the code in the Haskell 98 + accepts hexadecimal, octal and binary literals (the code in the Haskell 98 report doesn't). So, for example, :: read "0xf00" :: Int works in GHC. - A possible reason for this is that ``readLitChar`` accepts hex and - octal escapes, so it seems inconsistent not to do so for integers + This is to maintain consistency with the language's syntax. Haskell98 + accepts hexadecimal and octal formats, and GHC2021 accepts binary formats too. ``isAlpha`` ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). ===================================== libraries/base/changelog.md ===================================== @@ -1,7 +1,9 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) ## 4.21.0.0 *TBA* + * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) + * Make `read` accept binary integer notation ([CLC proposal #177](https://github.com/haskell/core-libraries-committee/issues/177)) ## 4.20.0.0 *TBA* * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) ===================================== libraries/base/tests/char001.hs ===================================== @@ -1,7 +1,8 @@ -- !!! Testing the behaviour of Char.lexLitChar a little.. --- [March 2003] We now allow \X and \O as escapes although the --- spec only permits \x and \o. Seems more consistent. +-- [March 2003] We now allow \X and \O as escapes although the +-- spec only permits \x and \o. Seems more consistent. +-- [January 2024] Binary character literals, something like '\b100' are not permitted. module Main where @@ -33,9 +34,15 @@ octs = do lex' "'\\o14b'" lex' "'\\0a4bg'" +-- Binaries are NOT supported. '\b' stands for backspace. +bins = do + lex' "'\\b'" + lex' "'\\b00'" + main = do hexes octs + bins ===================================== libraries/base/tests/char001.stdout ===================================== @@ -16,3 +16,5 @@ lex '\O000024' = [("'\\O000024'","")] lex '\024b' = [] lex '\o14b' = [] lex '\0a4bg' = [] +lex '\b' = [("'\\b'","")] +lex '\b00' = [] ===================================== libraries/base/tests/lex001.hs ===================================== @@ -27,7 +27,23 @@ testStrings "035e-3x", "35e+3y", "83.3e-22", - "083.3e-22" + "083.3e-22", + + "0b001", + "0b100", + "0b110", + "0B001", + "0B100", + "0B110", + + "78_91", + "678_346", + "0x23d_fa4", + "0X23d_fa4", + "0o01_253", + "0O304_367", + "0b0101_0110", + "0B11_010_0110" ] main = mapM test testStrings ===================================== libraries/base/tests/lex001.stdout ===================================== @@ -82,3 +82,58 @@ [("083.3e-22","")] [(Number (MkDecimal [0,8,3] (Just [3]) (Just (-22))),"")] +"0b001" +[("0b001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0b100" +[("0b100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0b110" +[("0b110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"0B001" +[("0B001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0B100" +[("0B100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0B110" +[("0B110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"78_91" +[("78","_91")] +[(Number (MkDecimal [7,8] Nothing Nothing),"_91")] + +"678_346" +[("678","_346")] +[(Number (MkDecimal [6,7,8] Nothing Nothing),"_346")] + +"0x23d_fa4" +[("0x23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0X23d_fa4" +[("0X23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0o01_253" +[("0o01","_253")] +[(Number (MkNumber 8 [0,1]),"_253")] + +"0O304_367" +[("0O304","_367")] +[(Number (MkNumber 8 [3,0,4]),"_367")] + +"0b0101_0110" +[("0b0101","_0110")] +[(Number (MkNumber 2 [0,1,0,1]),"_0110")] + +"0B11_010_0110" +[("0B11","_010_0110")] +[(Number (MkNumber 2 [1,1]),"_010_0110")] ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs ===================================== @@ -30,13 +30,13 @@ module GHC.Internal.Control.Monad.Fix ( import GHC.Internal.Data.Either import GHC.Internal.Data.Function ( fix ) import GHC.Internal.Data.Maybe -import GHC.Internal.Data.Monoid ( Dual(..), Sum(..), Product(..) +import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..) , First(..), Last(..), Alt(..), Ap(..) ) import GHC.Internal.Data.Ord ( Down(..) ) +import GHC.Internal.Data.Tuple ( Solo(..), snd ) import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) ) import GHC.Internal.Generics import GHC.Internal.List ( head, drop ) -import GHC.Tuple (Solo (..)) import GHC.Internal.Control.Monad.ST.Imp import GHC.Internal.System.IO @@ -72,6 +72,11 @@ instance MonadFix Solo where mfix f = let a = f (unSolo a) in a where unSolo (MkSolo x) = x +-- | @since base-4.21 +instance Monoid a => MonadFix ((,) a) where + -- See the CLC proposal thread for discussion and proofs of the laws: https://github.com/haskell/core-libraries-committee/issues/238 + mfix f = let a = f (snd a) in a + -- | @since base-2.01 instance MonadFix Maybe where mfix f = let a = f (unJust a) in a ===================================== libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs ===================================== @@ -300,6 +300,17 @@ lexCharE = n <- lexInteger base guard (n <= toInteger (ord maxBound)) return (chr (fromInteger n)) + where + -- Slightly different variant of lexBaseChar that denies binary format. + -- Binary formats are not allowed for character/string literal. + lexBaseChar = do + c <- get + case c of + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexCntrlChar = do _ <- char '^' @@ -415,27 +426,28 @@ type Digits = [Int] lexNumber :: ReadP Lexeme lexNumber - = lexHexOct <++ -- First try for hex or octal 0x, 0o etc + = lexHexOctBin <++ -- First try for hex, octal or binary 0x, 0o, 0b etc -- If that fails, try for a decimal number lexDecNumber -- Start with ordinary digits -lexHexOct :: ReadP Lexeme -lexHexOct +lexHexOctBin :: ReadP Lexeme +lexHexOctBin = do _ <- char '0' base <- lexBaseChar digits <- lexDigits base return (Number (MkNumber base digits)) - -lexBaseChar :: ReadP Int --- Lex a single character indicating the base; fail if not there -lexBaseChar = do - c <- get - case c of - 'o' -> return 8 - 'O' -> return 8 - 'x' -> return 16 - 'X' -> return 16 - _ -> pfail + where + -- Lex a single character indicating the base; fail if not there + lexBaseChar = do + c <- get + case c of + 'b' -> return 2 + 'B' -> return 2 + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexDecNumber :: ReadP Lexeme lexDecNumber = ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -14418,6 +14418,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -11647,6 +11647,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -11383,6 +11383,7 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Int instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.ST.ST s) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix Solo -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Fix’ +instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Control.Monad.Fix.MonadFix ((,) a) -- Defined in ‘GHC.Internal.Control.Monad.Fix’ instance forall s. GHC.Internal.Control.Monad.Fix.MonadFix (GHC.Internal.Control.Monad.ST.Lazy.Imp.ST s) -- Defined in ‘GHC.Internal.Control.Monad.ST.Lazy.Imp’ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Complex.Complex -- Defined in ‘Data.Complex’ instance GHC.Internal.Control.Monad.Fix.MonadFix GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== testsuite/tests/simplCore/should_compile/T24726.hs ===================================== @@ -0,0 +1,26 @@ +{-# OPTIONS_GHC -drule-check concatMap #-} + -- This rule-check thing crashed #24726 + +module T24726 where + +data Stream a = forall s. Stream (s -> ()) s + +concatMapS :: (a -> Stream b) -> Stream a -> Stream b +concatMapS f (Stream next0 s0) = Stream undefined undefined +{-# INLINE [1] concatMapS #-} + +concatMapS' :: (s -> ()) -> (a -> s) -> Stream a -> Stream b +concatMapS' = undefined + +{-# RULES "concatMap" forall step f. concatMapS (\x -> Stream step (f x)) = concatMapS' step f #-} + +replicateStep :: a -> b +replicateStep _ = undefined +{-# INLINE replicateStep #-} + +replicateS :: Int -> a -> Stream a +replicateS n x0 = Stream replicateStep undefined +{-# INLINE replicateS #-} + +foo1 :: Stream Int -> Stream Int +foo1 = concatMapS (replicateS 2) ===================================== testsuite/tests/simplCore/should_compile/T24726.stderr ===================================== @@ -0,0 +1,36 @@ + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -514,3 +514,4 @@ test('T24229a', [ grep_errmsg(r'wfoo') ], compile, ['-O2 -ddump-simpl -dno-typea test('T24229b', [ grep_errmsg(r'wfoo') ], compile, ['-O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques -dppr-cols=99999']) test('T24370', normal, compile, ['-O']) test('T24551', normal, compile, ['-O -dcore-lint']) +test('T24726', normal, compile, ['-dcore-lint -dsuppress-uniques']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8a8e6bbb656339524a5ec23be06df7ff243833d5...d5d664bd5ad70c26d169c8df8389d9f8c547ddb6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8a8e6bbb656339524a5ec23be06df7ff243833d5...d5d664bd5ad70c26d169c8df8389d9f8c547ddb6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:24:06 2024 From: gitlab at gitlab.haskell.org (Mikolaj Konarski (@Mikolaj)) Date: Tue, 30 Apr 2024 05:24:06 -0400 Subject: [Git][ghc/ghc][wip/T23923-mikolaj-take-2] 62 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <6630b8b6c639e_57453d0de64402a0@gitlab.mail> Mikolaj Konarski pushed to branch wip/T23923-mikolaj-take-2 at Glasgow Haskell Compiler / GHC Commits: dbdf1995 by Alex Mason at 2024-04-15T15:28:26+10:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 - - - - - 42bd0407 by Teo Camarasu at 2024-04-16T20:06:39-04:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 3d973e47 by Ben Gamari at 2024-04-16T20:07:15-04:00 Bump parsec submodule to 3.1.17.0 - - - - - 9d38bfa0 by Simon Peyton Jones at 2024-04-16T20:07:51-04:00 Clone CoVars in CorePrep This MR addresses #24463. It's all explained in the new Note [Cloning CoVars and TyVars] - - - - - 0fe2b410 by Andreas Klebinger at 2024-04-16T20:08:27-04:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 - - - - - 9f99126a by Teo Camarasu at 2024-04-16T20:09:04-04:00 Fix documentation preview from doc-tarball job - Include all the .html files and assets in the job artefacts - Include all the .pdf files in the job artefacts - Mark the artefact as an "exposed" artefact meaning it turns up in the UI. Resolves #24651 - - - - - 3a0642ea by Ben Gamari at 2024-04-16T20:09:39-04:00 rts: Ignore EINTR while polling in timerfd itimer implementation While the RTS does attempt to mask signals, it may be that a foreign library unmasks them. This previously caused benign warnings which we now ignore. See #24610. - - - - - 9a53cd3f by Alan Zimmerman at 2024-04-16T20:10:15-04:00 EPA: Add additional comments field to AnnsModule This is used in exact printing to store comments coming after the `where` keyword but before any comments allocated to imports or decls. It is used in ghc-exactprint, see https://github.com/alanz/ghc-exactprint/commit/44bbed311fd8f0d053053fef195bf47c17d34fa7 - - - - - e5c43259 by Bryan Richter at 2024-04-16T20:10:51-04:00 Remove unrunnable FreeBSD CI jobs FreeBSD runner supply is inelastic. Currently there is only one, and it's unavailable because of a hardware issue. - - - - - 914eb49a by Ben Gamari at 2024-04-16T20:11:27-04:00 rel-eng: Fix mktemp usage in recompress-all We need a temporary directory, not a file. - - - - - f30e4984 by Teo Camarasu at 2024-04-16T20:12:03-04:00 Fix ghc API link in docs/index.html This was missing part of the unit ID meaning it would 404. Resolves #24674 - - - - - d7a3d6b5 by Ben Gamari at 2024-04-16T20:12:39-04:00 template-haskell: Declare TH.Lib.Internal as not-home Rather than `hide`. Closes #24659. - - - - - 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 68bc204f by Mikolaj Konarski at 2024-04-30T11:23:20+02:00 Add DCoVarSet to PluginProv (!12037) - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/recompress-all - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PPC.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e29277caccfbf3577ab48d7454121ec47c522778...68bc204f3fb5d27958c6b89593d910d1a60eae91 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e29277caccfbf3577ab48d7454121ec47c522778...68bc204f3fb5d27958c6b89593d910d1a60eae91 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:30:25 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 05:30:25 -0400 Subject: [Git][ghc/ghc][wip/fendor/ifacetype-deduplication] 26 commits: ghc-bignum: remove obsolete ln script Message-ID: <6630ba31108dc_57453e9eee0414d8@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ifacetype-deduplication at Glasgow Haskell Compiler / GHC Commits: c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 44986061 by Fendor at 2024-04-30T11:29:50+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 795deda1 by Fendor at 2024-04-30T11:29:50+02:00 Break cyclic module dependency - - - - - 31b93f5a by Fendor at 2024-04-30T11:29:50+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - c064e2ef by Matthew Pickering at 2024-04-30T11:29:50+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: MultiLayerModulesDefsGhciWithCore T21839c T24471 ------------------------- - - - - - 158af23b by Matthew Pickering at 2024-04-30T11:29:50+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 485d2cb3 by Fendor at 2024-04-30T11:29:50+02:00 Implement TrieMap for IfaceType - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Stg/CSE.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9227f1a8826046876502fc3a0ea8d20c20cc47a8...485d2cb3fedc7f2dbf9d20c309bf7878af38bf3f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9227f1a8826046876502fc3a0ea8d20c20cc47a8...485d2cb3fedc7f2dbf9d20c309bf7878af38bf3f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:31:19 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 30 Apr 2024 05:31:19 -0400 Subject: [Git][ghc/ghc][master] utils: remove obsolete vagrant scripts Message-ID: <6630ba6787370_57453102c1cc451af@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 2 changed files: - − utils/vagrant/bootstrap-deb.sh - − utils/vagrant/bootstrap-rhel.sh Changes: ===================================== utils/vagrant/bootstrap-deb.sh deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -apt-get update -apt-get build-dep -y ghc ===================================== utils/vagrant/bootstrap-rhel.sh deleted ===================================== @@ -1,4 +0,0 @@ -#!/bin/sh -yum update -y -yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool \ - gcc make python ghc git View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/728af21e47daad7b20b2216fe6215d300c45aa56 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/728af21e47daad7b20b2216fe6215d300c45aa56 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:31:59 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 30 Apr 2024 05:31:59 -0400 Subject: [Git][ghc/ghc][master] Update autoconf scripts Message-ID: <6630ba8fa056a_5745310396384925@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - 2 changed files: - config.guess - config.sub Changes: ===================================== config.guess ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-05-25' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +910,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +972,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1068,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1191,7 +1232,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1373,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1554,6 +1595,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? ===================================== config.sub ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1190,7 +1191,7 @@ case $cpu-$vendor in | arc | arceb | arc32 | arc64 \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ - | asmjs | javascript \ + | asmjs \ | ba \ | be32 | be64 \ | bfin | bpf | bs2000 \ @@ -1199,50 +1200,29 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64eb | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r3 | mipsisa32r3el \ - | mipsisa32r5 | mipsisa32r5el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r3 | mipsisa64r3el \ - | mipsisa64r5 | mipsisa64r5el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ + | nanomips* \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ @@ -1274,6 +1254,7 @@ case $cpu-$vendor in | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ + | vc4 \ | visium \ | w65 \ | wasm32 | wasm64 \ @@ -1285,7 +1266,7 @@ case $cpu-$vendor in ;; *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1287,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1323,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1492,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; esac ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; *) # No normalization, but not necessarily accepted, that comes below. ;; @@ -1528,12 +1520,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1538,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1588,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; - mips*-*) - os=elf + mips*-*|nanomips*-*) + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1614,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1696,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,14 +1719,11 @@ esac fi -# Now, validate our (potentially fixed-up) OS. -case $os in - # GHC specific: added for JS backend support - js | ghcjs) - ;; +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - # Sometimes we do "kernel-abi", so those need to count as OSes. - musl* | newlib* | relibc* | uclibc*) +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) ;; # Likewise for "kernel-abi" eabi* | gnueabi*) @@ -1724,6 +1731,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. @@ -1732,7 +1742,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1741,11 +1751,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1758,49 +1768,116 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; none) ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1883,7 +1960,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36f2c3422d7f3620078dba701f57275a3708aff5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36f2c3422d7f3620078dba701f57275a3708aff5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:33:00 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 30 Apr 2024 05:33:00 -0400 Subject: [Git][ghc/ghc][master] ghcup-metadata: Drop output_name field Message-ID: <6630bacce92dc_57453136fdd4501a3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 1 changed file: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecbf22a6ac397a791204590f94c0afa82e29e79f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecbf22a6ac397a791204590f94c0afa82e29e79f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:47:45 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 05:47:45 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 29 commits: ghc-bignum: remove obsolete ln script Message-ID: <6630be41d0112_57453163030c520bc@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 44986061 by Fendor at 2024-04-30T11:29:50+02:00 Add Eq and Ord instance to `IfaceType` We add an `Ord` instance so that we can store `IfaceType` in a `Data.Map` container. This is required to deduplicate `IfaceType` while writing `.hi` files to disk. Deduplication has many beneficial consequences to both file size and memory usage, as the deduplication enables implicit sharing of values. See issue #24540 for more motivation. The `Ord` instance would be unnecessary if we used a `TrieMap` instead of `Data.Map` for the deduplication process. While in theory this is clerarly the better option, experiments on the agda code base showed that a `TrieMap` implementation has worse run-time performance characteristics. To the change itself, we mostly derive `Eq` and `Ord`. This requires us to change occurrences of `FastString` with `LexicalFastString`, since `FastString` has no `Ord` instance. We change the definition of `IfLclName` to a newtype of `LexicalFastString`, to make such changes in the future easier. Bump haddock submodule for IfLclName changes - - - - - 795deda1 by Fendor at 2024-04-30T11:29:50+02:00 Break cyclic module dependency - - - - - 31b93f5a by Fendor at 2024-04-30T11:29:50+02:00 Add deduplication table for `IfaceType` The type `IfaceType` is a highly redundant, tree-like data structure. While benchmarking, we realised that the high redundancy of `IfaceType` causes high memory consumption in GHCi sessions when byte code is embedded into the `.hi` file via `-fwrite-if-simplified-core` or `-fbyte-code-and-object-code`. Loading such `.hi` files from disk introduces many duplicates of memory expensive values in `IfaceType`, such as `IfaceTyCon`, `IfaceTyConApp`, `IA_Arg` and many more. We improve the memory behaviour of GHCi by adding an additional deduplication table for `IfaceType` to the serialisation of `ModIface`, similar to how we deduplicate `Name`s and `FastString`s. When reading the interface file back, the table allows us to automatically share identical values of `IfaceType`. To provide some numbers, we evaluated this patch on the agda code base. We loaded the full library from the `.hi` files, which contained the embedded core expressions (`-fwrite-if-simplified-core`). Before this patch: * Load time: 11.7 s, 2.5 GB maximum residency. After this patch: * Load time: 7.3 s, 1.7 GB maximum residency. This deduplication has the beneficial side effect to additionally reduce the size of the on-disk interface files tremendously. For example, on agda, we reduce the size of `.hi` files (with `-fwrite-if-simplified-core`): * Before: 101 MB on disk * Now: 24 MB on disk This has even a beneficial side effect on the cabal store. We reduce the size of the store on disk: * Before: 341 MB on disk * Now: 310 MB on disk Note, none of the dependencies have been compiled with `-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple locations in a `ModIface`. We also add IfaceType deduplication table to .hie serialisation and refactor .hie file serialisation to use the same infrastrucutre as `putWithTables`. Bump haddock submodule to accomodate for changes to the deduplication table layout and binary interface. - - - - - c064e2ef by Matthew Pickering at 2024-04-30T11:29:50+02:00 Add run-time configurability of .hi file compression Introduce the flag `-fwrite-if-compression=<n>` which allows to configure the compression level of writing .hi files. The motivation is that some deduplication operations are too expensive for the average use case. Hence, we introduce multiple compression levels that have a minimal impact on performance, but still reduce the memory residency and `.hi` file size on disk considerably. We introduce three compression levels: * `1`: `Normal` mode. This is the least amount of compression. It deduplicates only `Name` and `FastString`s, and is naturally the fastest compression mode. * `2`: `Safe` mode. It has a noticeable impact on .hi file size and is marginally slower than `Normal` mode. In general, it should be safe to always use `Safe` mode. * `3`: `Full` deduplication mode. Deduplicate as much as we can, resulting in minimal .hi files, but at the cost of additional compilation time. Reading .hi files doesn't need to know the initial compression level, and can always deserialise a `ModIface`. This allows users to experiment with different compression levels for packages, without recompilation of dependencies. Note, the deduplication also has an additional side effect of reduced memory consumption to implicit sharing of deduplicated elements. See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where that matters. ------------------------- Metric Decrease: MultiLayerModulesDefsGhciWithCore T21839c T24471 ------------------------- - - - - - 158af23b by Matthew Pickering at 2024-04-30T11:29:50+02:00 Introduce regression tests for `.hi` file sizes Add regression tests to track how `-fwrite-if-compression` levels affect the size of `.hi` files. - - - - - 485d2cb3 by Fendor at 2024-04-30T11:29:50+02:00 Implement TrieMap for IfaceType - - - - - a3703244 by Fendor at 2024-04-30T11:47:20+02:00 Improve sharing of duplicated values in `ModIface` As a `ModIface` contains often duplicated values that are not necessarily shared, we improve sharing by serialising the `ModIface` to an in-memory byte array. Serialisation uses deduplication tables, and deserialisation implicitly shares duplicated values. This helps reducing the peak memory usage while compiling in `--make` mode. The peak memory usage is especially reduced when generating interface files with core expressions (`-fwrite-if-simplified-core`). On agda, this reduces the peak memory usage: * `2.2 GB` to `1.9 GB` for a ghci session. On `lib:Cabal`, we report: * `570 MB` to `500 MB` for a ghci session * `790 MB` to `667 MB` for compiling `lib:Cabal` with ghc The execution time is not affected. - - - - - ada0e6a3 by Fendor at 2024-04-30T11:47:30+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - ebe3a0ad by Fendor at 2024-04-30T11:47:30+02:00 Make sure to always invalidate correctly - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Data/TrieMap.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Env.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - + compiler/GHC/Iface/Type/Map.hs - compiler/GHC/IfaceToCore.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7ada9b6f2949298f9b9dec32eabb3b70e9108ad...ebe3a0ad890dfe6a56d64bd486f69d4dc4fe057a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7ada9b6f2949298f9b9dec32eabb3b70e9108ad...ebe3a0ad890dfe6a56d64bd486f69d4dc4fe057a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 09:48:13 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 05:48:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fendor/ghc-iface-sharing Message-ID: <6630be5dde8a1_5745316acbc852232@gitlab.mail> Hannes Siebenhandl pushed new branch wip/fendor/ghc-iface-sharing at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/ghc-iface-sharing You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 10:20:23 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 06:20:23 -0400 Subject: [Git][ghc/ghc][wip/T23109] 62 commits: testsuite: Rename isCross() predicate to needsTargetWrapper() Message-ID: <6630c5e797816_2fbef53ee2206576@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 5eaa46e7 by Matthew Pickering at 2024-04-19T02:14:55-04:00 testsuite: Rename isCross() predicate to needsTargetWrapper() isCross() was a misnamed because it assumed that all cross targets would provide a target wrapper, but the two most common cross targets (javascript, wasm) don't need a target wrapper. Therefore we rename this predicate to `needsTargetWrapper()` so situations in the testsuite where we can check whether running executables requires a target wrapper or not. - - - - - 55a9d699 by Simon Peyton Jones at 2024-04-19T02:15:32-04:00 Do not float HNFs out of lambdas This MR adjusts SetLevels so that it is less eager to float a HNF (lambda or constructor application) out of a lambda, unless it gets to top level. Data suggests that this change is a small net win: * nofib bytes-allocated falls by -0.09% (but a couple go up) * perf/should_compile bytes-allocated falls by -0.5% * perf/should_run bytes-allocated falls by -0.1% See !12410 for more detail. When fiddling elsewhere, I also found that this patch had a huge positive effect on the (very delicate) test perf/should_run/T21839r But that improvement doesn't show up in this MR by itself. Metric Decrease: MultiLayerModulesRecomp T15703 parsing001 - - - - - f0701585 by Alan Zimmerman at 2024-04-19T02:16:08-04:00 EPA: Fix comments in mkListSyntaxTy0 Also extend the test to confirm. Addresses #24669, 1 of 4 - - - - - b01c01d4 by Serge S. Gulin at 2024-04-19T02:16:51-04:00 JS: set image `x86_64-linux-deb11-emsdk-closure` for build - - - - - c90c6039 by Alan Zimmerman at 2024-04-19T02:17:27-04:00 EPA: Provide correct span for PatBind And remove unused parameter in checkPatBind Contributes to #24669 - - - - - 26036f96 by Alan Zimmerman at 2024-04-19T13:11:08-04:00 EPA: Fix span for PatBuilderAppType Include the location of the prefix @ in the span for InVisPat. Also removes unnecessary annotations from HsTP. Contributes to #24669 - - - - - dba03aab by Matthew Craven at 2024-04-19T13:11:44-04:00 testsuite: Give the pre_cmd for mhu-perf more time - - - - - d31fbf6c by Krzysztof Gogolewski at 2024-04-19T21:04:09-04:00 Fix quantification order for a `op` b and a %m -> b Fixes #23764 Implements https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0640-tyop-quantification-order.rst Updates haddock submodule. - - - - - 385cd1c4 by Sebastian Graf at 2024-04-19T21:04:45-04:00 Make `seq#` a magic Id and inline it in CorePrep (#24124) We can save much code and explanation in Tag Inference and StgToCmm by making `seq#` a known-key Magic Id in `GHC.Internal.IO` and inline this definition in CorePrep. See the updated `Note [seq# magic]`. I also implemented a new `Note [Flatten case-bind]` to get better code for otherwise nested case scrutinees. I renamed the contructors of `ArgInfo` to use an `AI` prefix in order to resolve the clash between `type CpeApp = CoreExpr` and the data constructor of `ArgInfo`, as well as fixed typos in `Note [CorePrep invariants]`. Fixes #24252 and #24124. - - - - - 275e41a9 by Jade at 2024-04-20T11:10:40-04:00 Put the newline after errors instead of before them This mainly has consequences for GHCi but also slightly alters how the output of GHC on the commandline looks. Fixes: #22499 - - - - - dd339c7a by Teo Camarasu at 2024-04-20T11:11:16-04:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 - - - - - 2f8e3a25 by Alan Zimmerman at 2024-04-20T11:11:52-04:00 EPA: Avoid duplicated comments in splice decls Contributes to #24669 - - - - - c70b9ddb by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" - - - - - 3db54f9b by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: trivial checks for variable presence (fixes #24602) - - - - - 777f108f by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) - - - - - a45a5712 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` - - - - - ad90bf12 by Serge S. Gulin at 2024-04-21T16:33:43+03:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. - - - - - 5962fa52 by Serge S. Gulin at 2024-04-21T16:33:44+03:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. - - - - - a0694298 by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` - - - - - e58bb29f by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. - - - - - 909f3a9c by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments - - - - - 83eb10da by Serge S. Gulin at 2024-04-21T16:34:07+03:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. - - - - - e1cf8dc2 by brandon s allbery kf8nh at 2024-04-22T03:48:26-04:00 fix link in CODEOWNERS It seems that our local Gitlab no longer has documentation for the `CODEOWNERS` file, but the master documentation still does. Use that instead. - - - - - 593f4e04 by Fendor at 2024-04-23T10:19:14-04:00 Add performance regression test for '-fwrite-simplified-core' - - - - - 1ba39b05 by Fendor at 2024-04-23T10:19:14-04:00 Typecheck corebindings lazily during bytecode generation This delays typechecking the corebindings until the bytecode generation happens. We also avoid allocating a thunk that is retained by `unsafeInterleaveIO`. In general, we shouldn't retain values of the hydrated `Type`, as not evaluating the bytecode object keeps it alive. It is better if we retain the unhydrated `IfaceType`. See Note [Hydrating Modules] - - - - - e916fc92 by Alan Zimmerman at 2024-04-23T10:19:50-04:00 EPA: Keep comments in a CaseAlt match The comments now live in the surrounding location, not inside the Match. Make sure we keep them. Closes #24707 - - - - - d2b17f32 by Cheng Shao at 2024-04-23T15:01:22-04:00 driver: force merge objects when building dynamic objects This patch forces the driver to always merge objects when building dynamic objects even when ar -L is supported. It is an oversight of !8887: original rationale of that patch is favoring the relatively cheap ar -L operation over object merging when ar -L is supported, which makes sense but only if we are building static objects! Omitting check for whether we are building dynamic objects will result in broken .so files with undefined reference errors at executable link time when building GHC with llvm-ar. Fixes #22210. - - - - - 209d09f5 by Julian Ospald at 2024-04-23T15:02:03-04:00 Allow non-absolute values for bootstrap GHC variable Fixes #24682 - - - - - 3fff0977 by Matthew Pickering at 2024-04-23T15:02:38-04:00 Don't depend on registerPackage function in Cabal More recent versions of Cabal modify the behaviour of libAbiHash which breaks our usage of registerPackage. It is simpler to inline the part of registerPackage that we need and avoid any additional dependency and complication using the higher-level function introduces. - - - - - c62dc317 by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: remove obsolete ln script This commit removes an obsolete ln script in ghc-bignum/gmp. See 060251c24ad160264ae8553efecbb8bed2f06360 for its original intention, but it's been obsolete for a long time, especially since the removal of the make build system. Hence the house cleaning. - - - - - 6399d52b by Cheng Shao at 2024-04-25T01:32:02-04:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. - - - - - 65b4b92f by Cheng Shao at 2024-04-25T01:32:02-04:00 hadrian: remove obsolete Patch logic This commit removes obsolete Patch logic from hadrian, given we no longer need to patch the gmp tarball when building in-tree GMP. - - - - - 71f28958 by Cheng Shao at 2024-04-25T01:32:02-04:00 autoconf: remove obsolete patch detection This commit removes obsolete deletection logic of the patch command from autoconf scripts, given we no longer need to patch anything in the GHC build process. - - - - - daeda834 by Sylvain Henry at 2024-04-25T01:32:43-04:00 JS: correctly handle RUBBISH literals (#24664) - - - - - 8a06ddf6 by Matthew Pickering at 2024-04-25T11:16:16-04:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 - - - - - 94da9365 by Andrei Borzenkov at 2024-04-25T11:16:54-04:00 Fix tuple puns renaming (24702) Move tuple renaming short cutter from `isBuiltInOcc_maybe` to `isPunOcc_maybe`, so we consider incoming module. I also fixed some hidden bugs that raised after the change was done. - - - - - fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - f3032160 by Simon Peyton Jones at 2024-04-30T11:18:46+01:00 Make newtype instances opaque I think this will help with #23109 Wibbles Allow SelCo for newtype classes Experimental change Wibble Furher wibbles Further improvments Further wibbles esp exprIsConLike Run classop rule first Newtype classops are small needs comments - - - - - bacb648d by Simon Peyton Jones at 2024-04-30T11:18:46+01:00 Wibble imports - - - - - d3b1d259 by Simon Peyton Jones at 2024-04-30T11:18:46+01:00 Wibbles Notably: define and use mkNewTypeDictApp - - - - - c7ff697c by Simon Peyton Jones at 2024-04-30T11:18:46+01:00 Make newtype-class data constructors not inline This variant tries * Making the data constructor for a newtype class not inline * exprIsConApp_maybe treats it like a normal data constructor * CoreToStg discards it (perhaps CorePrep should do that instead) * Some as-it-turns-out unforced changes to corePrepPgm that makes it pass all TyCons, not just the data tycons * Significantly simpler story in mkNewTypeDictApp - - - - - 79a7d0f0 by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Wibble - - - - - 8050e3cf by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Get rid of newtype classes in CorePrep not CoreToStg - - - - - 35214427 by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Comment out bits that I think are no longer necessary * Extra field in ClassOpId, and classOpDictApp_maybe in Simplify.Iteration * Newtype classes being injective * Don't preInlineUnconditionally Dfuns * mkNewTypeDictApp * Zonking of unfoldings (only necessary for those local dfuns) - - - - - c9957a41 by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Wibble - - - - - a5c30faf by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Allow pushDataCon on ClassTyCon newtypes The fact that there is no *actual* data constructor in the end i kind-of-irrelevant, and we turn out to get quite a lot of class-op (d |> co) where co : C t1 ~R C t2 - - - - - ed696d46 by Simon Peyton Jones at 2024-04-30T11:18:47+01:00 Wibbles to merge - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - CODEOWNERS - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45c567cde6ccc0d22a706a427089c157add1949b...ed696d4638c5c69f987074e1dba4d2e43103889d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45c567cde6ccc0d22a706a427089c157add1949b...ed696d4638c5c69f987074e1dba4d2e43103889d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 10:23:31 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 06:23:31 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing-avoid-reserialisation] 4 commits: Shrink Bin buffer Message-ID: <6630c6a37720b_2fbef54ab7e4668fc@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing-avoid-reserialisation at Glasgow Haskell Compiler / GHC Commits: 80821eac by Fendor at 2024-04-30T12:22:45+02:00 Shrink Bin buffer - - - - - 09fd7e2e by Fendor at 2024-04-30T12:23:05+02:00 FullBindData Commit - - - - - f2ba480a by Fendor at 2024-04-30T12:23:06+02:00 Avoid unneccessarily re-serialising the `ModIface` To reduce memory usage of `ModIface`, we serialise `ModIface` to an in-memory byte array, which implicitly shares duplicated values. This serailised byte array can be reused to avoid work when we actually write the `ModIface` to disk. We introduce a new field to `ModIface` which allows us to save the byte array, and write it to disk if the `ModIface` wasn't changed after the initial serialisation. This requires us to change absolute offsets, for example to jump to the deduplication table for `Name` or `FastString` with relative offsets, as the deduplication byte array doesn't contain header information, such as fingerprints. To allow us to dump the binary blob to disk, we need to replace all absolute offsets with relative ones. This leads to new primitives for `ModIface`, which help to construct relative offsets. - - - - - 6a17f57f by Fendor at 2024-04-30T12:23:06+02:00 Make sure to always invalidate correctly - - - - - 13 changed files: - compiler/GHC.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -98,7 +98,32 @@ module GHC ( lookupGlobalName, findGlobalAnns, mkNamePprCtxForModule, - ModIface, ModIface_(..), + ModIface, + mi_module, + mi_sig_of, + mi_hsc_src, + mi_src_hash, + mi_hi_bytes, + mi_deps, + mi_usages, + mi_exports, + mi_used_th, + mi_fixities, + mi_warns, + mi_anns, + mi_insts, + mi_fam_insts, + mi_rules, + mi_decls, + mi_extra_decls, + mi_globals, + mi_hpc, + mi_trust, + mi_trust_pkg, + mi_complete_matches, + mi_docs, + mi_final_exts, + mi_ext_fields, SafeHaskellMode(..), -- * Printing ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -63,6 +63,8 @@ import Data.Map.Strict (Map) import Data.Word import System.IO.Unsafe import Data.Typeable (Typeable) +import qualified GHC.Data.Strict as Strict +import Data.Function ((&)) -- --------------------------------------------------------------------------- @@ -160,21 +162,24 @@ readBinIface profile name_cache checkHiWay traceBinIface hi_path = do mod_iface <- getIfaceWithExtFields name_cache bh - return mod_iface - { mi_src_hash = src_hash - } + return $ mod_iface + & addSourceFingerprint src_hash + getIfaceWithExtFields :: NameCache -> ReadBinHandle -> IO ModIface getIfaceWithExtFields name_cache bh = do - extFields_p <- get bh + start <- tellBinReader bh + extFields_p_rel <- getRelBin bh mod_iface <- getWithUserData name_cache bh - seekBinReader bh extFields_p + seekBinReader bh start + seekBinReaderRel bh extFields_p_rel extFields <- get bh - pure mod_iface - { mi_ext_fields = extFields - } + modIfaceData <- freezeBinHandle2 bh start + pure $ mod_iface + & set_mi_ext_fields extFields + & set_mi_hi_bytes (FullIfaceBinHandle $ Strict.Just modIfaceData) -- | This performs a get action after reading the dictionary and symbol @@ -204,7 +209,7 @@ getTables name_cache bh = do -- add it to the 'ReaderUserData' of 'ReadBinHandle'. decodeReaderTable :: Typeable a => ReaderTable a -> ReadBinHandle -> IO ReadBinHandle decodeReaderTable tbl bh0 = do - table <- Binary.forwardGet bh (getTable tbl bh0) + table <- Binary.forwardGetRel bh (getTable tbl bh0) let binaryReader = mkReaderFromTable tbl table pure $ addReaderToUserData binaryReader bh0 @@ -244,8 +249,12 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do -- | Puts the 'ModIface' putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = - forwardPut_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do - putWithUserData traceBinIface compressionLevel bh mod_iface + case mi_hi_bytes mod_iface of + -- FullIfaceBinHandle _ -> putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle Strict.Nothing -> do + forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do + putWithUserData traceBinIface compressionLevel bh mod_iface + FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. @@ -316,7 +325,7 @@ putAllTables _ [] act = do a <- act pure ([], a) putAllTables bh (x : xs) act = do - (r, (res, a)) <- forwardPut bh (const $ putTable x bh) $ do + (r, (res, a)) <- forwardPutRel bh (const $ putTable x bh) $ do putAllTables bh xs act pure (r : res, a) @@ -468,7 +477,7 @@ to the table we need to deserialise first. What deduplication tables exist and the order of serialisation is currently statically specified in 'putWithTables'. 'putWithTables' also takes care of the serialisation of used deduplication tables. The deserialisation of the deduplication tables happens 'getTables', using 'Binary' utility -functions such as 'forwardGet'. +functions such as 'forwardGetRel'. Here, a visualisation of the table structure we currently have (ignoring 'ExtensibleFields'): @@ -529,7 +538,6 @@ initWriteIfaceType compressionLevel = do putGenericSymTab sym_tab bh ty _ -> putIfaceType bh ty - fullIfaceTypeSerialiser sym_tab bh ty = do put_ bh ifaceTypeSharedByte putGenericSymTab sym_tab bh ty ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -235,7 +235,7 @@ readHieFileContents bh0 name_cache = do get bh1 where get_dictionary tbl bin_handle = do - fsTable <- Binary.forwardGet bin_handle (getTable tbl bin_handle) + fsTable <- Binary.forwardGetRel bin_handle (getTable tbl bin_handle) let fsReader = mkReaderFromTable tbl fsTable bhFs = addReaderToUserData fsReader bin_handle ===================================== compiler/GHC/Iface/Ext/Fields.hs ===================================== @@ -41,7 +41,7 @@ instance Binary ExtensibleFields where -- to point to the start of each payload: forM_ header_entries $ \(field_p_p, dat) -> do field_p <- tellBinWriter bh - putAt bh field_p_p field_p + putAtRel bh field_p_p field_p seekBinWriter bh field_p put_ bh dat @@ -50,11 +50,11 @@ instance Binary ExtensibleFields where -- Get the names and field pointers: header_entries <- replicateM n $ - (,) <$> get bh <*> get bh + (,) <$> get bh <*> getRelBin bh -- Seek to and get each field's payload: fields <- forM header_entries $ \(name, field_p) -> do - seekBinReader bh field_p + seekBinReaderRel bh field_p dat <- get bh return (name, dat) ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -117,6 +117,7 @@ import System.FilePath import System.Directory import GHC.Driver.Env.KnotVars import GHC.Iface.Errors.Types +import Data.Function ((&)) {- ************************************************************************ @@ -515,14 +516,12 @@ loadInterface doc_str mod from ; new_eps_anns <- tcIfaceAnnotations (mi_anns iface) ; new_eps_complete_matches <- tcIfaceCompleteMatches (mi_complete_matches iface) - ; let { final_iface = iface { - mi_decls = panic "No mi_decls in PIT", - mi_insts = panic "No mi_insts in PIT", - mi_fam_insts = panic "No mi_fam_insts in PIT", - mi_rules = panic "No mi_rules in PIT", - mi_anns = panic "No mi_anns in PIT" - } - } + ; let final_iface = iface + & set_mi_decls (panic "No mi_decls in PIT") + & set_mi_insts (panic "No mi_insts in PIT") + & set_mi_fam_insts (panic "No mi_fam_insts in PIT") + & set_mi_rules (panic "No mi_rules in PIT") + & set_mi_anns (panic "No mi_anns in PIT") ; let bad_boot = mi_boot iface == IsBoot && isJust (lookupKnotVars (if_rec_types gbl_env) mod) @@ -1017,13 +1016,13 @@ readIface dflags name_cache wanted_mod file_path = do -- See Note [GHC.Prim] in primops.txt.pp. ghcPrimIface :: ModIface ghcPrimIface - = empty_iface { - mi_exports = ghcPrimExports, - mi_decls = [], - mi_fixities = fixities, - mi_final_exts = (mi_final_exts empty_iface){ mi_fix_fn = mkIfaceFixCache fixities }, - mi_docs = Just ghcPrimDeclDocs -- See Note [GHC.Prim Docs] - } + = empty_iface + & set_mi_exports ghcPrimExports + & set_mi_decls [] + & set_mi_fixities fixities + & set_mi_final_exts ((mi_final_exts empty_iface){ mi_fix_fn = mkIfaceFixCache fixities }) + & set_mi_docs (Just ghcPrimDeclDocs) -- See Note [GHC.Prim Docs] + where empty_iface = emptyFullModIface gHC_PRIM @@ -1107,7 +1106,7 @@ pprModIfaceSimple unit_state iface = -- -- The UnitState is used to pretty-print units pprModIface :: UnitState -> ModIface -> SDoc -pprModIface unit_state iface at ModIface{ mi_final_exts = exts } +pprModIface unit_state iface = vcat [ text "interface" <+> ppr (mi_module iface) <+> pp_hsc_src (mi_hsc_src iface) <+> (if mi_orphan exts then text "[orphan module]" else Outputable.empty) @@ -1148,6 +1147,7 @@ pprModIface unit_state iface at ModIface{ mi_final_exts = exts } , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where + exts = mi_final_exts iface pp_hsc_src HsBootFile = text "[boot]" pp_hsc_src HsigFile = text "[hsig]" pp_hsc_src HsSrcFile = Outputable.empty ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -144,7 +144,7 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do full_iface <- {-# SCC "addFingerprints" #-} - addFingerprints hsc_env partial_iface{ mi_decls = decls } + addFingerprints hsc_env (set_mi_decls decls partial_iface) -- Debug printing let unit_state = hsc_units hsc_env @@ -153,17 +153,33 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos = do final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface return final_iface +-- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. +-- +-- We compress the 'ModIface' by serialising the 'ModIface' to an in-memory byte array, and then deserialising it. +-- The deserialisation will deduplicate certain values depending on the 'CompressionIFace' level. +-- See Note [Deduplication during iface binary serialisation] for how we do that. +-- +-- Additionally, we cache the serialised byte array, so if the 'ModIface' is not modified +-- after calling 'shareIface', 'writeBinIface' will reuse that buffer without serialising the 'ModIface' again. +-- Modifying the 'ModIface' forces us to re-serialise it again. shareIface :: NameCache -> CompressionIFace -> ModIface -> IO ModIface +shareIface _ NormalCompression mi = do + -- In 'NormalCompression', the sharing isn't reducing the memory usage, as 'Name's and 'FastString's are + -- already shared, and at this compression level, we don't compress/share anything else. + -- Thus, for a brief moment we simply double the memory residency for no reason. + -- Therefore, we only try to share expensive values if the compression mode is higher than + -- 'NormalCompression' + pure mi shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh - let resiface = res { mi_src_hash = mi_src_hash mi } + let resiface = set_mi_src_hash (mi_src_hash mi) res forceModIface resiface - return resiface + pure resiface updateDecl :: [IfaceDecl] -> Maybe StgCgInfos -> Maybe CmmCgInfos -> [IfaceDecl] @@ -318,40 +334,40 @@ mkIface_ hsc_env icomplete_matches = map mkIfaceCompleteMatch complete_matches !rdrs = maybeGlobalRdrEnv rdr_env - ModIface { - mi_module = this_mod, + emptyPartialModIface this_mod -- Need to record this because it depends on the -instantiated-with flag -- which could change - mi_sig_of = if semantic_mod == this_mod + & set_mi_sig_of ( if semantic_mod == this_mod then Nothing - else Just semantic_mod, - mi_hsc_src = hsc_src, - mi_deps = deps, - mi_usages = usages, - mi_exports = mkIfaceExports exports, + else Just semantic_mod) + & set_mi_hsc_src ( hsc_src) + & set_mi_deps ( deps) + & set_mi_usages ( usages) + & set_mi_exports ( mkIfaceExports exports) -- Sort these lexicographically, so that -- the result is stable across compilations - mi_insts = sortBy cmp_inst iface_insts, - mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts, - mi_rules = sortBy cmp_rule iface_rules, - - mi_fixities = fixities, - mi_warns = warns, - mi_anns = annotations, - mi_globals = rdrs, - mi_used_th = used_th, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_hpc = isHpcUsed hpc_info, - mi_trust = trust_info, - mi_trust_pkg = pkg_trust_req, - mi_complete_matches = icomplete_matches, - mi_docs = docs, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields, - mi_src_hash = ms_hs_hash mod_summary - } + & set_mi_insts ( sortBy cmp_inst iface_insts) + & set_mi_fam_insts ( sortBy cmp_fam_inst iface_fam_insts) + & set_mi_rules ( sortBy cmp_rule iface_rules) + + & set_mi_fixities ( fixities) + & set_mi_warns ( warns) + & set_mi_anns ( annotations) + & set_mi_globals ( rdrs) + & set_mi_used_th ( used_th) + & set_mi_decls ( decls) + & set_mi_extra_decls ( extra_decls) + & set_mi_hpc ( isHpcUsed hpc_info) + & set_mi_trust ( trust_info) + & set_mi_trust_pkg ( pkg_trust_req) + & set_mi_complete_matches ( icomplete_matches) + & set_mi_docs ( docs) + & set_mi_final_exts ( ()) + & set_mi_ext_fields ( emptyExtensibleFields) + & set_mi_src_hash ( ms_hs_hash mod_summary) + & set_mi_hi_bytes ( PartialIfaceBinHandle) + where cmp_rule = lexicalCompareFS `on` ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -83,6 +83,7 @@ import Data.Ord import Data.Containers.ListUtils import Data.Bifunctor import GHC.Iface.Errors.Ppr +import qualified GHC.Data.Strict as Strict {- ----------------------------------------------- @@ -1283,7 +1284,9 @@ addFingerprints hsc_env iface0 , mi_fix_fn = fix_fn , mi_hash_fn = lookupOccEnv local_env } - final_iface = iface0 { mi_decls = sorted_decls, mi_extra_decls = sorted_extra_decls, mi_final_exts = final_iface_exts } + final_iface = completePartialModIface iface0 + (sorted_decls) (sorted_extra_decls) (final_iface_exts) + (FullIfaceBinHandle Strict.Nothing) -- return final_iface ===================================== compiler/GHC/Iface/Rename.hs ===================================== @@ -44,6 +44,7 @@ import GHC.Utils.Panic import qualified Data.Traversable as T import Data.IORef +import Data.Function ((&)) tcRnMsgMaybe :: IO (Either (Messages TcRnMessage) a) -> TcM a tcRnMsgMaybe do_this = do @@ -108,13 +109,14 @@ rnModIface hsc_env insts nsubst iface = deps <- rnDependencies (mi_deps iface) -- TODO: -- mi_rules - return iface { mi_module = mod - , mi_sig_of = sig_of - , mi_insts = insts - , mi_fam_insts = fams - , mi_exports = exports - , mi_decls = decls - , mi_deps = deps } + return $ iface + & set_mi_module mod + & set_mi_sig_of sig_of + & set_mi_insts insts + & set_mi_fam_insts fams + & set_mi_exports exports + & set_mi_decls decls + & set_mi_deps deps -- | Rename just the exports of a 'ModIface'. Useful when we're doing -- shaping prior to signature merging. ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -76,7 +76,7 @@ import GHC.Tc.Utils.Unify ( tcSubTypeSigma ) import GHC.HsToCore.Docs ( extractDocs ) import GHC.Hs.Doc -import GHC.Unit.Module.ModIface ( ModIface_(..) ) +import GHC.Unit.Module.ModIface ( mi_docs ) import GHC.Iface.Load ( loadInterfaceForName ) import GHC.Builtin.Utils (knownKeyNames) ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1562,7 +1562,8 @@ lookupDeclDoc nm = do -- Wasn't in the current module. Try searching other external ones! mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_decls = dmap} } -> + Just iface + | Just Docs{docs_decls = dmap} <- mi_docs iface -> pure $ renderHsDocStrings . map hsDocString <$> lookupUniqMap dmap nm _ -> pure Nothing @@ -1578,7 +1579,8 @@ lookupArgDoc i nm = do Nothing -> do mIface <- getExternalModIface nm case mIface of - Just ModIface { mi_docs = Just Docs{docs_args = amap} } -> + Just iface + | Just Docs{docs_args = amap} <- mi_docs iface-> pure $ renderHsDocString . hsDocString <$> (lookupUniqMap amap nm >>= IntMap.lookup i) _ -> pure Nothing ===================================== compiler/GHC/Tc/Utils/Backpack.hs ===================================== @@ -87,6 +87,7 @@ import Control.Monad import Data.List (find) import GHC.Iface.Errors.Types +import Data.Function ((&)) checkHsigDeclM :: ModIface -> TyThing -> TyThing -> TcRn () checkHsigDeclM sig_iface sig_thing real_thing = do @@ -369,8 +370,8 @@ tcRnMergeSignatures hsc_env hpm orig_tcg_env iface = thinModIface :: [AvailInfo] -> ModIface -> ModIface thinModIface avails iface = - iface { - mi_exports = avails, + iface + & set_mi_exports avails -- mi_fixities = ..., -- mi_warns = ..., -- mi_anns = ..., @@ -378,10 +379,9 @@ thinModIface avails iface = -- perhaps there might be two IfaceTopBndr that are the same -- OccName but different Name. Requires better understanding -- of invariants here. - mi_decls = exported_decls ++ non_exported_decls ++ dfun_decls + & set_mi_decls (exported_decls ++ non_exported_decls ++ dfun_decls) -- mi_insts = ..., -- mi_fam_insts = ..., - } where decl_pred occs decl = nameOccName (ifName decl) `elemOccSet` occs filter_decls occs = filter (decl_pred occs . snd) (mi_decls iface) ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -7,7 +7,60 @@ module GHC.Unit.Module.ModIface ( ModIface - , ModIface_ (..) + , ModIface_ + , addSourceFingerprint + , mi_module + , mi_sig_of + , mi_hsc_src + , mi_src_hash + , mi_hi_bytes + , mi_deps + , mi_usages + , mi_exports + , mi_used_th + , mi_fixities + , mi_warns + , mi_anns + , mi_insts + , mi_fam_insts + , mi_rules + , mi_decls + , mi_extra_decls + , mi_globals + , mi_hpc + , mi_trust + , mi_trust_pkg + , mi_complete_matches + , mi_docs + , mi_final_exts + , mi_ext_fields + , set_mi_module + , set_mi_sig_of + , set_mi_hsc_src + , set_mi_src_hash + , set_mi_hi_bytes + , set_mi_deps + , set_mi_usages + , set_mi_exports + , set_mi_used_th + , set_mi_fixities + , set_mi_warns + , set_mi_anns + , set_mi_insts + , set_mi_fam_insts + , set_mi_rules + , set_mi_decls + , set_mi_extra_decls + , set_mi_globals + , set_mi_hpc + , set_mi_trust + , set_mi_trust_pkg + , set_mi_complete_matches + , set_mi_docs + , set_mi_final_exts + , set_mi_ext_fields + , completePartialModIface + , IfaceBinHandle(..) , PartialModIface , ModIfaceBackend (..) , IfaceDeclExts @@ -58,6 +111,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import qualified GHC.Data.Strict as Strict {- Note [Interface file stages] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -139,7 +193,9 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where IfaceBackendExts 'ModIfaceCore = () IfaceBackendExts 'ModIfaceFinal = ModIfaceBackend - +data IfaceBinHandle (phase :: ModIfacePhase) where + PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore + FullIfaceBinHandle :: Strict.Maybe FullBinData -> IfaceBinHandle 'ModIfaceFinal -- | A 'ModIface' plus a 'ModDetails' summarises everything we know -- about a compiled module. The 'ModIface' is the stuff *before* linking, @@ -155,60 +211,60 @@ type family IfaceBackendExts (phase :: ModIfacePhase) = bk | bk -> phase where -- strict and others are not. data ModIface_ (phase :: ModIfacePhase) = ModIface { - mi_module :: !Module, -- ^ Name of the module we are for - mi_sig_of :: !(Maybe Module), -- ^ Are we a sig of another mod? + mi_module_ :: !Module, -- ^ Name of the module we are for + mi_sig_of_ :: !(Maybe Module), -- ^ Are we a sig of another mod? - mi_hsc_src :: !HscSource, -- ^ Boot? Signature? + mi_hsc_src_ :: !HscSource, -- ^ Boot? Signature? - mi_deps :: Dependencies, + mi_deps_ :: Dependencies, -- ^ The dependencies of the module. This is -- consulted for directly-imported modules, but not -- for anything else (hence lazy) - mi_usages :: [Usage], + mi_usages_ :: [Usage], -- ^ Usages; kept sorted so that it's easy to decide -- whether to write a new iface file (changing usages -- doesn't affect the hash of this module) -- NOT STRICT! we read this field lazily from the interface file -- It is *only* consulted by the recompilation checker - mi_exports :: ![IfaceExport], + mi_exports_ :: ![IfaceExport], -- ^ Exports -- Kept sorted by (mod,occ), to make version comparisons easier -- Records the modules that are the declaration points for things -- exported by this module, and the 'OccName's of those things - mi_used_th :: !Bool, + mi_used_th_ :: !Bool, -- ^ Module required TH splices when it was compiled. -- This disables recompilation avoidance (see #481). - mi_fixities :: [(OccName,Fixity)], + mi_fixities_ :: [(OccName,Fixity)], -- ^ Fixities -- NOT STRICT! we read this field lazily from the interface file - mi_warns :: IfaceWarnings, + mi_warns_ :: IfaceWarnings, -- ^ Warnings -- NOT STRICT! we read this field lazily from the interface file - mi_anns :: [IfaceAnnotation], + mi_anns_ :: [IfaceAnnotation], -- ^ Annotations -- NOT STRICT! we read this field lazily from the interface file - mi_decls :: [IfaceDeclExts phase], + mi_decls_ :: [IfaceDeclExts phase], -- ^ Type, class and variable declarations -- The hash of an Id changes if its fixity or deprecations change -- (as well as its type of course) -- Ditto data constructors, class operations, except that -- the hash of the parent class/tycon changes - mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo], + mi_extra_decls_ :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo], -- ^ Extra variable definitions which are **NOT** exposed but when -- combined with mi_decls allows us to restart code generation. -- See Note [Interface Files with Core Definitions] and Note [Interface File with Core: Sharing RHSs] - mi_globals :: !(Maybe IfGlobalRdrEnv), + mi_globals_ :: !(Maybe IfGlobalRdrEnv), -- ^ Binds all the things defined at the top level in -- the /original source/ code for this module. which -- is NOT the same as mi_exports, nor mi_decls (which @@ -224,36 +280,36 @@ data ModIface_ (phase :: ModIfacePhase) -- 'HomeModInfo', but that leads to more plumbing. -- Instance declarations and rules - mi_insts :: [IfaceClsInst], -- ^ Sorted class instance - mi_fam_insts :: [IfaceFamInst], -- ^ Sorted family instances - mi_rules :: [IfaceRule], -- ^ Sorted rules + mi_insts_ :: [IfaceClsInst], -- ^ Sorted class instance + mi_fam_insts_ :: [IfaceFamInst], -- ^ Sorted family instances + mi_rules_ :: [IfaceRule], -- ^ Sorted rules - mi_hpc :: !AnyHpcUsage, + mi_hpc_ :: !AnyHpcUsage, -- ^ True if this program uses Hpc at any point in the program. - mi_trust :: !IfaceTrustInfo, + mi_trust_ :: !IfaceTrustInfo, -- ^ Safe Haskell Trust information for this module. - mi_trust_pkg :: !Bool, + mi_trust_pkg_ :: !Bool, -- ^ Do we require the package this module resides in be trusted -- to trust this module? This is used for the situation where a -- module is Safe (so doesn't require the package be trusted -- itself) but imports some trustworthy modules from its own -- package (which does require its own package be trusted). -- See Note [Trust Own Package] in GHC.Rename.Names - mi_complete_matches :: ![IfaceCompleteMatch], + mi_complete_matches_ :: ![IfaceCompleteMatch], - mi_docs :: !(Maybe Docs), + mi_docs_ :: !(Maybe Docs), -- ^ Docstrings and related data for use by haddock, the ghci -- @:doc@ command, and other tools. -- -- @Just _@ @<=>@ the module was built with @-haddock at . - mi_final_exts :: !(IfaceBackendExts phase), + mi_final_exts_ :: !(IfaceBackendExts phase), -- ^ Either `()` or `ModIfaceBackend` for -- a fully instantiated interface. - mi_ext_fields :: !ExtensibleFields, + mi_ext_fields_ :: !ExtensibleFields, -- ^ Additional optional fields, where the Map key represents -- the field name, resulting in a (size, serialized data) pair. -- Because the data is intended to be serialized through the @@ -262,8 +318,9 @@ data ModIface_ (phase :: ModIfacePhase) -- chosen over `ByteString`s. -- - mi_src_hash :: !Fingerprint + mi_src_hash_ :: !Fingerprint, -- ^ Hash of the .hs source, used for recompilation checking. + mi_hi_bytes_ :: !(IfaceBinHandle phase) } {- @@ -343,33 +400,34 @@ renameFreeHoles fhs insts = -- See Note [Strictness in ModIface] about where we use lazyPut vs put instance Binary ModIface where put_ bh (ModIface { - mi_module = mod, - mi_sig_of = sig_of, - mi_hsc_src = hsc_src, - mi_src_hash = _src_hash, -- Don't `put_` this in the instance + mi_module_ = mod, + mi_sig_of_ = sig_of, + mi_hsc_src_ = hsc_src, + mi_src_hash_ = _src_hash, -- Don't `put_` this in the instance -- because we are going to write it -- out separately in the actual file - mi_deps = deps, - mi_usages = usages, - mi_exports = exports, - mi_used_th = used_th, - mi_fixities = fixities, - mi_warns = warns, - mi_anns = anns, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_insts = insts, - mi_fam_insts = fam_insts, - mi_rules = rules, - mi_hpc = hpc_info, - mi_trust = trust, - mi_trust_pkg = trust_pkg, - mi_complete_matches = complete_matches, - mi_docs = docs, - mi_ext_fields = _ext_fields, -- Don't `put_` this in the instance so we + mi_hi_bytes_ = _hi_bytes, -- TODO: explain + mi_deps_ = deps, + mi_usages_ = usages, + mi_exports_ = exports, + mi_used_th_ = used_th, + mi_fixities_ = fixities, + mi_warns_ = warns, + mi_anns_ = anns, + mi_decls_ = decls, + mi_extra_decls_ = extra_decls, + mi_insts_ = insts, + mi_fam_insts_ = fam_insts, + mi_rules_ = rules, + mi_hpc_ = hpc_info, + mi_trust_ = trust, + mi_trust_pkg_ = trust_pkg, + mi_complete_matches_ = complete_matches, + mi_docs_ = docs, + mi_ext_fields_ = _ext_fields, -- Don't `put_` this in the instance so we -- can deal with it's pointer in the header -- when we write the actual file - mi_final_exts = ModIfaceBackend { + mi_final_exts_ = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, mi_flag_hash = flag_hash, @@ -444,33 +502,34 @@ instance Binary ModIface where complete_matches <- get bh docs <- lazyGetMaybe bh return (ModIface { - mi_module = mod, - mi_sig_of = sig_of, - mi_hsc_src = hsc_src, - mi_src_hash = fingerprint0, -- placeholder because this is dealt + mi_module_ = mod, + mi_sig_of_ = sig_of, + mi_hsc_src_ = hsc_src, + mi_src_hash_ = fingerprint0, -- placeholder because this is dealt -- with specially when the file is read - mi_deps = deps, - mi_usages = usages, - mi_exports = exports, - mi_used_th = used_th, - mi_anns = anns, - mi_fixities = fixities, - mi_warns = warns, - mi_decls = decls, - mi_extra_decls = extra_decls, - mi_globals = Nothing, - mi_insts = insts, - mi_fam_insts = fam_insts, - mi_rules = rules, - mi_hpc = hpc_info, - mi_trust = trust, - mi_trust_pkg = trust_pkg, + mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing, + mi_deps_ = deps, + mi_usages_ = usages, + mi_exports_ = exports, + mi_used_th_ = used_th, + mi_anns_ = anns, + mi_fixities_ = fixities, + mi_warns_ = warns, + mi_decls_ = decls, + mi_extra_decls_ = extra_decls, + mi_globals_ = Nothing, + mi_insts_ = insts, + mi_fam_insts_ = fam_insts, + mi_rules_ = rules, + mi_hpc_ = hpc_info, + mi_trust_ = trust, + mi_trust_pkg_ = trust_pkg, -- And build the cached values - mi_complete_matches = complete_matches, - mi_docs = docs, - mi_ext_fields = emptyExtensibleFields, -- placeholder because this is dealt + mi_complete_matches_ = complete_matches, + mi_docs_ = docs, + mi_ext_fields_ = emptyExtensibleFields, -- placeholder because this is dealt -- with specially when the file is read - mi_final_exts = ModIfaceBackend { + mi_final_exts_ = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, mi_flag_hash = flag_hash, @@ -487,42 +546,45 @@ instance Binary ModIface where mi_hash_fn = mkIfaceHashCache decls }}) + -- | The original names declared of a certain module that are exported type IfaceExport = AvailInfo emptyPartialModIface :: Module -> PartialModIface emptyPartialModIface mod - = ModIface { mi_module = mod, - mi_sig_of = Nothing, - mi_hsc_src = HsSrcFile, - mi_src_hash = fingerprint0, - mi_deps = noDependencies, - mi_usages = [], - mi_exports = [], - mi_used_th = False, - mi_fixities = [], - mi_warns = IfWarnSome [] [], - mi_anns = [], - mi_insts = [], - mi_fam_insts = [], - mi_rules = [], - mi_decls = [], - mi_extra_decls = Nothing, - mi_globals = Nothing, - mi_hpc = False, - mi_trust = noIfaceTrustInfo, - mi_trust_pkg = False, - mi_complete_matches = [], - mi_docs = Nothing, - mi_final_exts = (), - mi_ext_fields = emptyExtensibleFields + = ModIface { mi_module_ = mod, + mi_sig_of_ = Nothing, + mi_hsc_src_ = HsSrcFile, + mi_src_hash_ = fingerprint0, + mi_hi_bytes_ = PartialIfaceBinHandle, + mi_deps_ = noDependencies, + mi_usages_ = [], + mi_exports_ = [], + mi_used_th_ = False, + mi_fixities_ = [], + mi_warns_ = IfWarnSome [] [], + mi_anns_ = [], + mi_insts_ = [], + mi_fam_insts_ = [], + mi_rules_ = [], + mi_decls_ = [], + mi_extra_decls_ = Nothing, + mi_globals_ = Nothing, + mi_hpc_ = False, + mi_trust_ = noIfaceTrustInfo, + mi_trust_pkg_ = False, + mi_complete_matches_ = [], + mi_docs_ = Nothing, + mi_final_exts_ = (), + mi_ext_fields_ = emptyExtensibleFields } emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) - { mi_decls = [] - , mi_final_exts = ModIfaceBackend + { mi_decls_ = [] + , mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing + , mi_final_exts_ = ModIfaceBackend { mi_iface_hash = fingerprint0, mi_mod_hash = fingerprint0, mi_flag_hash = fingerprint0, @@ -557,36 +619,36 @@ emptyIfaceHashCache _occ = Nothing instance ( NFData (IfaceBackendExts (phase :: ModIfacePhase)) , NFData (IfaceDeclExts (phase :: ModIfacePhase)) ) => NFData (ModIface_ phase) where - rnf (ModIface{ mi_module, mi_sig_of, mi_hsc_src, mi_deps, mi_usages - , mi_exports, mi_used_th, mi_fixities, mi_warns, mi_anns - , mi_decls, mi_extra_decls, mi_globals, mi_insts - , mi_fam_insts, mi_rules, mi_hpc, mi_trust, mi_trust_pkg - , mi_complete_matches, mi_docs, mi_final_exts - , mi_ext_fields, mi_src_hash }) - = rnf mi_module - `seq` rnf mi_sig_of - `seq` mi_hsc_src - `seq` mi_deps - `seq` mi_usages - `seq` mi_exports - `seq` rnf mi_used_th - `seq` mi_fixities - `seq` rnf mi_warns - `seq` rnf mi_anns - `seq` rnf mi_decls - `seq` rnf mi_extra_decls - `seq` rnf mi_globals - `seq` rnf mi_insts - `seq` rnf mi_fam_insts - `seq` rnf mi_rules - `seq` rnf mi_hpc - `seq` mi_trust - `seq` rnf mi_trust_pkg - `seq` rnf mi_complete_matches - `seq` rnf mi_docs - `seq` mi_final_exts - `seq` mi_ext_fields - `seq` rnf mi_src_hash + rnf (ModIface{ mi_module_, mi_sig_of_, mi_hsc_src_, mi_deps_, mi_usages_ + , mi_exports_, mi_used_th_, mi_fixities_, mi_warns_, mi_anns_ + , mi_decls_, mi_extra_decls_, mi_globals_, mi_insts_ + , mi_fam_insts_, mi_rules_, mi_hpc_, mi_trust_, mi_trust_pkg_ + , mi_complete_matches_, mi_docs_, mi_final_exts_ + , mi_ext_fields_, mi_src_hash_ }) + = rnf mi_module_ + `seq` rnf mi_sig_of_ + `seq` mi_hsc_src_ + `seq` mi_deps_ + `seq` mi_usages_ + `seq` mi_exports_ + `seq` rnf mi_used_th_ + `seq` mi_fixities_ + `seq` rnf mi_warns_ + `seq` rnf mi_anns_ + `seq` rnf mi_decls_ + `seq` rnf mi_extra_decls_ + `seq` rnf mi_globals_ + `seq` rnf mi_insts_ + `seq` rnf mi_fam_insts_ + `seq` rnf mi_rules_ + `seq` rnf mi_hpc_ + `seq` mi_trust_ + `seq` rnf mi_trust_pkg_ + `seq` rnf mi_complete_matches_ + `seq` rnf mi_docs_ + `seq` mi_final_exts_ + `seq` mi_ext_fields_ + `seq` rnf mi_src_hash_ `seq` () instance NFData (ModIfaceBackend) where @@ -626,5 +688,151 @@ type WhetherHasOrphans = Bool -- | Does this module define family instances? type WhetherHasFamInst = Bool +completePartialModIface :: PartialModIface + -> [(Fingerprint, IfaceDecl)] + -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + -> ModIfaceBackend + -> IfaceBinHandle 'ModIfaceFinal + -> ModIface +completePartialModIface partial decls extra_decls final_exts hi_bytes = partial + { mi_decls_ = decls + , mi_extra_decls_ = extra_decls + , mi_final_exts_ = final_exts + , mi_hi_bytes_ = hi_bytes + } + +addSourceFingerprint :: Fingerprint -> ModIface_ 'ModIfaceFinal -> ModIface_ 'ModIfaceFinal +addSourceFingerprint val iface = iface { mi_src_hash_ = val } + +set_mi_module :: Module -> ModIface_ phase -> ModIface_ phase +set_mi_module val iface = clear_mi_hi_bytes $ iface { mi_module_ = val } + +set_mi_sig_of :: Maybe Module -> ModIface_ phase -> ModIface_ phase +set_mi_sig_of val iface = clear_mi_hi_bytes $ iface { mi_sig_of_ = val } + +set_mi_hsc_src :: HscSource -> ModIface_ phase -> ModIface_ phase +set_mi_hsc_src val iface = clear_mi_hi_bytes $ iface { mi_hsc_src_ = val } + +set_mi_src_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase +set_mi_src_hash val iface = clear_mi_hi_bytes $ iface { mi_src_hash_ = val } + +set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes val iface = iface { mi_hi_bytes_ = val } + +set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase +set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps_ = val } + +set_mi_usages :: [Usage] -> ModIface_ phase -> ModIface_ phase +set_mi_usages val iface = clear_mi_hi_bytes $ iface { mi_usages_ = val } + +set_mi_exports :: [IfaceExport] -> ModIface_ phase -> ModIface_ phase +set_mi_exports val iface = clear_mi_hi_bytes $ iface { mi_exports_ = val } + +set_mi_used_th :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_used_th val iface = clear_mi_hi_bytes $ iface { mi_used_th_ = val } + +set_mi_fixities :: [(OccName, Fixity)] -> ModIface_ phase -> ModIface_ phase +set_mi_fixities val iface = clear_mi_hi_bytes $ iface { mi_fixities_ = val } + +set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase +set_mi_warns val iface = clear_mi_hi_bytes $ iface { mi_warns_ = val } +set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase +set_mi_anns val iface = clear_mi_hi_bytes $ iface { mi_anns_ = val } + +set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase +set_mi_insts val iface = clear_mi_hi_bytes $ iface { mi_insts_ = val } + +set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase +set_mi_fam_insts val iface = clear_mi_hi_bytes $ iface { mi_fam_insts_ = val } + +set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase +set_mi_rules val iface = clear_mi_hi_bytes $ iface { mi_rules_ = val } + +set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase +set_mi_decls val iface = clear_mi_hi_bytes $ iface { mi_decls_ = val } + +set_mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -> ModIface_ phase -> ModIface_ phase +set_mi_extra_decls val iface = clear_mi_hi_bytes $ iface { mi_extra_decls_ = val } + +set_mi_globals :: Maybe IfGlobalRdrEnv -> ModIface_ phase -> ModIface_ phase +set_mi_globals val iface = clear_mi_hi_bytes $ iface { mi_globals_ = val } + +set_mi_hpc :: AnyHpcUsage -> ModIface_ phase -> ModIface_ phase +set_mi_hpc val iface = clear_mi_hi_bytes $ iface { mi_hpc_ = val } + +set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase +set_mi_trust val iface = clear_mi_hi_bytes $ iface { mi_trust_ = val } + +set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase +set_mi_trust_pkg val iface = clear_mi_hi_bytes $ iface { mi_trust_pkg_ = val } + +set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase +set_mi_complete_matches val iface = clear_mi_hi_bytes $ iface { mi_complete_matches_ = val } + +set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase +set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs_ = val } + +set_mi_final_exts :: IfaceBackendExts phase -> ModIface_ phase -> ModIface_ phase +set_mi_final_exts val iface = clear_mi_hi_bytes $ iface { mi_final_exts_ = val } + +set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase +set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields_ = val } + +clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase +clear_mi_hi_bytes iface = iface + { mi_hi_bytes_ = case mi_hi_bytes iface of + PartialIfaceBinHandle -> PartialIfaceBinHandle + FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing + } +mi_module :: ModIface_ phase -> Module +mi_module = mi_module_ +mi_sig_of :: ModIface_ phase -> Maybe Module +mi_sig_of = mi_sig_of_ +mi_hsc_src :: ModIface_ phase -> HscSource +mi_hsc_src = mi_hsc_src_ +mi_deps :: ModIface_ phase -> Dependencies +mi_deps = mi_deps_ +mi_usages :: ModIface_ phase -> [Usage] +mi_usages = mi_usages_ +mi_exports :: ModIface_ phase -> [IfaceExport] +mi_exports = mi_exports_ +mi_used_th :: ModIface_ phase -> Bool +mi_used_th = mi_used_th_ +mi_fixities :: ModIface_ phase -> [(OccName, Fixity)] +mi_fixities = mi_fixities_ +mi_warns :: ModIface_ phase -> IfaceWarnings +mi_warns = mi_warns_ +mi_anns :: ModIface_ phase -> [IfaceAnnotation] +mi_anns = mi_anns_ +mi_decls :: ModIface_ phase -> [IfaceDeclExts phase] +mi_decls = mi_decls_ +mi_extra_decls :: ModIface_ phase -> Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] +mi_extra_decls = mi_extra_decls_ +mi_globals :: ModIface_ phase -> Maybe IfGlobalRdrEnv +mi_globals = mi_globals_ +mi_insts :: ModIface_ phase -> [IfaceClsInst] +mi_insts = mi_insts_ +mi_fam_insts :: ModIface_ phase -> [IfaceFamInst] +mi_fam_insts = mi_fam_insts_ +mi_rules :: ModIface_ phase -> [IfaceRule] +mi_rules = mi_rules_ +mi_hpc :: ModIface_ phase -> AnyHpcUsage +mi_hpc = mi_hpc_ +mi_trust :: ModIface_ phase -> IfaceTrustInfo +mi_trust = mi_trust_ +mi_trust_pkg :: ModIface_ phase -> Bool +mi_trust_pkg = mi_trust_pkg_ +mi_complete_matches :: ModIface_ phase -> [IfaceCompleteMatch] +mi_complete_matches = mi_complete_matches_ +mi_docs :: ModIface_ phase -> Maybe Docs +mi_docs = mi_docs_ +mi_final_exts :: ModIface_ phase -> IfaceBackendExts phase +mi_final_exts = mi_final_exts_ +mi_ext_fields :: ModIface_ phase -> ExtensibleFields +mi_ext_fields = mi_ext_fields_ +mi_src_hash :: ModIface_ phase -> Fingerprint +mi_src_hash = mi_src_hash_ +mi_hi_bytes :: ModIface_ phase -> IfaceBinHandle phase +mi_hi_bytes = mi_hi_bytes_ ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -19,7 +19,7 @@ -- http://www.cs.york.ac.uk/fp/nhc98/ module GHC.Utils.Binary - ( {-type-} Bin, + ( {-type-} Bin, RelBin(..), getRelBin, {-class-} Binary(..), {-type-} ReadBinHandle, WriteBinHandle, SymbolTable, Dictionary, @@ -32,11 +32,13 @@ module GHC.Utils.Binary seekBinWriter, seekBinReader, + seekBinReaderRel, tellBinReader, tellBinWriter, castBin, withBinBuffer, freezeWriteHandle, + shrinkBinBuffer, thawReadHandle, foldGet, foldGet', @@ -46,7 +48,9 @@ module GHC.Utils.Binary readBinMemN, putAt, getAt, + putAtRel, forwardPut, forwardPut_, forwardGet, + forwardPutRel, forwardPutRel_, forwardGetRel, -- * For writing instances putByte, @@ -101,6 +105,9 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + FullBinData(..), freezeBinHandle, thawBinHandle, putFullBinData, + freezeBinHandle2, + BinArray, ) where import GHC.Prelude @@ -125,7 +132,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -155,7 +162,6 @@ import GHC.ForeignPtr ( unsafeWithForeignPtr ) import Unsafe.Coerce (unsafeCoerce) import GHC.Data.TrieMap - type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -195,6 +201,51 @@ dataHandle (BinData size bin) = do handleData :: WriteBinHandle -> IO BinData handleData (WriteBinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr +--------------------------------------------------------------- +-- FullBinData +--------------------------------------------------------------- + +data FullBinData = FullBinData + { fbd_readerUserData :: ReaderUserData + , fbd_off_s :: {-# UNPACK #-} !Int + -- ^ start offset + , fbd_off_e :: {-# UNPACK #-} !Int + -- ^ end offset + , fbd_size :: {-# UNPACK #-} !Int + -- ^ total buffer size + , fbd_buffer :: {-# UNPACK #-} !BinArray + } + +-- Equality and Ord assume that two distinct buffers are different, even if they compare the same things. +instance Eq FullBinData where + (FullBinData _ b c d e) == (FullBinData _ b1 c1 d1 e1) = b == b1 && c == c1 && d == d1 && e == e1 + +instance Ord FullBinData where + compare (FullBinData _ b c d e) (FullBinData _ b1 c1 d1 e1) = + compare b b1 `mappend` compare c c1 `mappend` compare d d1 `mappend` compare e e1 + +putFullBinData :: WriteBinHandle -> FullBinData -> IO () +putFullBinData bh (FullBinData _ o1 o2 _sz ba) = do + let sz = o2 - o1 + putPrim bh sz $ \dest -> + unsafeWithForeignPtr (ba `plusForeignPtr` o1) $ \orig -> + copyBytes dest orig sz + +freezeBinHandle :: Bin () -> ReadBinHandle -> IO FullBinData +freezeBinHandle (BinPtr len) (ReadBinMem user_data ixr sz binr) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data ix len sz binr) + +freezeBinHandle2 :: ReadBinHandle -> Bin () -> IO FullBinData +freezeBinHandle2 (ReadBinMem user_data ixr sz binr) (BinPtr start) = do + ix <- readFastMutInt ixr + pure (FullBinData user_data start ix sz binr) + +thawBinHandle :: FullBinData -> IO ReadBinHandle +thawBinHandle (FullBinData user_data ix _end sz ba) = do + ixr <- newFastMutInt ix + return $ ReadBinMem user_data ixr sz ba + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- @@ -288,9 +339,30 @@ unsafeUnpackBinBuffer (BS.BS arr len) = do newtype Bin a = BinPtr Int deriving (Eq, Ord, Show, Bounded) +data RelBin a = RelBin !(Bin a) !(Bin a) + deriving (Eq, Ord, Show, Bounded) + +newtype RelBinPtr a = RelBinPtr (Bin a) + castBin :: Bin a -> Bin b castBin (BinPtr i) = BinPtr i +getRelBin :: ReadBinHandle -> IO (RelBin a) +getRelBin bh = do + start <- tellBinReader bh + off <- get bh + pure $ RelBin start off + +makeAbsoluteBin :: RelBin a -> Bin a +makeAbsoluteBin (RelBin (BinPtr !start) (BinPtr !offset)) = BinPtr (start + offset) + +makeRelativeBin :: RelBin a -> RelBinPtr a +makeRelativeBin (RelBin _ offset) = RelBinPtr offset + +toRelBin :: Bin (RelBinPtr a) -> Bin a -> RelBin a +toRelBin (BinPtr !start) (BinPtr !goal) = + RelBin (BinPtr start) (BinPtr $! goal - start) + --------------------------------------------------------------- -- class Binary --------------------------------------------------------------- @@ -311,6 +383,9 @@ class Binary a where putAt :: Binary a => WriteBinHandle -> Bin a -> a -> IO () putAt bh p x = do seekBinWriter bh p; put_ bh x; return () +putAtRel :: WriteBinHandle -> Bin (RelBinPtr a) -> Bin a -> IO () +putAtRel bh from to = putAt bh from (makeRelativeBin $ toRelBin from to) + getAt :: Binary a => ReadBinHandle -> Bin a -> IO a getAt bh p = do seekBinReader bh p; get bh @@ -344,6 +419,17 @@ freezeWriteHandle wbm = do , rbm_arr_r = rbm_arr_r } +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + thawReadHandle :: ReadBinHandle -> IO WriteBinHandle thawReadHandle rbm = do wbm_off_r <- newFastMutInt =<< readFastMutInt (rbm_off_r rbm) @@ -381,12 +467,18 @@ seekBinNoExpandWriter (WriteBinMem _ ix_r sz_r _) (BinPtr !p) = do else writeFastMutInt ix_r p -- | SeekBin but without calling expandBin -seekBinReader :: ReadBinHandle -> Bin a -> IO () +seekBinReader :: HasCallStack => ReadBinHandle -> Bin a -> IO () seekBinReader (ReadBinMem _ ix_r sz_r _) (BinPtr !p) = do if (p > sz_r) then panic "seekBinReader: seek out of range" else writeFastMutInt ix_r p +seekBinReaderRel :: HasCallStack => ReadBinHandle -> RelBin a -> IO () +seekBinReaderRel (ReadBinMem _ ix_r sz_r _) (RelBin (BinPtr !start) (BinPtr !offset)) = do + if (start + offset > sz_r) + then panic "seekBinReaderRel: seek out of range" + else writeFastMutInt ix_r (start + offset) + writeBinMem :: WriteBinHandle -> FilePath -> IO () writeBinMem (WriteBinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode @@ -1107,6 +1199,11 @@ instance Binary (Bin a) where put_ bh (BinPtr i) = putWord32 bh (fromIntegral i :: Word32) get bh = do i <- getWord32 bh; return (BinPtr (fromIntegral (i :: Word32))) +-- Instance uses fixed-width encoding to allow inserting +-- Bin placeholders in the stream. +instance Binary (RelBinPtr a) where + put_ bh (RelBinPtr i) = put_ bh i + get bh = RelBinPtr <$> get bh -- ----------------------------------------------------------------------------- -- Forward reading/writing @@ -1135,7 +1232,7 @@ forwardPut_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B -- | Read a value stored using a forward reference -forwardGet :: ReadBinHandle -> IO a -> IO a +forwardGet :: HasCallStack => ReadBinHandle -> IO a -> IO a forwardGet bh get_A = do -- read forward reference p <- get bh -- a BinPtr @@ -1147,6 +1244,43 @@ forwardGet bh get_A = do seekBinReader bh p_a pure r + +-- | "forwardPutRel put_A put_B" outputs A after B but allows A to be read before B +-- by using a forward reference. +forwardPutRel :: WriteBinHandle -> (b -> IO a) -> IO b -> IO (a,b) +forwardPutRel bh put_A put_B = do + -- write placeholder pointer to A + pre_a <- tellBinWriter bh + put_ bh pre_a + + -- write B + r_b <- put_B + + -- update A's pointer + a <- tellBinWriter bh + putAtRel bh pre_a a + seekBinNoExpandWriter bh a + + -- write A + r_a <- put_A r_b + pure (r_a,r_b) + +forwardPutRel_ :: WriteBinHandle -> (b -> IO a) -> IO b -> IO () +forwardPutRel_ bh put_A put_B = void $ forwardPutRel bh put_A put_B + +-- | Read a value stored using a forward reference +forwardGetRel :: ReadBinHandle -> IO a -> IO a +forwardGetRel bh get_A = do + -- read forward reference + p <- getRelBin bh + -- store current position + p_a <- tellBinReader bh + -- go read the forward value, then seek back + seekBinReader bh $ makeAbsoluteBin p + r <- get_A + seekBinReader bh p_a + pure r + -- ----------------------------------------------------------------------------- -- Lazy reading/writing @@ -1156,19 +1290,19 @@ lazyPut = lazyPut' put_ lazyGet :: Binary a => ReadBinHandle -> IO a lazyGet = lazyGet' get -lazyPut' :: HasDebugCallStack => (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () +lazyPut' :: (WriteBinHandle -> a -> IO ()) -> WriteBinHandle -> a -> IO () lazyPut' f bh a = do -- output the obj with a ptr to skip over it: pre_a <- tellBinWriter bh put_ bh pre_a -- save a slot for the ptr f bh a -- dump the object q <- tellBinWriter bh -- q = ptr to after object - putAt bh pre_a q -- fill in slot before a with ptr to q + putAtRel bh pre_a q -- fill in slot before a with ptr to q seekBinWriter bh q -- finally carry on writing at q lazyGet' :: HasDebugCallStack => (ReadBinHandle -> IO a) -> ReadBinHandle -> IO a lazyGet' f bh = do - p <- get bh -- a BinPtr + p <- getRelBin bh -- a BinPtr p_a <- tellBinReader bh a <- unsafeInterleaveIO $ do -- NB: Use a fresh rbm_off_r variable in the child thread, for thread @@ -1177,7 +1311,7 @@ lazyGet' f bh = do let bh' = bh { rbm_off_r = off_r } seekBinReader bh' p_a f bh' - seekBinReader bh p -- skip over the object for now + seekBinReader bh (makeAbsoluteBin p) -- skip over the object for now return a -- | Serialize the constructor strictly but lazily serialize a value inside a @@ -1471,13 +1605,13 @@ putGenericSymbolTable gen_sym_tab serialiser bh = do mapM_ (\n -> serialiser bh n) (reverse todo) loop snd <$> - (forwardPut bh (const $ readFastMutInt symtab_next >>= put_ bh) $ + (forwardPutRel bh (const $ readFastMutInt symtab_next >>= put_ bh) $ loop) -- | Read the elements of a 'GenericSymbolTable' from disk into a 'SymbolTable'. getGenericSymbolTable :: forall a . (ReadBinHandle -> IO a) -> ReadBinHandle -> IO (SymbolTable a) getGenericSymbolTable deserialiser bh = do - sz <- forwardGet bh (get bh) :: IO Int + sz <- forwardGetRel bh (get bh) :: IO Int mut_arr <- newArray_ (0, sz-1) :: IO (IOArray Int a) forM_ [0..(sz-1)] $ \i -> do f <- deserialiser bh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebe3a0ad890dfe6a56d64bd486f69d4dc4fe057a...6a17f57fbc172195c129561eb250fb5de03b0781 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebe3a0ad890dfe6a56d64bd486f69d4dc4fe057a...6a17f57fbc172195c129561eb250fb5de03b0781 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 10:23:55 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 06:23:55 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing] Shrink Bin buffer Message-ID: <6630c6bb7d181_2fbef54e5020684fa@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing at Glasgow Haskell Compiler / GHC Commits: 80821eac by Fendor at 2024-04-30T12:22:45+02:00 Shrink Bin buffer - - - - - 1 changed file: - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -37,6 +37,7 @@ module GHC.Utils.Binary castBin, withBinBuffer, freezeWriteHandle, + shrinkBinBuffer, thawReadHandle, foldGet, foldGet', @@ -101,6 +102,7 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + BinArray, ) where import GHC.Prelude @@ -125,7 +127,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -344,6 +346,17 @@ freezeWriteHandle wbm = do , rbm_arr_r = rbm_arr_r } +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + thawReadHandle :: ReadBinHandle -> IO WriteBinHandle thawReadHandle rbm = do wbm_off_r <- newFastMutInt =<< readFastMutInt (rbm_off_r rbm) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/80821eac0039229c5d52e1deb3e8c627262c903a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/80821eac0039229c5d52e1deb3e8c627262c903a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 10:25:20 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 06:25:20 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing] Shrink Bin buffer Message-ID: <6630c710edaf5_2fbef55504b068635@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing at Glasgow Haskell Compiler / GHC Commits: 3f5bcc81 by Fendor at 2024-04-30T12:25:04+02:00 Shrink Bin buffer - - - - - 2 changed files: - compiler/GHC/Iface/Make.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -158,7 +158,7 @@ shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -37,6 +37,7 @@ module GHC.Utils.Binary castBin, withBinBuffer, freezeWriteHandle, + shrinkBinBuffer, thawReadHandle, foldGet, foldGet', @@ -101,6 +102,7 @@ module GHC.Utils.Binary BindingName(..), simpleBindingNameWriter, simpleBindingNameReader, + BinArray, ) where import GHC.Prelude @@ -125,7 +127,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -344,6 +346,17 @@ freezeWriteHandle wbm = do , rbm_arr_r = rbm_arr_r } +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + thawReadHandle :: ReadBinHandle -> IO WriteBinHandle thawReadHandle rbm = do wbm_off_r <- newFastMutInt =<< readFastMutInt (rbm_off_r rbm) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f5bcc81924ad148e1e1b60bfc4412422319e2e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f5bcc81924ad148e1e1b60bfc4412422319e2e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 10:25:47 2024 From: gitlab at gitlab.haskell.org (Hannes Siebenhandl (@fendor)) Date: Tue, 30 Apr 2024 06:25:47 -0400 Subject: [Git][ghc/ghc][wip/fendor/ghc-iface-sharing] Shrink Bin buffer Message-ID: <6630c72b93829_2fbef559556068875@gitlab.mail> Hannes Siebenhandl pushed to branch wip/fendor/ghc-iface-sharing at Glasgow Haskell Compiler / GHC Commits: 2cf700f8 by Fendor at 2024-04-30T12:25:39+02:00 Shrink Bin buffer - - - - - 2 changed files: - compiler/GHC/Iface/Make.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -158,7 +158,7 @@ shareIface nc compressionLevel mi = do bh <- openBinMem (1024 * 1024) start <- tellBinWriter bh putIfaceWithExtFields QuietBinIFace compressionLevel bh mi - rbh <- freezeWriteHandle bh + rbh <- shrinkBinBuffer bh seekBinReader rbh start res <- getIfaceWithExtFields nc rbh let resiface = res { mi_src_hash = mi_src_hash mi } ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -37,6 +37,7 @@ module GHC.Utils.Binary castBin, withBinBuffer, freezeWriteHandle, + shrinkBinBuffer, thawReadHandle, foldGet, foldGet', @@ -125,7 +126,7 @@ import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe -import Data.ByteString (ByteString) +import Data.ByteString (ByteString, copy) import Data.Coerce import qualified Data.ByteString.Internal as BS import qualified Data.ByteString.Unsafe as BS @@ -344,6 +345,17 @@ freezeWriteHandle wbm = do , rbm_arr_r = rbm_arr_r } +-- Copy the BinBuffer to a new BinBuffer which is exactly the right size. +-- This performs a copy of the underlying buffer. +-- The buffer may be truncated if the offset is not at the end of the written +-- output. +-- +-- UserData is also discarded during the copy +-- You should just use this when translating a Put handle into a Get handle. +shrinkBinBuffer :: WriteBinHandle -> IO ReadBinHandle +shrinkBinBuffer bh = withBinBuffer bh $ \bs -> do + unsafeUnpackBinBuffer (copy bs) + thawReadHandle :: ReadBinHandle -> IO WriteBinHandle thawReadHandle rbm = do wbm_off_r <- newFastMutInt =<< readFastMutInt (rbm_off_r rbm) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2cf700f834d4684bd05b76907503a09dd4d36e46 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2cf700f834d4684bd05b76907503a09dd4d36e46 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 11:01:32 2024 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Tue, 30 Apr 2024 07:01:32 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] 10 commits: Make read accepts binary integer formats Message-ID: <6630cf8cab6a1_2fbef597ca5c814c3@gitlab.mail> Cheng Shao pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 8e20ab33 by Andreas Klebinger at 2024-04-30T10:59:26+00:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - eec83538 by Andreas Klebinger at 2024-04-30T11:00:25+00:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 30 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - config.guess - config.sub - docs/users_guide/bugs.rst - hadrian/src/Rules/Compile.hs - libraries/base/changelog.md - libraries/base/tests/char001.hs - libraries/base/tests/char001.stdout - libraries/base/tests/lex001.hs - libraries/base/tests/lex001.stdout - libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - testsuite/tests/printer/Makefile - + testsuite/tests/printer/MatchPatComments.hs - testsuite/tests/printer/all.T - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T - utils/check-exact/Main.hs - − utils/vagrant/bootstrap-deb.sh - − utils/vagrant/bootstrap-rhel.sh Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -603,6 +603,7 @@ data ValidateRule = FullCI -- ^ Run this job when the "full-ci" label is present. | LLVMBackend -- ^ Run this job when the "LLVM backend" label is present | JSBackend -- ^ Run this job when the "javascript" label is present + | WasmBackend -- ^ Run this job when the "wasm" label is present | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set. | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set. | IpeData -- ^ Run this job when the "IPE" label is set @@ -649,6 +650,7 @@ validateRuleString FullCI = or_all ([ labelString "full-ci" validateRuleString LLVMBackend = labelString "LLVM backend" validateRuleString JSBackend = labelString "javascript" +validateRuleString WasmBackend = labelString "wasm" validateRuleString FreeBSDLabel = labelString "FreeBSD" validateRuleString NonmovingGc = labelString "non-moving GC" validateRuleString IpeData = labelString "IPE" @@ -1048,7 +1050,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux AlpineWasm) cfg + $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) ===================================== .gitlab/jobs.yaml ===================================== @@ -4502,7 +4502,7 @@ ], "rules": [ { - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -4566,7 +4566,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], @@ -4630,7 +4630,7 @@ "rules": [ { "allow_failure": true, - "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*wasm.*/)) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "manual" } ], ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -56,6 +56,7 @@ data Signage = Signed | Unsigned deriving (Eq, Show) genLlvmProc :: RawCmmDecl -> LlvmM [LlvmCmmDecl] genLlvmProc (CmmProc infos lbl live graph) = do let blocks = toBlockListEntryFirstFalseFallthrough graph + (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos proc = CmmProc info lbl live (ListGraph lmblocks) @@ -67,6 +68,11 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" -- * Block code generation -- +-- | Unreachable basic block +-- +-- See Note [Unreachable block as default destination in Switch] +newtype UnreachableBlockId = UnreachableBlockId BlockId + -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry -- point. @@ -82,20 +88,27 @@ basicBlocksCodeGen live cmmBlocks (prologue, prologueTops) <- funPrologue live cmmBlocks let entryBlock = BasicBlock bid (fromOL prologue) + -- allocate one unreachable basic block that can be used as a default + -- destination in exhaustive switches. + -- + -- See Note [Unreachable block as default destination in Switch] + ubid@(UnreachableBlockId ubid') <- (UnreachableBlockId . mkBlockId) <$> getUniqueM + let ubblock = BasicBlock ubid' [Unreachable] + -- Generate code - (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks + (blocks, topss) <- fmap unzip $ mapM (basicBlockCodeGen ubid) cmmBlocks -- Compose - return (entryBlock : blocks, prologueTops ++ concat topss) + return (entryBlock : ubblock : blocks, prologueTops ++ concat topss) -- | Generate code for one block -basicBlockCodeGen :: CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) -basicBlockCodeGen block +basicBlockCodeGen :: UnreachableBlockId -> CmmBlock -> LlvmM ( LlvmBasicBlock, [LlvmCmmDecl] ) +basicBlockCodeGen ubid block = do let (_, nodes, tail) = blockSplit block id = entryLabel block - (mid_instrs, top) <- stmtsToInstrs $ blockToList nodes - (tail_instrs, top') <- stmtToInstrs tail + (mid_instrs, top) <- stmtsToInstrs ubid $ blockToList nodes + (tail_instrs, top') <- stmtToInstrs ubid tail let instrs = fromOL (mid_instrs `appOL` tail_instrs) return (BasicBlock id instrs, top' ++ top) @@ -110,15 +123,15 @@ type StmtData = (LlvmStatements, [LlvmCmmDecl]) -- | Convert a list of CmmNode's to LlvmStatement's -stmtsToInstrs :: [CmmNode e x] -> LlvmM StmtData -stmtsToInstrs stmts - = do (instrss, topss) <- fmap unzip $ mapM stmtToInstrs stmts +stmtsToInstrs :: UnreachableBlockId -> [CmmNode e x] -> LlvmM StmtData +stmtsToInstrs ubid stmts + = do (instrss, topss) <- fmap unzip $ mapM (stmtToInstrs ubid) stmts return (concatOL instrss, concat topss) -- | Convert a CmmStmt to a list of LlvmStatement's -stmtToInstrs :: CmmNode e x -> LlvmM StmtData -stmtToInstrs stmt = case stmt of +stmtToInstrs :: UnreachableBlockId -> CmmNode e x -> LlvmM StmtData +stmtToInstrs ubid stmt = case stmt of CmmComment _ -> return (nilOL, []) -- nuke comments CmmTick _ -> return (nilOL, []) @@ -131,7 +144,7 @@ stmtToInstrs stmt = case stmt of CmmBranch id -> genBranch id CmmCondBranch arg true false likely -> genCondBranch arg true false likely - CmmSwitch arg ids -> genSwitch arg ids + CmmSwitch arg ids -> genSwitch ubid arg ids -- Foreign Call CmmUnsafeForeignCall target res args @@ -1305,21 +1318,38 @@ For a real example of this, see ./rts/StgStdThunks.cmm -- | Switch branch -genSwitch :: CmmExpr -> SwitchTargets -> LlvmM StmtData -genSwitch cond ids = do +genSwitch :: UnreachableBlockId -> CmmExpr -> SwitchTargets -> LlvmM StmtData +genSwitch (UnreachableBlockId ubid) cond ids = do (vc, stmts, top) <- exprToVar cond let ty = getVarType vc let labels = [ (mkIntLit ty ix, blockIdToLlvm b) | (ix, b) <- switchTargetsCases ids ] - -- out of range is undefined, so let's just branch to first label let defLbl | Just l <- switchTargetsDefault ids = blockIdToLlvm l - | otherwise = snd (head labels) + | otherwise = blockIdToLlvm ubid + -- switch to an unreachable basic block for exhaustive + -- switches. See Note [Unreachable block as default destination + -- in Switch] let s1 = Switch vc defLbl labels return $ (stmts `snocOL` s1, top) +-- Note [Unreachable block as default destination in Switch] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- LLVM IR requires a default destination (a block label) for its Switch +-- operation, even if the switch is exhaustive. An LLVM switch is considered +-- exhausitve (e.g. to omit range checks for bit tests [1]) if the default +-- destination is unreachable. +-- +-- When we codegen a Cmm function, we always reserve an unreachable basic block +-- that is used as a default destination for exhaustive Cmm switches in +-- genSwitch. See #24717 +-- +-- [1] https://reviews.llvm.org/D68131 + + + -- ----------------------------------------------------------------------------- -- * CmmExpr code generation -- ===================================== compiler/GHC/Parser/Annotation.hs ===================================== @@ -1244,7 +1244,7 @@ transferAnnsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') -- | Transfer comments from the annotations in the -- first 'SrcSpanAnnA' argument to those in the second. -transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA) +transferCommentsOnlyA :: EpAnn a -> EpAnn b -> (EpAnn a, EpAnn b) transferCommentsOnlyA (EpAnn a an cs) (EpAnn a' an' cs') = (EpAnn a an emptyComments, EpAnn a' an' (cs <> cs')) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1220,19 +1220,23 @@ checkLPat e@(L l _) = checkPat l e [] [] checkPat :: SrcSpanAnnA -> LocatedA (PatBuilder GhcPs) -> [HsConPatTyArg GhcPs] -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args - | isRdrDataCon c = return . L loc $ ConPat - { pat_con_ext = noAnn -- AZ: where should this come from? - , pat_con = L ln c - , pat_args = PrefixCon tyargs args - } + | isRdrDataCon c = do + let (_l', loc') = transferCommentsOnlyA l loc + return . L loc' $ ConPat + { pat_con_ext = noAnn -- AZ: where should this come from? + , pat_con = L ln c + , pat_args = PrefixCon tyargs args + } | (not (null args) && patIsRec c) = do ctx <- askParseContext patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx -checkPat loc (L _ (PatBuilderAppType f at t)) tyargs args = - checkPat loc f (HsConPatTyArg at t : tyargs) args -checkPat loc (L _ (PatBuilderApp f e)) [] args = do - p <- checkLPat e - checkPat loc f [] (p : args) +checkPat loc (L _ (PatBuilderAppType (L lf f) at t)) tyargs args = do + let (loc', lf') = transferCommentsOnlyA loc lf + checkPat loc' (L lf' f) (HsConPatTyArg at t : tyargs) args +checkPat loc (L _ (PatBuilderApp f (L le e))) [] args = do + let (loc', le') = transferCommentsOnlyA loc le + p <- checkLPat (L le' e) + checkPat loc' f [] (p : args) checkPat loc (L l e) [] [] = do p <- checkAPat loc e return (L l p) @@ -1432,20 +1436,27 @@ isFunLhs e = go e [] [] [] where mk = fmap ArgPatBuilderVisPat - go (L _ (PatBuilderVar (L loc f))) es ops cps - | not (isRdrDataCon f) = return (Just (L loc f, Prefix, es, (reverse ops) ++ cps)) - go (L _ (PatBuilderApp f e)) es ops cps = go f (mk e:es) ops cps - go (L l (PatBuilderPar _ e _)) es@(_:_) ops cps = go e es (o:ops) (c:cps) + go (L l (PatBuilderVar (L loc f))) es ops cps + | not (isRdrDataCon f) = do + let (_l, loc') = transferCommentsOnlyA l loc + return (Just (L loc' f, Prefix, es, (reverse ops) ++ cps)) + go (L l (PatBuilderApp (L lf f) e)) es ops cps = do + let (_l, lf') = transferCommentsOnlyA l lf + go (L lf' f) (mk e:es) ops cps + go (L l (PatBuilderPar _ (L le e) _)) es@(_:_) ops cps = go (L le' e) es (o:ops) (c:cps) -- NB: es@(_:_) means that there must be an arg after the parens for the -- LHS to be a function LHS. This corresponds to the Haskell Report's definition -- of funlhs. where + (_l, le') = transferCommentsOnlyA l le (o,c) = mkParensEpAnn (realSrcSpan $ locA l) - go (L loc (PatBuilderOpApp l (L loc' op) r anns)) es ops cps + go (L loc (PatBuilderOpApp (L ll l) (L loc' op) r anns)) es ops cps | not (isRdrDataCon op) -- We have found the function! - = return (Just (L loc' op, Infix, (mk l:mk r:es), (anns ++ reverse ops ++ cps))) + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; return (Just (L loc' op, Infix, (mk (L ll' l):mk r:es), (anns ++ reverse ops ++ cps))) } | otherwise -- Infix data con; keep going - = do { mb_l <- go l es ops cps + = do { let (_l, ll') = transferCommentsOnlyA loc ll + ; mb_l <- go (L ll' l) es ops cps ; return (reassociate =<< mb_l) } where reassociate (op', Infix, j : L k_loc (ArgPatBuilderVisPat k) : es', anns') @@ -1454,12 +1465,13 @@ isFunLhs e = go e [] [] [] op_app = mk $ L loc (PatBuilderOpApp (L k_loc k) (L loc' op) r (reverse ops ++ cps)) reassociate _other = Nothing - go (L _ (PatBuilderAppType pat tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps - = go pat (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps + go (L l (PatBuilderAppType (L lp pat) tok ty_pat@(HsTP _ (L (EpAnn anc ann cs) _)))) es ops cps + = go (L lp' pat) (L (EpAnn anc' ann cs) (ArgPatBuilderArgPat invis_pat) : es) ops cps where invis_pat = InvisPat tok ty_pat anc' = case tok of NoEpTok -> anc EpTok l -> widenAnchor anc [AddEpAnn AnnAnyclass l] + (_l, lp') = transferCommentsOnlyA l lp go _ _ _ _ = return Nothing data ArgPatBuilder p ===================================== config.guess ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-05-25' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +910,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +972,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1068,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1191,7 +1232,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1373,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1554,6 +1595,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? ===================================== config.sub ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1190,7 +1191,7 @@ case $cpu-$vendor in | arc | arceb | arc32 | arc64 \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ - | asmjs | javascript \ + | asmjs \ | ba \ | be32 | be64 \ | bfin | bpf | bs2000 \ @@ -1199,50 +1200,29 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64eb | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r3 | mipsisa32r3el \ - | mipsisa32r5 | mipsisa32r5el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r3 | mipsisa64r3el \ - | mipsisa64r5 | mipsisa64r5el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ + | nanomips* \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ @@ -1274,6 +1254,7 @@ case $cpu-$vendor in | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ + | vc4 \ | visium \ | w65 \ | wasm32 | wasm64 \ @@ -1285,7 +1266,7 @@ case $cpu-$vendor in ;; *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1287,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1323,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1492,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; esac ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; *) # No normalization, but not necessarily accepted, that comes below. ;; @@ -1528,12 +1520,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1538,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1588,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; - mips*-*) - os=elf + mips*-*|nanomips*-*) + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1614,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1696,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,14 +1719,11 @@ esac fi -# Now, validate our (potentially fixed-up) OS. -case $os in - # GHC specific: added for JS backend support - js | ghcjs) - ;; +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - # Sometimes we do "kernel-abi", so those need to count as OSes. - musl* | newlib* | relibc* | uclibc*) +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) ;; # Likewise for "kernel-abi" eabi* | gnueabi*) @@ -1724,6 +1731,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. @@ -1732,7 +1742,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1741,11 +1751,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1758,49 +1768,116 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; none) ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1883,7 +1960,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: ===================================== docs/users_guide/bugs.rst ===================================== @@ -445,15 +445,15 @@ In ``Prelude`` support ``Read``\ ing integers GHC's implementation of the ``Read`` class for integral types - accepts hexadecimal and octal literals (the code in the Haskell 98 + accepts hexadecimal, octal and binary literals (the code in the Haskell 98 report doesn't). So, for example, :: read "0xf00" :: Int works in GHC. - A possible reason for this is that ``readLitChar`` accepts hex and - octal escapes, so it seems inconsistent not to do so for integers + This is to maintain consistency with the language's syntax. Haskell98 + accepts hexadecimal and octal formats, and GHC2021 accepts binary formats too. ``isAlpha`` ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -218,6 +218,9 @@ compileHsObjectAndHi rs objpath = do ctxPath <- contextPath ctx (src, deps) <- lookupDependencies (ctxPath -/- ".dependencies") objpath need (src:deps) + -- The .conf file is needed when template-haskell is implicitly added as a dependency + -- when a module in the template-haskell package is compiled. (See #24737) + when (isLibrary (C.package ctx)) (need . (:[]) =<< pkgConfFile ctx) -- The .dependencies file lists indicating inputs. ghc will -- generally read more *.hi and *.hi-boot files (direct inputs). ===================================== libraries/base/changelog.md ===================================== @@ -3,6 +3,7 @@ ## 4.21.0.0 *TBA* * Add the `MonadFix` instance for `(,) a`, similar to the one for `Writer a` ([CLC proposal #238](https://github.com/haskell/core-libraries-committee/issues/238)) * Improve `toInteger :: Word32 -> Integer` on 64-bit platforms ([CLC proposal #259](https://github.com/haskell/core-libraries-committee/issues/259)) + * Make `read` accept binary integer notation ([CLC proposal #177](https://github.com/haskell/core-libraries-committee/issues/177)) ## 4.20.0.0 *TBA* * Deprecate `GHC.Pack` ([#21461](https://gitlab.haskell.org/ghc/ghc/-/issues/21461)) ===================================== libraries/base/tests/char001.hs ===================================== @@ -1,7 +1,8 @@ -- !!! Testing the behaviour of Char.lexLitChar a little.. --- [March 2003] We now allow \X and \O as escapes although the --- spec only permits \x and \o. Seems more consistent. +-- [March 2003] We now allow \X and \O as escapes although the +-- spec only permits \x and \o. Seems more consistent. +-- [January 2024] Binary character literals, something like '\b100' are not permitted. module Main where @@ -33,9 +34,15 @@ octs = do lex' "'\\o14b'" lex' "'\\0a4bg'" +-- Binaries are NOT supported. '\b' stands for backspace. +bins = do + lex' "'\\b'" + lex' "'\\b00'" + main = do hexes octs + bins ===================================== libraries/base/tests/char001.stdout ===================================== @@ -16,3 +16,5 @@ lex '\O000024' = [("'\\O000024'","")] lex '\024b' = [] lex '\o14b' = [] lex '\0a4bg' = [] +lex '\b' = [("'\\b'","")] +lex '\b00' = [] ===================================== libraries/base/tests/lex001.hs ===================================== @@ -27,7 +27,23 @@ testStrings "035e-3x", "35e+3y", "83.3e-22", - "083.3e-22" + "083.3e-22", + + "0b001", + "0b100", + "0b110", + "0B001", + "0B100", + "0B110", + + "78_91", + "678_346", + "0x23d_fa4", + "0X23d_fa4", + "0o01_253", + "0O304_367", + "0b0101_0110", + "0B11_010_0110" ] main = mapM test testStrings ===================================== libraries/base/tests/lex001.stdout ===================================== @@ -82,3 +82,58 @@ [("083.3e-22","")] [(Number (MkDecimal [0,8,3] (Just [3]) (Just (-22))),"")] +"0b001" +[("0b001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0b100" +[("0b100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0b110" +[("0b110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"0B001" +[("0B001","")] +[(Number (MkNumber 2 [0,0,1]),"")] + +"0B100" +[("0B100","")] +[(Number (MkNumber 2 [1,0,0]),"")] + +"0B110" +[("0B110","")] +[(Number (MkNumber 2 [1,1,0]),"")] + +"78_91" +[("78","_91")] +[(Number (MkDecimal [7,8] Nothing Nothing),"_91")] + +"678_346" +[("678","_346")] +[(Number (MkDecimal [6,7,8] Nothing Nothing),"_346")] + +"0x23d_fa4" +[("0x23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0X23d_fa4" +[("0X23d","_fa4")] +[(Number (MkNumber 16 [2,3,13]),"_fa4")] + +"0o01_253" +[("0o01","_253")] +[(Number (MkNumber 8 [0,1]),"_253")] + +"0O304_367" +[("0O304","_367")] +[(Number (MkNumber 8 [3,0,4]),"_367")] + +"0b0101_0110" +[("0b0101","_0110")] +[(Number (MkNumber 2 [0,1,0,1]),"_0110")] + +"0B11_010_0110" +[("0B11","_010_0110")] +[(Number (MkNumber 2 [1,1]),"_010_0110")] ===================================== libraries/ghc-internal/src/GHC/Internal/Text/Read/Lex.hs ===================================== @@ -300,6 +300,17 @@ lexCharE = n <- lexInteger base guard (n <= toInteger (ord maxBound)) return (chr (fromInteger n)) + where + -- Slightly different variant of lexBaseChar that denies binary format. + -- Binary formats are not allowed for character/string literal. + lexBaseChar = do + c <- get + case c of + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexCntrlChar = do _ <- char '^' @@ -415,27 +426,28 @@ type Digits = [Int] lexNumber :: ReadP Lexeme lexNumber - = lexHexOct <++ -- First try for hex or octal 0x, 0o etc + = lexHexOctBin <++ -- First try for hex, octal or binary 0x, 0o, 0b etc -- If that fails, try for a decimal number lexDecNumber -- Start with ordinary digits -lexHexOct :: ReadP Lexeme -lexHexOct +lexHexOctBin :: ReadP Lexeme +lexHexOctBin = do _ <- char '0' base <- lexBaseChar digits <- lexDigits base return (Number (MkNumber base digits)) - -lexBaseChar :: ReadP Int --- Lex a single character indicating the base; fail if not there -lexBaseChar = do - c <- get - case c of - 'o' -> return 8 - 'O' -> return 8 - 'x' -> return 16 - 'X' -> return 16 - _ -> pfail + where + -- Lex a single character indicating the base; fail if not there + lexBaseChar = do + c <- get + case c of + 'b' -> return 2 + 'B' -> return 2 + 'o' -> return 8 + 'O' -> return 8 + 'x' -> return 16 + 'X' -> return 16 + _ -> pfail lexDecNumber :: ReadP Lexeme lexDecNumber = ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/STM.c ===================================== @@ -31,10 +31,8 @@ * interface. In the Haskell RTS this means it is suitable only for * non-THREADED_RTS builds. * - * STM_CG_LOCK uses coarse-grained locking -- a single 'stm lock' is acquired - * during an invocation on the STM interface. Note that this does not mean that - * transactions are simply serialized -- the lock is only held *within* the - * implementation of stmCommitTransaction, stmWait etc. + * STM_CG_LOCK was a historic locking mode using coarse-grained locking + * It has been removed, look at the git history if you are interest in it. * * STM_FG_LOCKS uses fine-grained locking -- locking is done on a per-TVar basis * and, when committing a transaction, no locks are acquired for TVars that have @@ -42,19 +40,14 @@ * * Concurrency control is implemented in the functions: * - * lock_stm - * unlock_stm * lock_tvar / cond_lock_tvar * unlock_tvar * - * The choice between STM_UNIPROC / STM_CG_LOCK / STM_FG_LOCKS affects the + * The choice between STM_UNIPROC / STM_FG_LOCKS affects the * implementation of these functions. * - * lock_stm & unlock_stm are straightforward : they acquire a simple spin-lock - * using STM_CG_LOCK, and otherwise they are no-ops. - * * lock_tvar / cond_lock_tvar and unlock_tvar are more complex because they have - * other effects (present in STM_UNIPROC and STM_CG_LOCK builds) as well as the + * other effects (present in STM_UNIPROC builds) as well as the * actual business of manipulating a lock (present only in STM_FG_LOCKS builds). * This is because locking a TVar is implemented by writing the lock holder's * TRec into the TVar's current_value field: @@ -167,7 +160,6 @@ static int shake(void) { /*......................................................................*/ #define IF_STM_UNIPROC(__X) do { } while (0) -#define IF_STM_CG_LOCK(__X) do { } while (0) #define IF_STM_FG_LOCKS(__X) do { } while (0) #if defined(STM_UNIPROC) @@ -175,14 +167,6 @@ static int shake(void) { #define IF_STM_UNIPROC(__X) do { __X } while (0) static const StgBool config_use_read_phase = false; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgTRecHeader *trec STG_UNUSED, StgTVar *s STG_UNUSED) { @@ -210,64 +194,9 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgTVar *s STG_UNUSED, StgClosure *expected) { StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); - return (result == expected); -} -#endif - -#if defined(STM_CG_LOCK) /*........................................*/ - -#undef IF_STM_CG_LOCK -#define IF_STM_CG_LOCK(__X) do { __X } while (0) -static const StgBool config_use_read_phase = false; -static volatile StgTRecHeader *smp_locked = NULL; - -static void lock_stm(StgTRecHeader *trec) { - while (cas(&smp_locked, NULL, trec) != NULL) { } - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); - ASSERT(smp_locked == trec); - RELEASE_STORE(&smp_locked, 0); -} - -static StgClosure *lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED) { - StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); - ASSERT(smp_locked == trec); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); result = ACQUIRE_LOAD(&s->current_value); - return result; -} - -static void *unlock_tvar(Capability *cap, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s, - StgClosure *c, - StgBool force_update) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); - ASSERT(smp_locked == trec); - if (force_update) { - StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); - RELEASE_STORE(&s->current_value, c); - dirty_TVAR(cap, s, old_value); - } -} - -static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED, - StgClosure *expected) { - StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - ASSERT(smp_locked == trec); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %d", result ? "success" : "failure"); + // TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); return (result == expected); } #endif @@ -278,19 +207,11 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, #define IF_STM_FG_LOCKS(__X) do { __X } while (0) static const StgBool config_use_read_phase = true; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap, StgTRecHeader *trec, StgTVar *s STG_UNUSED) { StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); + // TRACE("%p : lock_tvar(%p)", trec, s); do { const StgInfoTable *info; do { @@ -313,7 +234,7 @@ static void unlock_tvar(Capability *cap, StgTVar *s, StgClosure *c, StgBool force_update STG_UNUSED) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); + // TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, (StgClosure *) trec); @@ -325,14 +246,14 @@ static StgBool cond_lock_tvar(Capability *cap, StgClosure *expected) { StgClosure *result; StgWord w; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); w = cas((void *)&(s -> current_value), (StgWord)expected, (StgWord)trec); result = (StgClosure *)w; IF_NONMOVING_WRITE_BARRIER_ENABLED { if (result) updateRemembSetPushClosure(cap, expected); } - TRACE("%p : %s", trec, result ? "success" : "failure"); + // TRACE("%p : %s", trec, result ? "success" : "failure"); return (result == expected); } #endif @@ -438,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -760,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -778,6 +739,8 @@ static StgBool validate_and_acquire_ownership (Capability *cap, int acquire_all, int retain_ownership) { StgBool result; + TRACE("cap %d, trec %p : validate_and_acquire_ownership, all: %d, retrain: %d", + cap->no, trec, acquire_all, retain_ownership); if (shake()) { TRACE("%p : shake, pretending trec is invalid when it may not be", trec); @@ -828,6 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -878,12 +842,10 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { /************************************************************************/ void stmPreGCHook (Capability *cap) { - lock_stm(NO_TREC); TRACE("stmPreGCHook"); cap->free_tvar_watch_queues = END_STM_WATCH_QUEUE; cap->free_trec_chunks = END_STM_CHUNK_LIST; cap->free_trec_headers = NO_TREC; - unlock_stm(NO_TREC); } /************************************************************************/ @@ -959,8 +921,6 @@ void stmAbortTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; if (et == NO_TREC) { // We're a top-level transaction: remove any watch queue entries that @@ -984,8 +944,6 @@ void stmAbortTransaction(Capability *cap, } trec -> state = TREC_ABORTED; - unlock_stm(trec); - TRACE("%p : stmAbortTransaction done", trec); } @@ -1013,35 +971,210 @@ void stmCondemnTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); if (trec -> state == TREC_WAITING) { ASSERT(trec -> enclosing_trec == NO_TREC); TRACE("%p : stmCondemnTransaction condemning waiting transaction", trec); remove_watch_queue_entries_for_trec(cap, trec); } trec -> state = TREC_CONDEMNED; - unlock_stm(trec); TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +To "validate" a transaction means to check that the transaction's log (Trec) is +consistent with the current state of memory; specifically, that any variable +observed (through reads AND writes) by the transaction has the same value in +memory as it did when the transaction read it. + +In some situations we can give ourself some leeway by allowing: +* False positives - The validation check claims the memory state is consistent when it isn't. +* False negatives - The validation check claims memory state is inconsistent when it + is in fact consistent. + +We validate a STM transaction for two purposes: + +(A) Post-run validation runs /after/ the transaction has completed, either during + commit or after an exception has occurred. + + This is done by validate_and_acquire_ownership. The commit process + /absolutely must/ be transactional: that is, it must read a consistent + snapshot of memory, compare with the log, and then atomically commit all the + writes in the log. We do this by locking the TVars. + + For post-run validation we must *never* allow false-positives for correctness + reasons. But we allow for false-negatives, trading occasional spurious retries + for performance in the average case. + + The implementation of performing this update atomically is mostly based on + the 2002 paper "A Practical Multi-Word Compare-and-Swap Operation" + +(B) In-flight validation runs /during/ the execution of the transaction. Suppose a transaction + is long-running, and memory has /already/ changed so that it is inconsistent with the + transaction's log. It is just conceivable that memory might change back again to be + consistent, but very unlikely. It is better to terminate and retry the transaction, + rather than let it run potentially forever as a zombie, and only retry when it attempts to commit. + + This is done by validate_trec_optimistic. Since in-flight validation at most results in early + termination of a transaction we may accept both + * a "false negative" (causing the transaction to retry unnecessarily), and + * a "false positive" (allowing the transaction to continue as a zombie). + + We want to run in-flight validation somewhat frequently to detect invalid + transactions early. We perform in-flight validation whenever a thread returns to + the scheduler, a convenient and regular opportunity. + +Note that in-flight validation is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +As noted above, post-run validation and commit /must/ be transactional, involving expensive locking. +But in-flight validation can accept false positives and false negatives. While we could lock TVars +during in-flight validation to rule out false positives, we don't have to: +it is much cheaper and very nearly as good simply to read them without locking allowing for +false-postive results. + +Moreover, locking during in-flight validation can cause lack of progress, or livelock (#24446) +through false-negative results. Suppose we have two long-running transactions, each doing successive +in-flight validation using locking. If the validation discovers a locked TVar it aborts and retries. +Now they can each abort the other, forever. +This *can* also happen with post-run validation. But since post-run validation occurs less +frequently it's incredibly unlikely to happen repeatedly compared to in-flight validation. + +Hence: locking during in-flight validation is + * Expensive + * Can lead to livelock-like conditions. + +Conclusion: + * don't use locking during in-flight validation. + * Use locking during post-run validation, where the risk of livelock is comparatively small + compared to the cost of ruling out live-lock completely. + +See below for other design alternatives. + +Design considerations about locking during in flight validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All else being equal we would always want to get a precise result for validation. +And indeed for the non-threaded runtime this is reasonably easy to achieve +(see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult, and ruling out false negatives/positives +would come at significant cost in the average case. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we use for post-run validation. +The trade off being that it can lead to false negatives during validation when multiple +threads perform validation in parallel. As long as the false-negative rate is +is reasonably low this is not problematic. + +However in-flight validation can happen multiple times per transaction. +So even a fairly low rate of spurious validation failures will result in a large +performance hit. In the worst case preventing progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve in-flight validation perf by allowing false positives. +This removes the need for tacking locks which means: + +Benefits +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. +The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. So we accept this behaviour. + +Design alternatives to improve in-flight false-postive rate: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + +A1: +Take locks for in-flight validation but don't fail if in-flight validation +encounters already locked tvars. +This would solve lock contention/false positives caused by concurrent in-flight validations. + +But it would still result in in-flight validation causing some false-negatives +during post-run validation by holding locks post-run validation is trying to take. + +It also doesn't *guaranteed* that we recognize looping transaction as invalid. +As the relevant tvars might be locked by other validations when we try to lock +them. So while this would improve over using regular lock tacking for in-flight +transactions it seems straight up worse than not taking locks to me in most +situations. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +locked tvars we encountered, as these are the only sources of false-positives. +This would give a hard upper bound on the number of false-positives while keeping +the impact on post-run validations lower. + +If the looping transaction issue turns out to be a real problem this might be worth +doing. + +A3: +When locking a tvar for a potential update keep the old value accessible. Then +in-flight validations should never return false-positives. However compared to A2 +this seems like it would come with a non-trivial overhead relative to the likelyhood +of these false-positives causing actual issues. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - t = trec; StgBool result = true; while (t != NO_TREC) { - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -1049,12 +1182,9 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { trec -> state = TREC_CONDEMNED; } - unlock_stm(trec); - TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { @@ -1087,8 +1217,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitTransaction()", trec); ASSERT(trec != NO_TREC); - lock_stm(trec); - ASSERT(trec -> enclosing_trec == NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); @@ -1112,6 +1240,7 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { max_concurrent_commits = ((max_commits_at_end - max_commits_at_start) + (getNumCapabilities() * TOKEN_BATCH_SIZE)); if (((max_concurrent_commits >> 32) > 0) || shake()) { + TRACE("STM - Max commit number exceeded"); result = false; } } @@ -1145,8 +1274,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitTransaction()=%d", trec, result); @@ -1162,8 +1289,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitNestedTransaction() into %p", trec, trec -> enclosing_trec); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; bool result = validate_and_acquire_ownership(cap, trec, (!config_use_read_phase), true); if (result) { @@ -1196,8 +1321,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitNestedTransaction()=%d", trec, result); @@ -1214,7 +1337,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); if (result) { // The transaction is valid so far so we can actually start waiting. @@ -1237,7 +1359,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { // TRec. } else { - unlock_stm(trec); free_stg_trec_header(cap, trec); } @@ -1249,7 +1370,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { void stmWaitUnlock(Capability *cap, StgTRecHeader *trec) { revert_ownership(cap, trec, true); - unlock_stm(trec); } /*......................................................................*/ @@ -1263,7 +1383,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { ASSERT((trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); TRACE("%p : validation %s", trec, result ? "succeeded" : "failed"); if (result) { @@ -1280,7 +1399,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { } free_stg_trec_header(cap, trec); } - unlock_stm(trec); TRACE("%p : stmReWait()=%d", trec, result); return result; ===================================== rts/STM.h ===================================== @@ -6,24 +6,21 @@ * *---------------------------------------------------------------------- - STM.h defines the C-level interface to the STM. + STM.h defines the C-level interface to the STM. The design follows that of the PPoPP 2005 paper "Composable memory transactions" extended to include fine-grained locking of TVars. Three different implementations can be built. In overview: - + STM_UNIPROC -- no locking at all: not safe for concurrent invocations - - STM_CG_LOCK -- coarse-grained locking : a single mutex protects all - TVars - + STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at most one TRec at any time. This allows dynamically non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- - extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + extra versioning information is retained in the + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -72,7 +69,7 @@ void stmAbortTransaction(Capability *cap, StgTRecHeader *trec); void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec); /* - * Ensure that a subsequent commit / validation will fail. We use this + * Ensure that a subsequent commit / validation will fail. We use this * in our current handling of transactions that may have become invalid * and started looping. We strip their stack back to the ATOMICALLY_FRAME, * and, when the thread is next scheduled, discover it to be invalid and @@ -87,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -106,14 +110,14 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); These four operations return boolean results which should be interpreted as follows: - true => The transaction record was definitely valid + true => The transaction record was definitely valid false => The transaction record may not have been valid Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be - nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + nested are themselves valid. Callers can check this with + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in @@ -151,7 +155,7 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec); * Test whether the current transaction context is valid and, if so, * start the thread waiting for updates to any of the tvars it has * ready from and mark it as blocked. It is an error to call stmWait - * if the thread is already waiting. + * if the thread is already waiting. */ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec); @@ -180,7 +184,7 @@ StgBool stmReWait(Capability *cap, StgTSO *tso); */ StgClosure *stmReadTVar(Capability *cap, - StgTRecHeader *trec, + StgTRecHeader *trec, StgTVar *tvar); /* Update the logical contents of 'tvar' within the context of the @@ -189,7 +193,7 @@ StgClosure *stmReadTVar(Capability *cap, void stmWriteTVar(Capability *cap, StgTRecHeader *trec, - StgTVar *tvar, + StgTVar *tvar, StgClosure *new_value); /*----------------------------------------------------------------------*/ ===================================== rts/Schedule.c ===================================== @@ -1106,7 +1106,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/tests/printer/Makefile ===================================== @@ -831,3 +831,8 @@ PprLetIn: CaseAltComments: $(CHECK_PPR) $(LIBDIR) CaseAltComments.hs $(CHECK_EXACT) $(LIBDIR) CaseAltComments.hs + +.PHONY: MatchPatComments +MatchPatComments: + $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs + $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs ===================================== testsuite/tests/printer/MatchPatComments.hs ===================================== @@ -0,0 +1,16 @@ +module MatchPatComments where + +expandProcess + outCHAs -- c0 + locationDescr = + blah + +next + ( steps -- c1 + , ys -- c2 + ) x -- c3 + = (steps, x, ys) + +makeProjection + Function{funMutual = VV, -- c4 + funAbstr = ConcreteDef} = undefined ===================================== testsuite/tests/printer/all.T ===================================== @@ -199,3 +199,4 @@ test('AnnotationNoListTuplePuns', [ignore_stderr, req_ppr_deps], makefile_test, test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) +test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,5 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [req_target_smp], compile_and_run, ['-threaded -with-rtsopts "-N2"']) ===================================== utils/check-exact/Main.hs ===================================== @@ -128,7 +128,7 @@ _tt = testOneFile changers "/home/alanz/mysrc/git.haskell.org/ghc/_build/stage1/ -- "../../testsuite/tests/printer/Ppr034.hs" Nothing -- "../../testsuite/tests/printer/Ppr035.hs" Nothing -- "../../testsuite/tests/printer/Ppr036.hs" Nothing - "../../testsuite/tests/printer/Ppr037.hs" Nothing + "../../testsuite/tests/printer/MatchPatComments.hs" Nothing -- "../../testsuite/tests/printer/Ppr038.hs" Nothing -- "../../testsuite/tests/printer/Ppr039.hs" Nothing -- "../../testsuite/tests/printer/Ppr040.hs" Nothing ===================================== utils/vagrant/bootstrap-deb.sh deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -apt-get update -apt-get build-dep -y ghc ===================================== utils/vagrant/bootstrap-rhel.sh deleted ===================================== @@ -1,4 +0,0 @@ -#!/bin/sh -yum update -y -yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool \ - gcc make python ghc git View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53327d1e7d829cc1bd911f9beccdb3ebd11e3fe9...eec83538359e59c03d73edbaaa287140fb40959a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53327d1e7d829cc1bd911f9beccdb3ebd11e3fe9...eec83538359e59c03d73edbaaa287140fb40959a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 12:46:57 2024 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 30 Apr 2024 08:46:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/debug-symbols Message-ID: <6630e841321cd_2091051708b8759ed@gitlab.mail> Zubin pushed new branch wip/debug-symbols at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/debug-symbols You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 13:10:01 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 09:10:01 -0400 Subject: [Git][ghc/ghc][wip/T23109] Make newtype classes pretend to be injective Message-ID: <6630eda96c82c_209105445f2079539@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC Commits: 6ae47cf0 by Simon Peyton Jones at 2024-04-30T14:08:29+01:00 Make newtype classes pretend to be injective - - - - - 2 changed files: - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/TyCon.hs Changes: ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -52,7 +52,7 @@ import GHC.Core import GHC.Core.FVs import GHC.Core.Utils import GHC.Core.DataCon -import GHC.Core.TyCon ( TyCon, tyConArity ) +import GHC.Core.TyCon ( TyCon, tyConArity, isInjectiveTyCon ) import GHC.Core.TyCon.RecWalk ( initRecTc, checkRecTc ) import GHC.Core.Predicate ( isDictTy, isEvVar, isCallStackPredTy, isCallStackTy ) import GHC.Core.Multiplicity @@ -3091,6 +3091,7 @@ push_data_con to_tc to_tc_arg_tys dc dc_args co role = assertPpr (eqType from_ty dc_app_ty) dump_doc $ assertPpr (equalLength val_args arg_tys) dump_doc $ assertPpr (role == coercionRole co) dump_doc $ + assertPpr (isInjectiveTyCon to_tc role) dump_doc $ (dc, to_tc_arg_tys, to_ex_args ++ new_val_args) where Pair from_ty to_ty = coercionKind co ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2053,8 +2053,9 @@ isInjectiveTyCon (TyCon { tyConDetails = details }) role go_alg_rep (SumTyCon {}) _ = True go_alg_rep (DataTyCon {}) _ = True go_alg_rep (AbstractTyCon {}) _ = False --- Not sure why we need this --- go_alg_rep (NewTyCon {}) (ClassTyCon {}) = True -- See Note [Newtype classes] + go_alg_rep (NewTyCon {}) (ClassTyCon {}) = True -- See Note [Newtype classes] + -- ToDo: Lint and pushDataCon both check for injective TyCons in SelCo + -- So newtype classes need to pretend to be injective. go_alg_rep (NewTyCon {}) _ = False {- Note [Newtype classes] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ae47cf0696b9a4bc6ecfee77676758edfaec5dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ae47cf0696b9a4bc6ecfee77676758edfaec5dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 14:18:53 2024 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Tue, 30 Apr 2024 10:18:53 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] 3 commits: testsuite: make req_target_smp skip the test Message-ID: <6630fdccd5f65_2d9bfc7d3a5c125628@gitlab.mail> Cheng Shao pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: 1cad009e by Cheng Shao at 2024-04-30T14:18:27+00:00 testsuite: make req_target_smp skip the test - - - - - 677a4ff9 by Andreas Klebinger at 2024-04-30T14:18:28+00:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - cfaa788d by Andreas Klebinger at 2024-04-30T14:18:28+00:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 9 changed files: - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - testsuite/driver/testlib.py - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T Changes: ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/STM.c ===================================== @@ -31,10 +31,8 @@ * interface. In the Haskell RTS this means it is suitable only for * non-THREADED_RTS builds. * - * STM_CG_LOCK uses coarse-grained locking -- a single 'stm lock' is acquired - * during an invocation on the STM interface. Note that this does not mean that - * transactions are simply serialized -- the lock is only held *within* the - * implementation of stmCommitTransaction, stmWait etc. + * STM_CG_LOCK was a historic locking mode using coarse-grained locking + * It has been removed, look at the git history if you are interest in it. * * STM_FG_LOCKS uses fine-grained locking -- locking is done on a per-TVar basis * and, when committing a transaction, no locks are acquired for TVars that have @@ -42,19 +40,14 @@ * * Concurrency control is implemented in the functions: * - * lock_stm - * unlock_stm * lock_tvar / cond_lock_tvar * unlock_tvar * - * The choice between STM_UNIPROC / STM_CG_LOCK / STM_FG_LOCKS affects the + * The choice between STM_UNIPROC / STM_FG_LOCKS affects the * implementation of these functions. * - * lock_stm & unlock_stm are straightforward : they acquire a simple spin-lock - * using STM_CG_LOCK, and otherwise they are no-ops. - * * lock_tvar / cond_lock_tvar and unlock_tvar are more complex because they have - * other effects (present in STM_UNIPROC and STM_CG_LOCK builds) as well as the + * other effects (present in STM_UNIPROC builds) as well as the * actual business of manipulating a lock (present only in STM_FG_LOCKS builds). * This is because locking a TVar is implemented by writing the lock holder's * TRec into the TVar's current_value field: @@ -167,7 +160,6 @@ static int shake(void) { /*......................................................................*/ #define IF_STM_UNIPROC(__X) do { } while (0) -#define IF_STM_CG_LOCK(__X) do { } while (0) #define IF_STM_FG_LOCKS(__X) do { } while (0) #if defined(STM_UNIPROC) @@ -175,14 +167,6 @@ static int shake(void) { #define IF_STM_UNIPROC(__X) do { __X } while (0) static const StgBool config_use_read_phase = false; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgTRecHeader *trec STG_UNUSED, StgTVar *s STG_UNUSED) { @@ -210,64 +194,9 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgTVar *s STG_UNUSED, StgClosure *expected) { StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); - return (result == expected); -} -#endif - -#if defined(STM_CG_LOCK) /*........................................*/ - -#undef IF_STM_CG_LOCK -#define IF_STM_CG_LOCK(__X) do { __X } while (0) -static const StgBool config_use_read_phase = false; -static volatile StgTRecHeader *smp_locked = NULL; - -static void lock_stm(StgTRecHeader *trec) { - while (cas(&smp_locked, NULL, trec) != NULL) { } - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); - ASSERT(smp_locked == trec); - RELEASE_STORE(&smp_locked, 0); -} - -static StgClosure *lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED) { - StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); - ASSERT(smp_locked == trec); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); result = ACQUIRE_LOAD(&s->current_value); - return result; -} - -static void *unlock_tvar(Capability *cap, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s, - StgClosure *c, - StgBool force_update) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); - ASSERT(smp_locked == trec); - if (force_update) { - StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); - RELEASE_STORE(&s->current_value, c); - dirty_TVAR(cap, s, old_value); - } -} - -static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED, - StgClosure *expected) { - StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - ASSERT(smp_locked == trec); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %d", result ? "success" : "failure"); + // TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); return (result == expected); } #endif @@ -278,19 +207,11 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, #define IF_STM_FG_LOCKS(__X) do { __X } while (0) static const StgBool config_use_read_phase = true; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap, StgTRecHeader *trec, StgTVar *s STG_UNUSED) { StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); + // TRACE("%p : lock_tvar(%p)", trec, s); do { const StgInfoTable *info; do { @@ -313,7 +234,7 @@ static void unlock_tvar(Capability *cap, StgTVar *s, StgClosure *c, StgBool force_update STG_UNUSED) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); + // TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, (StgClosure *) trec); @@ -325,14 +246,14 @@ static StgBool cond_lock_tvar(Capability *cap, StgClosure *expected) { StgClosure *result; StgWord w; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); w = cas((void *)&(s -> current_value), (StgWord)expected, (StgWord)trec); result = (StgClosure *)w; IF_NONMOVING_WRITE_BARRIER_ENABLED { if (result) updateRemembSetPushClosure(cap, expected); } - TRACE("%p : %s", trec, result ? "success" : "failure"); + // TRACE("%p : %s", trec, result ? "success" : "failure"); return (result == expected); } #endif @@ -438,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -760,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -778,6 +739,8 @@ static StgBool validate_and_acquire_ownership (Capability *cap, int acquire_all, int retain_ownership) { StgBool result; + TRACE("cap %d, trec %p : validate_and_acquire_ownership, all: %d, retrain: %d", + cap->no, trec, acquire_all, retain_ownership); if (shake()) { TRACE("%p : shake, pretending trec is invalid when it may not be", trec); @@ -828,6 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -878,12 +842,10 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { /************************************************************************/ void stmPreGCHook (Capability *cap) { - lock_stm(NO_TREC); TRACE("stmPreGCHook"); cap->free_tvar_watch_queues = END_STM_WATCH_QUEUE; cap->free_trec_chunks = END_STM_CHUNK_LIST; cap->free_trec_headers = NO_TREC; - unlock_stm(NO_TREC); } /************************************************************************/ @@ -959,8 +921,6 @@ void stmAbortTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; if (et == NO_TREC) { // We're a top-level transaction: remove any watch queue entries that @@ -984,8 +944,6 @@ void stmAbortTransaction(Capability *cap, } trec -> state = TREC_ABORTED; - unlock_stm(trec); - TRACE("%p : stmAbortTransaction done", trec); } @@ -1013,35 +971,210 @@ void stmCondemnTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); if (trec -> state == TREC_WAITING) { ASSERT(trec -> enclosing_trec == NO_TREC); TRACE("%p : stmCondemnTransaction condemning waiting transaction", trec); remove_watch_queue_entries_for_trec(cap, trec); } trec -> state = TREC_CONDEMNED; - unlock_stm(trec); TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +To "validate" a transaction means to check that the transaction's log (Trec) is +consistent with the current state of memory; specifically, that any variable +observed (through reads AND writes) by the transaction has the same value in +memory as it did when the transaction read it. + +In some situations we can give ourself some leeway by allowing: +* False positives - The validation check claims the memory state is consistent when it isn't. +* False negatives - The validation check claims memory state is inconsistent when it + is in fact consistent. + +We validate a STM transaction for two purposes: + +(A) Post-run validation runs /after/ the transaction has completed, either during + commit or after an exception has occurred. + + This is done by validate_and_acquire_ownership. The commit process + /absolutely must/ be transactional: that is, it must read a consistent + snapshot of memory, compare with the log, and then atomically commit all the + writes in the log. We do this by locking the TVars. + + For post-run validation we must *never* allow false-positives for correctness + reasons. But we allow for false-negatives, trading occasional spurious retries + for performance in the average case. + + The implementation of performing this update atomically is mostly based on + the 2002 paper "A Practical Multi-Word Compare-and-Swap Operation" + +(B) In-flight validation runs /during/ the execution of the transaction. Suppose a transaction + is long-running, and memory has /already/ changed so that it is inconsistent with the + transaction's log. It is just conceivable that memory might change back again to be + consistent, but very unlikely. It is better to terminate and retry the transaction, + rather than let it run potentially forever as a zombie, and only retry when it attempts to commit. + + This is done by validate_trec_optimistic. Since in-flight validation at most results in early + termination of a transaction we may accept both + * a "false negative" (causing the transaction to retry unnecessarily), and + * a "false positive" (allowing the transaction to continue as a zombie). + + We want to run in-flight validation somewhat frequently to detect invalid + transactions early. We perform in-flight validation whenever a thread returns to + the scheduler, a convenient and regular opportunity. + +Note that in-flight validation is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +As noted above, post-run validation and commit /must/ be transactional, involving expensive locking. +But in-flight validation can accept false positives and false negatives. While we could lock TVars +during in-flight validation to rule out false positives, we don't have to: +it is much cheaper and very nearly as good simply to read them without locking allowing for +false-postive results. + +Moreover, locking during in-flight validation can cause lack of progress, or livelock (#24446) +through false-negative results. Suppose we have two long-running transactions, each doing successive +in-flight validation using locking. If the validation discovers a locked TVar it aborts and retries. +Now they can each abort the other, forever. +This *can* also happen with post-run validation. But since post-run validation occurs less +frequently it's incredibly unlikely to happen repeatedly compared to in-flight validation. + +Hence: locking during in-flight validation is + * Expensive + * Can lead to livelock-like conditions. + +Conclusion: + * don't use locking during in-flight validation. + * Use locking during post-run validation, where the risk of livelock is comparatively small + compared to the cost of ruling out live-lock completely. + +See below for other design alternatives. + +Design considerations about locking during in flight validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All else being equal we would always want to get a precise result for validation. +And indeed for the non-threaded runtime this is reasonably easy to achieve +(see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult, and ruling out false negatives/positives +would come at significant cost in the average case. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we use for post-run validation. +The trade off being that it can lead to false negatives during validation when multiple +threads perform validation in parallel. As long as the false-negative rate is +is reasonably low this is not problematic. + +However in-flight validation can happen multiple times per transaction. +So even a fairly low rate of spurious validation failures will result in a large +performance hit. In the worst case preventing progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve in-flight validation perf by allowing false positives. +This removes the need for tacking locks which means: + +Benefits +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. +The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. So we accept this behaviour. + +Design alternatives to improve in-flight false-postive rate: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + +A1: +Take locks for in-flight validation but don't fail if in-flight validation +encounters already locked tvars. +This would solve lock contention/false positives caused by concurrent in-flight validations. + +But it would still result in in-flight validation causing some false-negatives +during post-run validation by holding locks post-run validation is trying to take. + +It also doesn't *guaranteed* that we recognize looping transaction as invalid. +As the relevant tvars might be locked by other validations when we try to lock +them. So while this would improve over using regular lock tacking for in-flight +transactions it seems straight up worse than not taking locks to me in most +situations. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +locked tvars we encountered, as these are the only sources of false-positives. +This would give a hard upper bound on the number of false-positives while keeping +the impact on post-run validations lower. + +If the looping transaction issue turns out to be a real problem this might be worth +doing. + +A3: +When locking a tvar for a potential update keep the old value accessible. Then +in-flight validations should never return false-positives. However compared to A2 +this seems like it would come with a non-trivial overhead relative to the likelyhood +of these false-positives causing actual issues. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - t = trec; StgBool result = true; while (t != NO_TREC) { - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -1049,12 +1182,9 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { trec -> state = TREC_CONDEMNED; } - unlock_stm(trec); - TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { @@ -1087,8 +1217,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitTransaction()", trec); ASSERT(trec != NO_TREC); - lock_stm(trec); - ASSERT(trec -> enclosing_trec == NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); @@ -1112,6 +1240,7 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { max_concurrent_commits = ((max_commits_at_end - max_commits_at_start) + (getNumCapabilities() * TOKEN_BATCH_SIZE)); if (((max_concurrent_commits >> 32) > 0) || shake()) { + TRACE("STM - Max commit number exceeded"); result = false; } } @@ -1145,8 +1274,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitTransaction()=%d", trec, result); @@ -1162,8 +1289,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitNestedTransaction() into %p", trec, trec -> enclosing_trec); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; bool result = validate_and_acquire_ownership(cap, trec, (!config_use_read_phase), true); if (result) { @@ -1196,8 +1321,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitNestedTransaction()=%d", trec, result); @@ -1214,7 +1337,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); if (result) { // The transaction is valid so far so we can actually start waiting. @@ -1237,7 +1359,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { // TRec. } else { - unlock_stm(trec); free_stg_trec_header(cap, trec); } @@ -1249,7 +1370,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { void stmWaitUnlock(Capability *cap, StgTRecHeader *trec) { revert_ownership(cap, trec, true); - unlock_stm(trec); } /*......................................................................*/ @@ -1263,7 +1383,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { ASSERT((trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); TRACE("%p : validation %s", trec, result ? "succeeded" : "failed"); if (result) { @@ -1280,7 +1399,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { } free_stg_trec_header(cap, trec); } - unlock_stm(trec); TRACE("%p : stmReWait()=%d", trec, result); return result; ===================================== rts/STM.h ===================================== @@ -6,24 +6,21 @@ * *---------------------------------------------------------------------- - STM.h defines the C-level interface to the STM. + STM.h defines the C-level interface to the STM. The design follows that of the PPoPP 2005 paper "Composable memory transactions" extended to include fine-grained locking of TVars. Three different implementations can be built. In overview: - + STM_UNIPROC -- no locking at all: not safe for concurrent invocations - - STM_CG_LOCK -- coarse-grained locking : a single mutex protects all - TVars - + STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at most one TRec at any time. This allows dynamically non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- - extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + extra versioning information is retained in the + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -72,7 +69,7 @@ void stmAbortTransaction(Capability *cap, StgTRecHeader *trec); void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec); /* - * Ensure that a subsequent commit / validation will fail. We use this + * Ensure that a subsequent commit / validation will fail. We use this * in our current handling of transactions that may have become invalid * and started looping. We strip their stack back to the ATOMICALLY_FRAME, * and, when the thread is next scheduled, discover it to be invalid and @@ -87,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -106,14 +110,14 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); These four operations return boolean results which should be interpreted as follows: - true => The transaction record was definitely valid + true => The transaction record was definitely valid false => The transaction record may not have been valid Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be - nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + nested are themselves valid. Callers can check this with + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in @@ -151,7 +155,7 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec); * Test whether the current transaction context is valid and, if so, * start the thread waiting for updates to any of the tvars it has * ready from and mark it as blocked. It is an error to call stmWait - * if the thread is already waiting. + * if the thread is already waiting. */ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec); @@ -180,7 +184,7 @@ StgBool stmReWait(Capability *cap, StgTSO *tso); */ StgClosure *stmReadTVar(Capability *cap, - StgTRecHeader *trec, + StgTRecHeader *trec, StgTVar *tvar); /* Update the logical contents of 'tvar' within the context of the @@ -189,7 +193,7 @@ StgClosure *stmReadTVar(Capability *cap, void stmWriteTVar(Capability *cap, StgTRecHeader *trec, - StgTVar *tvar, + StgTVar *tvar, StgClosure *new_value); /*----------------------------------------------------------------------*/ ===================================== rts/Schedule.c ===================================== @@ -1106,7 +1106,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/driver/testlib.py ===================================== @@ -328,11 +328,11 @@ def req_ghc_smp( name, opts ): def req_target_smp( name, opts ): """ Mark a test as requiring smp when run on the target. If the target does - not support smp, then mark the test as an expected fail. Use this when the + not support smp, then skip the test. Use this when the test needs to run with smp support. """ if not config.target_has_smp: - opts.expect = 'fail' + opts.skip = True def req_ghc_with_threaded_rts( name, opts ): if not config.ghc_with_threaded_rts: ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,5 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [req_target_smp], compile_and_run, ['-threaded -with-rtsopts "-N2"']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eec83538359e59c03d73edbaaa287140fb40959a...cfaa788d5e80bce348e814a9c1b821372f7a908c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eec83538359e59c03d73edbaaa287140fb40959a...cfaa788d5e80bce348e814a9c1b821372f7a908c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 14:48:29 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 10:48:29 -0400 Subject: [Git][ghc/ghc][wip/T24676] 18 commits: Refactor the Binary serialisation interface Message-ID: <663104bd3096a_2d9bfcdd31281518d@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC Commits: fa03b1fb by Fendor at 2024-04-26T18:03:13-04:00 Refactor the Binary serialisation interface The goal is simplifiy adding deduplication tables to `ModIface` interface serialisation. We identify two main points of interest that make this difficult: 1. UserData hardcodes what `Binary` instances can have deduplication tables. Moreover, it heavily uses partial functions. 2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and 'FastString', making it difficult to add more deduplication. Instead of having a single `UserData` record with fields for all the types that can have deduplication tables, we allow to provide custom serialisers for any `Typeable`. These are wrapped in existentials and stored in a `Map` indexed by their respective `TypeRep`. The `Binary` instance of the type to deduplicate still needs to explicitly look up the decoder via `findUserDataReader` and `findUserDataWriter`, which is no worse than the status-quo. `Map` was chosen as microbenchmarks indicate it is the fastest for a small number of keys (< 10). To generalise the deduplication table serialisation mechanism, we introduce the types `ReaderTable` and `WriterTable` which provide a simple interface that is sufficient to implement a general purpose deduplication mechanism for `writeBinIface` and `readBinIface`. This allows us to provide a list of deduplication tables for serialisation that can be extended more easily, for example for `IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for more motivation. In addition to this refactoring, we split `UserData` into `ReaderUserData` and `WriterUserData`, to avoid partial functions and reduce overall memory usage, as we need fewer mutable variables. Bump haddock submodule to accomodate for `UserData` split. ------------------------- Metric Increase: MultiLayerModulesTH_Make MultiLayerModulesRecomp T21839c ------------------------- - - - - - bac57298 by Fendor at 2024-04-26T18:03:13-04:00 Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle` A `BinHandle` contains too much information for reading data. For example, it needs to keep a `FastMutInt` and a `IORef BinData`, when the non-mutable variants would suffice. Additionally, this change has the benefit that anyone can immediately tell whether the `BinHandle` is used for reading or writing. Bump haddock submodule BinHandle split. - - - - - 4d6394dd by Simon Peyton Jones at 2024-04-26T18:03:49-04:00 Fix missing escaping-kind check in tcPatSynSig Note [Escaping kind in type signatures] explains how we deal with escaping kinds in type signatures, e.g. f :: forall r (a :: TYPE r). a where the kind of the body is (TYPE r), but `r` is not in scope outside the forall-type. I had missed this subtlety in tcPatSynSig, leading to #24686. This MR fixes it; and a similar bug in tc_top_lhs_type. (The latter is tested by T24686a.) - - - - - 981c2c2c by Alan Zimmerman at 2024-04-26T18:04:25-04:00 EPA: check-exact: check that the roundtrip reproduces the source Closes #24670 - - - - - a8616747 by Andrew Lelechenko at 2024-04-26T18:05:01-04:00 Document that setEnv is not thread-safe - - - - - 1e41de83 by Bryan Richter at 2024-04-26T18:05:37-04:00 CI: Work around frequent Signal 9 errors - - - - - a6d5f9da by Naïm Favier at 2024-04-27T17:52:40-04:00 ghc-internal: add MonadFix instance for (,) Closes https://gitlab.haskell.org/ghc/ghc/-/issues/24288, implements CLC proposal https://github.com/haskell/core-libraries-committee/issues/238. Adds a MonadFix instance for tuples, permitting value recursion in the "native" writer monad and bringing consistency with the existing instance for transformers's WriterT (and, to a lesser extent, for Solo). - - - - - 64feadcd by Rodrigo Mesquita at 2024-04-27T17:53:16-04:00 bindist: Fix xattr cleaning The original fix (725343aa) was incorrect because it used the shell bracket syntax which is the quoting syntax in autoconf, making the test for existence be incorrect and therefore `xattr` was never run. Fixes #24554 - - - - - e2094df3 by damhiya at 2024-04-28T23:52:00+09:00 Make read accepts binary integer formats CLC proposal : https://github.com/haskell/core-libraries-committee/issues/177 - - - - - 1c2fd963 by Alan Zimmerman at 2024-04-29T23:17:00-04:00 EPA: Preserve comments in Match Pats Closes #24708 Closes #24715 Closes #24734 - - - - - 4189d17e by Sylvain Henry at 2024-04-29T23:17:42-04:00 LLVM: better unreachable default destination in Switch (#24717) See added note. Co-authored-by: Siddharth Bhat <siddu.druid at gmail.com> - - - - - a3725c88 by Cheng Shao at 2024-04-29T23:18:20-04:00 ci: enable wasm jobs for MRs with wasm label This patch enables wasm jobs for MRs with wasm label. Previously the wasm label didn't actually have any effect on the CI pipeline, and full-ci needed to be applied to run wasm jobs which was a waste of runners when working on the wasm backend, hence the fix here. - - - - - 702f7964 by Matthew Pickering at 2024-04-29T23:18:56-04:00 Make interface files and object files depend on inplace .conf file A potential fix for #24737 - - - - - 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 78cdaaae by Simon Peyton Jones at 2024-04-30T15:47:50+01:00 Fix a QuickLook bug This MR fixes the bug exposed by #24676. The problem was that quickLookArg was trying to avoid calling tcInstFun unnecessarily; but it was in fact necessary. But that in turn forced me into a significant refactoring, putting more fields into EValArgQL. I added a lot of new material to Note [Quick Look at value arguments] It is a bit more subtle than I would like, but the overall plan is rather clearer now than it was. - - - - - 5f69ac07 by Simon Peyton Jones at 2024-04-30T15:47:50+01:00 More responses to Richard's review - - - - - 29 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Fields.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Recomp/Binary.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/FieldLabel.hs - compiler/GHC/Types/Name.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ac999ca4e4ecda1bd6e8077ccfff4fdbca50b0b5...5f69ac0796979ad04ef536b7e8de0643f2cc1dc7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ac999ca4e4ecda1bd6e8077ccfff4fdbca50b0b5...5f69ac0796979ad04ef536b7e8de0643f2cc1dc7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 15:35:11 2024 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 30 Apr 2024 11:35:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: utils: remove obsolete vagrant scripts Message-ID: <66310faf76594_2d9bfc16683241957ac@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - da1c1a0a by Zubin Duggal at 2024-04-30T11:34:55-04:00 testsuite: Handle exceptions in framework_fail when testdir is not initialised When `framework_fail` is called before initialising testdir, it would fail with an exception reporting the testdir not being initialised instead of the actual failure. Ensure we report the actual reason for the failure instead of failing in this way. One way this can manifest is when trying to run a test that doesn't exist using `--only` - - - - - c79e9693 by Alan Zimmerman at 2024-04-30T11:34:56-04:00 EPA: Fix range for GADT decl with sig only Closes #24714 - - - - - 10 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/Parser.y - config.guess - config.sub - testsuite/driver/testlib.py - + testsuite/tests/printer/DataDeclShort.hs - testsuite/tests/printer/Makefile - testsuite/tests/printer/all.T - − utils/vagrant/bootstrap-deb.sh - − utils/vagrant/bootstrap-rhel.sh Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res ===================================== compiler/GHC/Parser.y ===================================== @@ -1303,7 +1303,7 @@ ty_decl :: { LTyClDecl GhcPs } | type_data_or_newtype capi_ctype tycl_hdr opt_kind_sig gadt_constrlist maybe_derivings - {% mkTyData (comb4 $1 $3 $5 $6) (sndOf3 $ unLoc $1) (thdOf3 $ unLoc $1) $2 $3 + {% mkTyData (comb5 $1 $3 $4 $5 $6) (sndOf3 $ unLoc $1) (thdOf3 $ unLoc $1) $2 $3 (snd $ unLoc $4) (snd $ unLoc $5) (fmap reverse $6) ((fstOf3 $ unLoc $1)++(fst $ unLoc $4)++(fst $ unLoc $5)) } ===================================== config.guess ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-05-25' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +910,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +972,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1068,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1191,7 +1232,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1373,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1554,6 +1595,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? ===================================== config.sub ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1190,7 +1191,7 @@ case $cpu-$vendor in | arc | arceb | arc32 | arc64 \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ - | asmjs | javascript \ + | asmjs \ | ba \ | be32 | be64 \ | bfin | bpf | bs2000 \ @@ -1199,50 +1200,29 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64eb | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r3 | mipsisa32r3el \ - | mipsisa32r5 | mipsisa32r5el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r3 | mipsisa64r3el \ - | mipsisa64r5 | mipsisa64r5el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ + | nanomips* \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ @@ -1274,6 +1254,7 @@ case $cpu-$vendor in | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ + | vc4 \ | visium \ | w65 \ | wasm32 | wasm64 \ @@ -1285,7 +1266,7 @@ case $cpu-$vendor in ;; *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1287,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1323,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1492,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; esac ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; *) # No normalization, but not necessarily accepted, that comes below. ;; @@ -1528,12 +1520,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1538,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1588,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; - mips*-*) - os=elf + mips*-*|nanomips*-*) + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1614,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1696,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,14 +1719,11 @@ esac fi -# Now, validate our (potentially fixed-up) OS. -case $os in - # GHC specific: added for JS backend support - js | ghcjs) - ;; +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - # Sometimes we do "kernel-abi", so those need to count as OSes. - musl* | newlib* | relibc* | uclibc*) +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) ;; # Likewise for "kernel-abi" eabi* | gnueabi*) @@ -1724,6 +1731,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. @@ -1732,7 +1742,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1741,11 +1751,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1758,49 +1768,116 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; none) ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1883,7 +1960,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: ===================================== testsuite/driver/testlib.py ===================================== @@ -1542,7 +1542,13 @@ def override_options(pre_cmd): def framework_fail(name: Optional[TestName], way: Optional[WayName], reason: str) -> None: opts = getTestOpts() - directory = re.sub(r'^\.[/\\]', '', str(opts.testdir)) + # framework_fail can be called before testdir is initialised, + # so we need to take care not to blow up with the wrong way + # and report the actual reason for the failure. + try: + directory = re.sub(r'^\.[/\\]', '', str(opts.testdir)) + except: + directory = '' full_name = '%s(%s)' % (name, way) if_verbose(1, '*** framework failure for %s %s ' % (full_name, reason)) name2 = name if name is not None else TestName('none') ===================================== testsuite/tests/printer/DataDeclShort.hs ===================================== @@ -0,0 +1,8 @@ +module DataDeclShort where + +data GenericOptions + :: fieldLabelModifier + -> tagSingleConstructors + -> Type + +x = 1 ===================================== testsuite/tests/printer/Makefile ===================================== @@ -836,3 +836,8 @@ CaseAltComments: MatchPatComments: $(CHECK_PPR) $(LIBDIR) MatchPatComments.hs $(CHECK_EXACT) $(LIBDIR) MatchPatComments.hs + +.PHONY: DataDeclShort +DataDeclShort: + $(CHECK_PPR) $(LIBDIR) DataDeclShort.hs + $(CHECK_EXACT) $(LIBDIR) DataDeclShort.hs ===================================== testsuite/tests/printer/all.T ===================================== @@ -200,3 +200,4 @@ test('Test24533', [ignore_stderr, req_ppr_deps], makefile_test, ['Test24533']) test('PprLetIn', [ignore_stderr, req_ppr_deps], makefile_test, ['PprLetIn']) test('CaseAltComments', [ignore_stderr, req_ppr_deps], makefile_test, ['CaseAltComments']) test('MatchPatComments', [ignore_stderr, req_ppr_deps], makefile_test, ['MatchPatComments']) +test('DataDeclShort', [ignore_stderr, req_ppr_deps], makefile_test, ['DataDeclShort']) ===================================== utils/vagrant/bootstrap-deb.sh deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -apt-get update -apt-get build-dep -y ghc ===================================== utils/vagrant/bootstrap-rhel.sh deleted ===================================== @@ -1,4 +0,0 @@ -#!/bin/sh -yum update -y -yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool \ - gcc make python ghc git View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ef9a788561644ee458075c200c0d45a57c68ef6...c79e96939225583820318f4d91afe32682e2feee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ef9a788561644ee458075c200c0d45a57c68ef6...c79e96939225583820318f4d91afe32682e2feee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 16:33:53 2024 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Tue, 30 Apr 2024 12:33:53 -0400 Subject: [Git][ghc/ghc][wip/andreask/stm] 3 commits: testsuite: fix req_target_smp predicate Message-ID: <66311d7158aa1_2d9bfc1f2500c2140a9@gitlab.mail> Cheng Shao pushed to branch wip/andreask/stm at Glasgow Haskell Compiler / GHC Commits: 39e33a81 by Cheng Shao at 2024-04-30T16:33:08+00:00 testsuite: fix req_target_smp predicate - - - - - 0512df04 by Andreas Klebinger at 2024-04-30T16:33:28+00:00 STM: Remove (unused)coarse grained locking. The STM code had a coarse grained locking mode guarded by #defines that was unused. This commit removes the code. - - - - - 9b954aa3 by Andreas Klebinger at 2024-04-30T16:33:28+00:00 STM: Be more optimistic when validating in-flight transactions. * Don't lock tvars when performing non-committal validation. * If we encounter a locked tvar don't consider it a failure. This means in-flight validation will only fail if committing at the moment of validation is *guaranteed* to fail. This prevents in-flight validation from failing spuriously if it happens in parallel on multiple threads or parallel to thread comitting. - - - - - 13 changed files: - hadrian/src/Settings/Builders/RunTest.hs - rts/Exception.cmm - rts/STM.c - rts/STM.h - rts/Schedule.c - rts/include/stg/SMP.h - testsuite/config/ghc - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/mk/test.mk - + testsuite/tests/rts/T24142.hs - + testsuite/tests/rts/T24142.stdout - testsuite/tests/rts/all.T Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -282,7 +282,7 @@ runTestBuilderArgs = builder Testsuite ? do , arg "-e", arg $ asBool "ghc_with_dynamic_rts=" (hasDynamicRts) , arg "-e", arg $ asBool "config.ghc_with_threaded_rts=" (hasThreadedRts) , arg "-e", arg $ asBool "config.have_fast_bignum=" (bignumBackend /= "native" && not bignumCheck) - , arg "-e", arg $ asBool "target_with_smp=" targetWithSMP + , arg "-e", arg $ asBool "config.target_has_smp=" targetWithSMP , arg "-e", arg $ "config.ghc_dynamic=" ++ show hasDynamic , arg "-e", arg $ "config.leading_underscore=" ++ show leadingUnderscore ===================================== rts/Exception.cmm ===================================== @@ -495,7 +495,7 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr"); + (r) = ccall stmValidateNestOfTransactions(MyCapability() "ptr", trec "ptr", 0); outer = StgTRecHeader_enclosing_trec(trec); ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr"); ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); ===================================== rts/STM.c ===================================== @@ -31,10 +31,8 @@ * interface. In the Haskell RTS this means it is suitable only for * non-THREADED_RTS builds. * - * STM_CG_LOCK uses coarse-grained locking -- a single 'stm lock' is acquired - * during an invocation on the STM interface. Note that this does not mean that - * transactions are simply serialized -- the lock is only held *within* the - * implementation of stmCommitTransaction, stmWait etc. + * STM_CG_LOCK was a historic locking mode using coarse-grained locking + * It has been removed, look at the git history if you are interest in it. * * STM_FG_LOCKS uses fine-grained locking -- locking is done on a per-TVar basis * and, when committing a transaction, no locks are acquired for TVars that have @@ -42,19 +40,14 @@ * * Concurrency control is implemented in the functions: * - * lock_stm - * unlock_stm * lock_tvar / cond_lock_tvar * unlock_tvar * - * The choice between STM_UNIPROC / STM_CG_LOCK / STM_FG_LOCKS affects the + * The choice between STM_UNIPROC / STM_FG_LOCKS affects the * implementation of these functions. * - * lock_stm & unlock_stm are straightforward : they acquire a simple spin-lock - * using STM_CG_LOCK, and otherwise they are no-ops. - * * lock_tvar / cond_lock_tvar and unlock_tvar are more complex because they have - * other effects (present in STM_UNIPROC and STM_CG_LOCK builds) as well as the + * other effects (present in STM_UNIPROC builds) as well as the * actual business of manipulating a lock (present only in STM_FG_LOCKS builds). * This is because locking a TVar is implemented by writing the lock holder's * TRec into the TVar's current_value field: @@ -167,7 +160,6 @@ static int shake(void) { /*......................................................................*/ #define IF_STM_UNIPROC(__X) do { } while (0) -#define IF_STM_CG_LOCK(__X) do { } while (0) #define IF_STM_FG_LOCKS(__X) do { } while (0) #if defined(STM_UNIPROC) @@ -175,14 +167,6 @@ static int shake(void) { #define IF_STM_UNIPROC(__X) do { __X } while (0) static const StgBool config_use_read_phase = false; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgTRecHeader *trec STG_UNUSED, StgTVar *s STG_UNUSED) { @@ -210,64 +194,9 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgTVar *s STG_UNUSED, StgClosure *expected) { StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); - return (result == expected); -} -#endif - -#if defined(STM_CG_LOCK) /*........................................*/ - -#undef IF_STM_CG_LOCK -#define IF_STM_CG_LOCK(__X) do { __X } while (0) -static const StgBool config_use_read_phase = false; -static volatile StgTRecHeader *smp_locked = NULL; - -static void lock_stm(StgTRecHeader *trec) { - while (cas(&smp_locked, NULL, trec) != NULL) { } - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); - ASSERT(smp_locked == trec); - RELEASE_STORE(&smp_locked, 0); -} - -static StgClosure *lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED) { - StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); - ASSERT(smp_locked == trec); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); result = ACQUIRE_LOAD(&s->current_value); - return result; -} - -static void *unlock_tvar(Capability *cap, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s, - StgClosure *c, - StgBool force_update) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); - ASSERT(smp_locked == trec); - if (force_update) { - StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); - RELEASE_STORE(&s->current_value, c); - dirty_TVAR(cap, s, old_value); - } -} - -static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, - StgTRecHeader *trec STG_UNUSED, - StgTVar *s STG_UNUSED, - StgClosure *expected) { - StgClosure *result; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - ASSERT(smp_locked == trec); - result = ACQUIRE_LOAD(&s->current_value); - TRACE("%p : %d", result ? "success" : "failure"); + // TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); return (result == expected); } #endif @@ -278,19 +207,11 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, #define IF_STM_FG_LOCKS(__X) do { __X } while (0) static const StgBool config_use_read_phase = true; -static void lock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : lock_stm()", trec); -} - -static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { - TRACE("%p : unlock_stm()", trec); -} - static StgClosure *lock_tvar(Capability *cap, StgTRecHeader *trec, StgTVar *s STG_UNUSED) { StgClosure *result; - TRACE("%p : lock_tvar(%p)", trec, s); + // TRACE("%p : lock_tvar(%p)", trec, s); do { const StgInfoTable *info; do { @@ -313,7 +234,7 @@ static void unlock_tvar(Capability *cap, StgTVar *s, StgClosure *c, StgBool force_update STG_UNUSED) { - TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); + // TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, (StgClosure *) trec); @@ -325,14 +246,14 @@ static StgBool cond_lock_tvar(Capability *cap, StgClosure *expected) { StgClosure *result; StgWord w; - TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); + // TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); w = cas((void *)&(s -> current_value), (StgWord)expected, (StgWord)trec); result = (StgClosure *)w; IF_NONMOVING_WRITE_BARRIER_ENABLED { if (result) updateRemembSetPushClosure(cap, expected); } - TRACE("%p : %s", trec, result ? "success" : "failure"); + // TRACE("%p : %s", trec, result ? "success" : "failure"); return (result == expected); } #endif @@ -438,6 +359,8 @@ static StgTRecHeader *new_stg_trec_header(Capability *cap, // Allocation / deallocation functions that retain per-capability lists // of closures that can be re-used +//TODO: I think some of these lack write barriers required by the non-moving gc. + static StgTVarWatchQueue *alloc_stg_tvar_watch_queue(Capability *cap, StgClosure *closure) { StgTVarWatchQueue *result = NULL; @@ -760,6 +683,44 @@ static void revert_ownership(Capability *cap STG_UNUSED, /*......................................................................*/ +// validate_optimistic() +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec); + +StgBool validate_trec_optimistic (Capability *cap, StgTRecHeader *trec) { + StgBool result; + TRACE("cap %d, trec %p : validate_trec_optimistic", + cap->no, trec); + + if (shake()) { + TRACE("%p : shake, pretending trec is invalid when it may not be", trec); + return false; + } + + ASSERT((trec -> state == TREC_ACTIVE) || + (trec -> state == TREC_WAITING) || + (trec -> state == TREC_CONDEMNED)); + result = !((trec -> state) == TREC_CONDEMNED); + if (result) { + FOR_EACH_ENTRY(trec, e, { + StgTVar *s; + s = e -> tvar; + StgClosure *current = RELAXED_LOAD(&s->current_value); + if(current != e->expected_value && + //If the trec is locked we optimistically assume our trec will still be valid after it's unlocked. + (GET_INFO(UNTAG_CLOSURE(current)) != &stg_TREC_HEADER_info)) + { TRACE("%p : failed optimistic validate %p", trec, s); + result = false; + BREAK_FOR_EACH; + } + }); + } + + + TRACE("%p : validate_trec_optimistic, result: %d", trec, result); + return result; +} + + // validate_and_acquire_ownership : this performs the twin functions // of checking that the TVars referred to by entries in trec hold the // expected values and: @@ -778,6 +739,8 @@ static StgBool validate_and_acquire_ownership (Capability *cap, int acquire_all, int retain_ownership) { StgBool result; + TRACE("cap %d, trec %p : validate_and_acquire_ownership, all: %d, retrain: %d", + cap->no, trec, acquire_all, retain_ownership); if (shake()) { TRACE("%p : shake, pretending trec is invalid when it may not be", trec); @@ -828,6 +791,7 @@ static StgBool validate_and_acquire_ownership (Capability *cap, revert_ownership(cap, trec, acquire_all); } + TRACE("%p : validate_and_acquire_ownership, result: %d", trec, result); return result; } @@ -878,12 +842,10 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { /************************************************************************/ void stmPreGCHook (Capability *cap) { - lock_stm(NO_TREC); TRACE("stmPreGCHook"); cap->free_tvar_watch_queues = END_STM_WATCH_QUEUE; cap->free_trec_chunks = END_STM_CHUNK_LIST; cap->free_trec_headers = NO_TREC; - unlock_stm(NO_TREC); } /************************************************************************/ @@ -959,8 +921,6 @@ void stmAbortTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; if (et == NO_TREC) { // We're a top-level transaction: remove any watch queue entries that @@ -984,8 +944,6 @@ void stmAbortTransaction(Capability *cap, } trec -> state = TREC_ABORTED; - unlock_stm(trec); - TRACE("%p : stmAbortTransaction done", trec); } @@ -1013,35 +971,210 @@ void stmCondemnTransaction(Capability *cap, (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); if (trec -> state == TREC_WAITING) { ASSERT(trec -> enclosing_trec == NO_TREC); TRACE("%p : stmCondemnTransaction condemning waiting transaction", trec); remove_watch_queue_entries_for_trec(cap, trec); } trec -> state = TREC_CONDEMNED; - unlock_stm(trec); TRACE("%p : stmCondemnTransaction done", trec); } -/*......................................................................*/ - -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { +/*...................................................................... + +Note [STM Validation] +~~~~~~~~~~~~~~~~~~~~~ +To "validate" a transaction means to check that the transaction's log (Trec) is +consistent with the current state of memory; specifically, that any variable +observed (through reads AND writes) by the transaction has the same value in +memory as it did when the transaction read it. + +In some situations we can give ourself some leeway by allowing: +* False positives - The validation check claims the memory state is consistent when it isn't. +* False negatives - The validation check claims memory state is inconsistent when it + is in fact consistent. + +We validate a STM transaction for two purposes: + +(A) Post-run validation runs /after/ the transaction has completed, either during + commit or after an exception has occurred. + + This is done by validate_and_acquire_ownership. The commit process + /absolutely must/ be transactional: that is, it must read a consistent + snapshot of memory, compare with the log, and then atomically commit all the + writes in the log. We do this by locking the TVars. + + For post-run validation we must *never* allow false-positives for correctness + reasons. But we allow for false-negatives, trading occasional spurious retries + for performance in the average case. + + The implementation of performing this update atomically is mostly based on + the 2002 paper "A Practical Multi-Word Compare-and-Swap Operation" + +(B) In-flight validation runs /during/ the execution of the transaction. Suppose a transaction + is long-running, and memory has /already/ changed so that it is inconsistent with the + transaction's log. It is just conceivable that memory might change back again to be + consistent, but very unlikely. It is better to terminate and retry the transaction, + rather than let it run potentially forever as a zombie, and only retry when it attempts to commit. + + This is done by validate_trec_optimistic. Since in-flight validation at most results in early + termination of a transaction we may accept both + * a "false negative" (causing the transaction to retry unnecessarily), and + * a "false positive" (allowing the transaction to continue as a zombie). + + We want to run in-flight validation somewhat frequently to detect invalid + transactions early. We perform in-flight validation whenever a thread returns to + the scheduler, a convenient and regular opportunity. + +Note that in-flight validation is not merely a optimization. Consider transactions +that are in an infinite loop as a result of seeing an inconsistent view of +memory, e.g. + + atomically $ do + [a,b] <- mapM readTVar [ta,tb] + -- a is never equal to b given a consistent view of memory. + when (a == b) loop + +As noted above, post-run validation and commit /must/ be transactional, involving expensive locking. +But in-flight validation can accept false positives and false negatives. While we could lock TVars +during in-flight validation to rule out false positives, we don't have to: +it is much cheaper and very nearly as good simply to read them without locking allowing for +false-postive results. + +Moreover, locking during in-flight validation can cause lack of progress, or livelock (#24446) +through false-negative results. Suppose we have two long-running transactions, each doing successive +in-flight validation using locking. If the validation discovers a locked TVar it aborts and retries. +Now they can each abort the other, forever. +This *can* also happen with post-run validation. But since post-run validation occurs less +frequently it's incredibly unlikely to happen repeatedly compared to in-flight validation. + +Hence: locking during in-flight validation is + * Expensive + * Can lead to livelock-like conditions. + +Conclusion: + * don't use locking during in-flight validation. + * Use locking during post-run validation, where the risk of livelock is comparatively small + compared to the cost of ruling out live-lock completely. + +See below for other design alternatives. + +Design considerations about locking during in flight validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All else being equal we would always want to get a precise result for validation. +And indeed for the non-threaded runtime this is reasonably easy to achieve +(see STM paper "Composable Memory Transactions"). +However for SMP things are more difficult, and ruling out false negatives/positives +would come at significant cost in the average case. + +The easiest way to avoid false positives is to lock all relevant tvars during +validation. And indeed that is what we use for post-run validation. +The trade off being that it can lead to false negatives during validation when multiple +threads perform validation in parallel. As long as the false-negative rate is +is reasonably low this is not problematic. + +However in-flight validation can happen multiple times per transaction. +So even a fairly low rate of spurious validation failures will result in a large +performance hit. In the worst case preventing progress alltogether (See #24446). + +We don't want to reduce validation frequency too much to detect invalid +transactions early. So we simply stick with the frequency "on return to scheduler" +that's described in the stm paper. + +However we can improve in-flight validation perf by allowing false positives. +This removes the need for tacking locks which means: + +Benefits +* No lock contention between post-run and in-flight validations operating on the + same tvars. This reduces the false negative rate significantly for both. +* Concurrent in-flight validations won't cause each other to fail spuriously + through lock contention. +* No cas operations for in-flight validation reduces it's overhead significantly. + +Drawbacks: +* We will sometimes fail to recognize invalid trecs as such by assuming locked + tvars contain valid values. + +Why can we simply not lock tvars for in-flight validations? Unlike with post-run +validation if we miss part of an update which would invalidate the trec it will +be either seen by a later validation (at the latest in the post-run validation +which still locks). However there is one exception: Looping transactions. + +If a transaction loops it will *only* be validated optimistically. +The only way for in-flight validation to constantly +result in false-positives is for the conflicting tvar(s) to get constantly locked +for updates by post-run validations. Which seems impossibly unlikely over a long +period of time. So we accept this behaviour. + +Design alternatives to improve in-flight false-postive rate: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +All of these primarily revolve around ways to ensure that we can recognize invalid +looping transactions. However without proof this is a real problem implementing +those seems not worthwhile. + +A1: +Take locks for in-flight validation but don't fail if in-flight validation +encounters already locked tvars. +This would solve lock contention/false positives caused by concurrent in-flight validations. + +But it would still result in in-flight validation causing some false-negatives +during post-run validation by holding locks post-run validation is trying to take. + +It also doesn't *guaranteed* that we recognize looping transaction as invalid. +As the relevant tvars might be locked by other validations when we try to lock +them. So while this would improve over using regular lock tacking for in-flight +transactions it seems straight up worse than not taking locks to me in most +situations. + +A2: +Perform occasional locking in-flight validation for long running transactions. +This would solve the theoretical looping transaction recognition issue at the +cost of some performance and complexity. This could done by adding a counter to +the trec, counting the number of validations it has endured. + +A2.1: +Like A2, but instead of counting the number of validations count the number of +locked tvars we encountered, as these are the only sources of false-positives. +This would give a hard upper bound on the number of false-positives while keeping +the impact on post-run validations lower. + +If the looping transaction issue turns out to be a real problem this might be worth +doing. + +A3: +When locking a tvar for a potential update keep the old value accessible. Then +in-flight validations should never return false-positives. However compared to A2 +this seems like it would come with a non-trivial overhead relative to the likelyhood +of these false-positives causing actual issues. + + +*/ + +// Check if a transaction is possibly invalid by this point. +// Pessimistically - Currently we use this if an exception occured inside a transaction. +// To decide weither or not to abort by checking if the transaction was valid. +// Optimistically - Currently we use this to eagerly abort invalid transactions from the scheduler. +// See Note [STM Validation] +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically) { StgTRecHeader *t; - TRACE("%p : stmValidateNestOfTransactions", trec); + TRACE("%p : stmValidateNestOfTransactions, %b", trec, optimistically); ASSERT(trec != NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - t = trec; StgBool result = true; while (t != NO_TREC) { - result &= validate_and_acquire_ownership(cap, t, true, false); + if(optimistically) { + result &= validate_trec_optimistic(cap, t); + + } else { + // TODO: I don't think there is a need to lock all tvars here. + result &= validate_and_acquire_ownership(cap, t, true, false); + } t = t -> enclosing_trec; } @@ -1049,12 +1182,9 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec) { trec -> state = TREC_CONDEMNED; } - unlock_stm(trec); - TRACE("%p : stmValidateNestOfTransactions()=%d", trec, result); return result; } - /*......................................................................*/ static TRecEntry *get_entry_for(StgTRecHeader *trec, StgTVar *tvar, StgTRecHeader **in) { @@ -1087,8 +1217,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitTransaction()", trec); ASSERT(trec != NO_TREC); - lock_stm(trec); - ASSERT(trec -> enclosing_trec == NO_TREC); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); @@ -1112,6 +1240,7 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { max_concurrent_commits = ((max_commits_at_end - max_commits_at_start) + (getNumCapabilities() * TOKEN_BATCH_SIZE)); if (((max_concurrent_commits >> 32) > 0) || shake()) { + TRACE("STM - Max commit number exceeded"); result = false; } } @@ -1145,8 +1274,6 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitTransaction()=%d", trec, result); @@ -1162,8 +1289,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { TRACE("%p : stmCommitNestedTransaction() into %p", trec, trec -> enclosing_trec); ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); - et = trec -> enclosing_trec; bool result = validate_and_acquire_ownership(cap, trec, (!config_use_read_phase), true); if (result) { @@ -1196,8 +1321,6 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { } } - unlock_stm(trec); - free_stg_trec_header(cap, trec); TRACE("%p : stmCommitNestedTransaction()=%d", trec, result); @@ -1214,7 +1337,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { ASSERT((trec -> state == TREC_ACTIVE) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); if (result) { // The transaction is valid so far so we can actually start waiting. @@ -1237,7 +1359,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { // TRec. } else { - unlock_stm(trec); free_stg_trec_header(cap, trec); } @@ -1249,7 +1370,6 @@ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec) { void stmWaitUnlock(Capability *cap, StgTRecHeader *trec) { revert_ownership(cap, trec, true); - unlock_stm(trec); } /*......................................................................*/ @@ -1263,7 +1383,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { ASSERT((trec -> state == TREC_WAITING) || (trec -> state == TREC_CONDEMNED)); - lock_stm(trec); bool result = validate_and_acquire_ownership(cap, trec, true, true); TRACE("%p : validation %s", trec, result ? "succeeded" : "failed"); if (result) { @@ -1280,7 +1399,6 @@ StgBool stmReWait(Capability *cap, StgTSO *tso) { } free_stg_trec_header(cap, trec); } - unlock_stm(trec); TRACE("%p : stmReWait()=%d", trec, result); return result; ===================================== rts/STM.h ===================================== @@ -6,24 +6,21 @@ * *---------------------------------------------------------------------- - STM.h defines the C-level interface to the STM. + STM.h defines the C-level interface to the STM. The design follows that of the PPoPP 2005 paper "Composable memory transactions" extended to include fine-grained locking of TVars. Three different implementations can be built. In overview: - + STM_UNIPROC -- no locking at all: not safe for concurrent invocations - - STM_CG_LOCK -- coarse-grained locking : a single mutex protects all - TVars - + STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at most one TRec at any time. This allows dynamically non-conflicting transactions to commit in parallel. The implementation treats reads optimistically -- - extra versioning information is retained in the - saw_update_by field of the TVars so that they do not + extra versioning information is retained in the + num_updates field of the TVars so that they do not need to be locked for reading. STM.C contains more details about the locking schemes used. @@ -72,7 +69,7 @@ void stmAbortTransaction(Capability *cap, StgTRecHeader *trec); void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec); /* - * Ensure that a subsequent commit / validation will fail. We use this + * Ensure that a subsequent commit / validation will fail. We use this * in our current handling of transactions that may have become invalid * and started looping. We strip their stack back to the ATOMICALLY_FRAME, * and, when the thread is next scheduled, discover it to be invalid and @@ -87,16 +84,23 @@ void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); Validation ---------- - Test whether the specified transaction record, and all those within which - it is nested, are still valid. + Test whether the specified transaction record, and all those within which + it is nested, are still valid. + + stmValidateNestOfTransactions - optimistically + - Can return false positives when tvars are locked. + - Faster + - Does not take any locks + + stmValidateNestOfTransactions - pessimistic + - Can return false negatives. + - Slower + - Takes locks, negatively affecting performance of other threads. + - Most importantly - no false positives! - Note: the caller can assume that once stmValidateTransaction has - returned false for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) */ -StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); +StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec, StgBool optimistically); /*---------------------------------------------------------------------- @@ -106,14 +110,14 @@ StgBool stmValidateNestOfTransactions(Capability *cap, StgTRecHeader *trec); These four operations return boolean results which should be interpreted as follows: - true => The transaction record was definitely valid + true => The transaction record was definitely valid false => The transaction record may not have been valid Note that, for nested operations, validity here is solely in terms of the specified trec: it does not say whether those that it may be - nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. + nested are themselves valid. Callers can check this with + stmValidateNestOfTransactionsPessimistic. The user of the STM should ensure that it is always safe to assume that a transaction context is not valid when in fact it is (i.e. to return false in @@ -151,7 +155,7 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec); * Test whether the current transaction context is valid and, if so, * start the thread waiting for updates to any of the tvars it has * ready from and mark it as blocked. It is an error to call stmWait - * if the thread is already waiting. + * if the thread is already waiting. */ StgBool stmWait(Capability *cap, StgTSO *tso, StgTRecHeader *trec); @@ -180,7 +184,7 @@ StgBool stmReWait(Capability *cap, StgTSO *tso); */ StgClosure *stmReadTVar(Capability *cap, - StgTRecHeader *trec, + StgTRecHeader *trec, StgTVar *tvar); /* Update the logical contents of 'tvar' within the context of the @@ -189,7 +193,7 @@ StgClosure *stmReadTVar(Capability *cap, void stmWriteTVar(Capability *cap, StgTRecHeader *trec, - StgTVar *tvar, + StgTVar *tvar, StgClosure *new_value); /*----------------------------------------------------------------------*/ ===================================== rts/Schedule.c ===================================== @@ -1106,7 +1106,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t) // and a is never equal to b given a consistent view of memory. // if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) { - if (!stmValidateNestOfTransactions(cap, t -> trec)) { + if (!stmValidateNestOfTransactions(cap, t -> trec, true)) { debugTrace(DEBUG_sched | DEBUG_stm, "trec %p found wasting its time", t); ===================================== rts/include/stg/SMP.h ===================================== @@ -201,14 +201,15 @@ EXTERN_INLINE void busy_wait_nop(void); * - StgWeak: finalizer * - StgMVar: head, tail, value * - StgMVarTSOQueue: link - * - StgTVar: current_value, first_watch_queue_entry - * - StgTVarWatchQueue: {next,prev}_queue_entry - * - StgTRecChunk: TODO * - StgMutArrPtrs: payload * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgInd: indirectee * - StgTSO: block_info + + * - StgTVar: current_value, first_watch_queue_entry + * - StgTVarWatchQueue: {next,prev}_queue_entry + * - StgTRecChunk: TODO * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent ===================================== testsuite/config/ghc ===================================== @@ -48,8 +48,7 @@ if config.have_interp: # whether the target supports smp if config.ghc_with_threaded_rts: config.run_ways.append('threaded1') - if target_with_smp: - config.target_has_smp = True + if config.target_has_smp: config.run_ways.append('threaded2') if config.speed == 0: config.run_ways.append('nonmoving_thr') ===================================== testsuite/driver/testglobals.py ===================================== @@ -154,7 +154,7 @@ class TestConfig: self.ghc_has_smp = True # Does the target have SMP support? - self.target_has_smp = True + self.target_has_smp = False # Is gdb available? self.have_gdb = False ===================================== testsuite/driver/testlib.py ===================================== @@ -328,11 +328,11 @@ def req_ghc_smp( name, opts ): def req_target_smp( name, opts ): """ Mark a test as requiring smp when run on the target. If the target does - not support smp, then mark the test as an expected fail. Use this when the + not support smp, then skip the test. Use this when the test needs to run with smp support. """ if not config.target_has_smp: - opts.expect = 'fail' + opts.skip = True def req_ghc_with_threaded_rts( name, opts ): if not config.ghc_with_threaded_rts: ===================================== testsuite/mk/test.mk ===================================== @@ -167,9 +167,9 @@ CABAL_PLUGIN_BUILD = --enable-library-vanilla --disable-shared endif ifeq "$(GhcWithSMP)" "YES" -RUNTEST_OPTS += -e target_with_smp=True +RUNTEST_OPTS += -e config.target_has_smp=True else -RUNTEST_OPTS += -e target_with_smp=False +RUNTEST_OPTS += -e config.target_has_smp=False endif ifeq "$(GhcWithRtsLinker)" "YES" ===================================== testsuite/tests/rts/T24142.hs ===================================== @@ -0,0 +1,63 @@ +{- This test constructs a program that used to trigger an excessive amount of STM retries. -} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Conc +import Control.Concurrent (newMVar, newEmptyMVar, takeMVar, putMVar) +import Control.Monad +import Control.Concurrent.STM.TArray +import Data.Array.MArray +import Data.IORef + + +main :: IO () +main = + forM_ [2..40] $ \i -> do + -- Run the test with an increasing number of tvars + let tvar_count = i * 10 + -- print $ "Tvars: " ++ show tvar_count + provokeLivelock tvar_count + + +-- Forks two threads running a STM transactions, both accessing the same tvars but in opposite order. +provokeLivelock :: Int -> IO () +provokeLivelock n = do + -- Use tvar array as a convenient way to bundle up n Tvars. + tvarArray <- atomically $ do + newListArray (0,n) [0.. fromIntegral n :: Integer] :: STM (TArray Int Integer) + m1 <- newEmptyMVar + m2 <- newEmptyMVar + updateCount <- newIORef (0 :: Int) + + let useTvars :: [Int] -> Bool -> IO () + useTvars tvar_order use_writes = atomically $ do + -- Walk the array once in the given order to add all tvars to the transaction log. + unsafeIOToSTM $ atomicModifyIORef' updateCount (\i -> (i+1,())) + mapM_ (\i -> readArray tvarArray i >>= \(!_n) -> return ()) tvar_order + + + -- Then we just enter the scheduler a lot + forM_ tvar_order $ \i -> do + -- when use_writes $ + -- readArray tvarArray i >>= \(!n) -> writeArray tvarArray i (n+1 :: Integer) + unsafeIOToSTM yield + + _ <- forkIO $ do + useTvars [0..n] False + -- print "Thread1 done." + putMVar m1 True + _ <- forkIO $ do + useTvars (reverse [0..n]) False + -- print "Thread1 done." + putMVar m2 True + -- Wait for forked threads. + _ <- takeMVar m1 + _ <- takeMVar m2 + updates <- readIORef updateCount + if updates > n + then putStrLn $ "TVars: " ++ show n ++ ", ERROR: more than " ++ show n ++ " transaction attempts. (" ++ show updates ++")\n" + else putStrLn $ "TVars: " ++ show n ++ ", OK: no more than " ++ show n ++ " transaction attempts." + + return () + ===================================== testsuite/tests/rts/T24142.stdout ===================================== @@ -0,0 +1,39 @@ +TVars: 20, OK: no more than 20 transaction attempts. +TVars: 30, OK: no more than 30 transaction attempts. +TVars: 40, OK: no more than 40 transaction attempts. +TVars: 50, OK: no more than 50 transaction attempts. +TVars: 60, OK: no more than 60 transaction attempts. +TVars: 70, OK: no more than 70 transaction attempts. +TVars: 80, OK: no more than 80 transaction attempts. +TVars: 90, OK: no more than 90 transaction attempts. +TVars: 100, OK: no more than 100 transaction attempts. +TVars: 110, OK: no more than 110 transaction attempts. +TVars: 120, OK: no more than 120 transaction attempts. +TVars: 130, OK: no more than 130 transaction attempts. +TVars: 140, OK: no more than 140 transaction attempts. +TVars: 150, OK: no more than 150 transaction attempts. +TVars: 160, OK: no more than 160 transaction attempts. +TVars: 170, OK: no more than 170 transaction attempts. +TVars: 180, OK: no more than 180 transaction attempts. +TVars: 190, OK: no more than 190 transaction attempts. +TVars: 200, OK: no more than 200 transaction attempts. +TVars: 210, OK: no more than 210 transaction attempts. +TVars: 220, OK: no more than 220 transaction attempts. +TVars: 230, OK: no more than 230 transaction attempts. +TVars: 240, OK: no more than 240 transaction attempts. +TVars: 250, OK: no more than 250 transaction attempts. +TVars: 260, OK: no more than 260 transaction attempts. +TVars: 270, OK: no more than 270 transaction attempts. +TVars: 280, OK: no more than 280 transaction attempts. +TVars: 290, OK: no more than 290 transaction attempts. +TVars: 300, OK: no more than 300 transaction attempts. +TVars: 310, OK: no more than 310 transaction attempts. +TVars: 320, OK: no more than 320 transaction attempts. +TVars: 330, OK: no more than 330 transaction attempts. +TVars: 340, OK: no more than 340 transaction attempts. +TVars: 350, OK: no more than 350 transaction attempts. +TVars: 360, OK: no more than 360 transaction attempts. +TVars: 370, OK: no more than 370 transaction attempts. +TVars: 380, OK: no more than 380 transaction attempts. +TVars: 390, OK: no more than 390 transaction attempts. +TVars: 400, OK: no more than 400 transaction attempts. ===================================== testsuite/tests/rts/all.T ===================================== @@ -609,3 +609,5 @@ test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) test('IOManager', [js_skip, when(arch('wasm32'), skip), when(opsys('mingw32'), skip), pre_cmd('$MAKE -s --no-print-directory IOManager.hs')], compile_and_run, ['']) + +test('T24142', [req_target_smp], compile_and_run, ['-threaded -with-rtsopts "-N2"']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cfaa788d5e80bce348e814a9c1b821372f7a908c...9b954aa3035627a68c9a6739dd1dca1454dd6d70 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cfaa788d5e80bce348e814a9c1b821372f7a908c...9b954aa3035627a68c9a6739dd1dca1454dd6d70 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 16:47:11 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 12:47:11 -0400 Subject: [Git][ghc/ghc][wip/T24726] 7 commits: utils: remove obsolete vagrant scripts Message-ID: <6631208f3541_2d9bfc221fa00216718@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24726 at Glasgow Haskell Compiler / GHC Commits: 728af21e by Cheng Shao at 2024-04-30T05:30:23-04:00 utils: remove obsolete vagrant scripts Vagrantfile has long been removed in !5288. This commit further removes the obsolete vagrant scripts in the tree. - - - - - 36f2c342 by Cheng Shao at 2024-04-30T05:31:00-04:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 - - - - - ecbf22a6 by Ben Gamari at 2024-04-30T05:31:36-04:00 ghcup-metadata: Drop output_name field This is entirely redundant to the filename of the URL. There is no compelling reason to name the downloaded file differently from its source. - - - - - 06d1aca2 by Simon Peyton Jones at 2024-04-30T17:46:43+01:00 Track in-scope variables in ruleCheckProgram This small patch fixes #24726, by tracking in-scope variables properly in -drule-check. Not hard to do! - - - - - 2200d296 by Simon Peyton Jones at 2024-04-30T17:46:43+01:00 Add a couple more HasCallStack constraints in SimpleOpt Just for debugging, no effect on normal code - - - - - f5e4ab53 by Simon Peyton Jones at 2024-04-30T17:46:43+01:00 Add comments to Prep.hs This documentation patch fixes a TODO left over from !12364 - - - - - db5176ae by Simon Peyton Jones at 2024-04-30T17:46:43+01:00 Use HasDebugCallStack, rather than HasCallStack - - - - - 26 changed files: - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Stg/Subst.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Utils.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Types/Origin.hs-boot - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/TcType.hs-boot - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Word64.hs - config.guess - config.sub - + testsuite/tests/simplCore/should_compile/T24726.hs - + testsuite/tests/simplCore/should_compile/T24726.stderr - testsuite/tests/simplCore/should_compile/all.T - − utils/vagrant/bootstrap-deb.sh - − utils/vagrant/bootstrap-rhel.sh Changes: ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -65,7 +65,6 @@ eprint(f"Supported platforms: {job_mapping.keys()}") class Artifact(NamedTuple): job_name: str download_name: str - output_name: str subdir: str # Platform spec provides a specification which is agnostic to Job @@ -75,11 +74,9 @@ class PlatformSpec(NamedTuple): subdir: str source_artifact = Artifact('source-tarball' - , 'ghc-{version}-src.tar.xz' , 'ghc-{version}-src.tar.xz' , 'ghc-{version}' ) test_artifact = Artifact('source-tarball' - , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}-testsuite.tar.xz' , 'ghc-{version}/testsuite' ) @@ -164,11 +161,6 @@ def mk_one_metadata(release_mode, version, job_map, artifact): , "dlSubdir": artifact.subdir.format(version=version) , "dlHash" : h } - # Only add dlOutput if it is inconsistent with the filename inferred from the URL - output = artifact.output_name.format(version=version) - if Path(urlparse(final_url).path).name != output: - res["dlOutput"] = output - eprint(res) return res ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -483,7 +483,7 @@ isOffsetImm off w -- TODO OPT: we might be able give getRegister -- a hint, what kind of register we want. -getFloatReg :: HasCallStack => CmmExpr -> NatM (Reg, Format, InstrBlock) +getFloatReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, Format, InstrBlock) getFloatReg expr = do r <- getRegister expr case r of ===================================== compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs ===================================== @@ -8,11 +8,11 @@ import GHC.Platform.Reg import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Platform import Data.Word -import GHC.Stack -- AArch64 has 32 64bit general purpose register r0..r30, and zr/sp -- AArch64 has 32 128bit floating point registers v0..v31 as part of the NEON -- extension in Armv8-A. @@ -65,7 +65,7 @@ showBits :: Word32 -> String showBits w = map (\i -> if testBit w i then '1' else '0') [0..31] -- FR instance implementation (See Linear.FreeRegs) -allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +allocateReg :: HasDebugCallStack => RealReg -> FreeRegs -> FreeRegs allocateReg (RealRegSingle r) (FreeRegs g f) | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32)) | r < 32 && testBit g r = FreeRegs (clearBit g r) f @@ -127,7 +127,7 @@ getFreeRegs cls (FreeRegs g f) initFreeRegs :: Platform -> FreeRegs initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs platform) -releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +releaseReg :: HasDebugCallStack => RealReg -> FreeRegs -> FreeRegs releaseReg (RealRegSingle r) (FreeRegs g f) | r > 31 && testBit f (r - 32) = pprPanic "Linear.AArch64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32)) | r < 32 && testBit g r = pprPanic "Linear.AArch64.releaseReg" (text "can't release non-allocated reg x" <> int r) ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -2360,7 +2360,7 @@ addWeakFVs dmd_ty weak_fvs -- L demand doesn't get both'd with the Bot coming up from the inner -- call to f. So we just get an L demand for x for g. -setBndrsDemandInfo :: HasCallStack => [Var] -> [Demand] -> [Var] +setBndrsDemandInfo :: HasDebugCallStack => [Var] -> [Demand] -> [Var] setBndrsDemandInfo (b:bs) ds | isTyVar b = b : setBndrsDemandInfo bs ds setBndrsDemandInfo (b:bs) (d:ds) = ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -47,7 +47,7 @@ import GHC.Driver.Ppr( showSDoc ) import GHC.Core -- All of it import GHC.Core.Subst import GHC.Core.SimpleOpt ( exprIsLambda_maybe ) -import GHC.Core.FVs ( exprFreeVars, exprsFreeVars, bindFreeVars +import GHC.Core.FVs ( exprFreeVars, bindFreeVars , rulesFreeVarsDSet, exprsOrphNames ) import GHC.Core.Utils ( exprType, mkTick, mkTicks , stripTicksTopT, stripTicksTopE @@ -1887,41 +1887,59 @@ ruleCheckProgram ropts phase rule_pat rules binds vcat [ p $$ line | p <- bagToList results ] ] where + line = text (replicate 20 '-') env = RuleCheckEnv { rc_is_active = isActive phase , rc_id_unf = idUnfolding -- Not quite right -- Should use activeUnfolding , rc_pattern = rule_pat , rc_rules = rules , rc_ropts = ropts - } - results = unionManyBags (map (ruleCheckBind env) binds) - line = text (replicate 20 '-') + , rc_in_scope = emptyInScopeSet } + + results = go env binds + + go _ [] = emptyBag + go env (bind:binds) = let (env', ds) = ruleCheckBind env bind + in ds `unionBags` go env' binds + +data RuleCheckEnv = RuleCheckEnv + { rc_is_active :: Activation -> Bool + , rc_id_unf :: IdUnfoldingFun + , rc_pattern :: String + , rc_rules :: Id -> [CoreRule] + , rc_ropts :: RuleOpts + , rc_in_scope :: InScopeSet } + +extendInScopeRC :: RuleCheckEnv -> Var -> RuleCheckEnv +extendInScopeRC env@(RuleCheckEnv { rc_in_scope = in_scope }) v + = env { rc_in_scope = in_scope `extendInScopeSet` v } -data RuleCheckEnv = RuleCheckEnv { - rc_is_active :: Activation -> Bool, - rc_id_unf :: IdUnfoldingFun, - rc_pattern :: String, - rc_rules :: Id -> [CoreRule], - rc_ropts :: RuleOpts -} +extendInScopeListRC :: RuleCheckEnv -> [Var] -> RuleCheckEnv +extendInScopeListRC env@(RuleCheckEnv { rc_in_scope = in_scope }) vs + = env { rc_in_scope = in_scope `extendInScopeSetList` vs } -ruleCheckBind :: RuleCheckEnv -> CoreBind -> Bag SDoc +ruleCheckBind :: RuleCheckEnv -> CoreBind -> (RuleCheckEnv, Bag SDoc) -- The Bag returned has one SDoc for each call site found -ruleCheckBind env (NonRec _ r) = ruleCheck env r -ruleCheckBind env (Rec prs) = unionManyBags [ruleCheck env r | (_,r) <- prs] +ruleCheckBind env (NonRec b r) = (env `extendInScopeRC` b, ruleCheck env r) +ruleCheckBind env (Rec prs) = (env', unionManyBags (map (ruleCheck env') rhss)) + where + (bs, rhss) = unzip prs + env' = env `extendInScopeListRC` bs ruleCheck :: RuleCheckEnv -> CoreExpr -> Bag SDoc -ruleCheck _ (Var _) = emptyBag -ruleCheck _ (Lit _) = emptyBag -ruleCheck _ (Type _) = emptyBag -ruleCheck _ (Coercion _) = emptyBag -ruleCheck env (App f a) = ruleCheckApp env (App f a) [] -ruleCheck env (Tick _ e) = ruleCheck env e -ruleCheck env (Cast e _) = ruleCheck env e -ruleCheck env (Let bd e) = ruleCheckBind env bd `unionBags` ruleCheck env e -ruleCheck env (Lam _ e) = ruleCheck env e -ruleCheck env (Case e _ _ as) = ruleCheck env e `unionBags` - unionManyBags [ruleCheck env r | Alt _ _ r <- as] +ruleCheck _ (Var _) = emptyBag +ruleCheck _ (Lit _) = emptyBag +ruleCheck _ (Type _) = emptyBag +ruleCheck _ (Coercion _) = emptyBag +ruleCheck env (App f a) = ruleCheckApp env (App f a) [] +ruleCheck env (Tick _ e) = ruleCheck env e +ruleCheck env (Cast e _) = ruleCheck env e +ruleCheck env (Let bd e) = let (env', ds) = ruleCheckBind env bd + in ds `unionBags` ruleCheck env' e +ruleCheck env (Lam b e) = ruleCheck (env `extendInScopeRC` b) e +ruleCheck env (Case e b _ as) = ruleCheck env e `unionBags` + unionManyBags [ruleCheck (env `extendInScopeListRC` (b:bs)) r + | Alt _ bs r <- as] ruleCheckApp :: RuleCheckEnv -> Expr CoreBndr -> [Arg CoreBndr] -> Bag SDoc ruleCheckApp env (App f a) as = ruleCheck env a `unionBags` ruleCheckApp env f (a:as) @@ -1945,8 +1963,9 @@ ruleAppCheck_help env fn args rules vcat [text "Expression:" <+> ppr (mkApps (Var fn) args), vcat (map check_rule rules)] where - n_args = length args - i_args = args `zip` [1::Int ..] + in_scope = rc_in_scope env + n_args = length args + i_args = args `zip` [1::Int ..] rough_args = map roughTopName args check_rule rule = rule_herald rule <> colon <+> rule_info (rc_ropts env) rule @@ -1976,10 +1995,8 @@ ruleAppCheck_help env fn args rules mismatches = [i | (rule_arg, (arg,i)) <- rule_args `zip` i_args, not (isJust (match_fn rule_arg arg))] - lhs_fvs = exprsFreeVars rule_args -- Includes template tyvars match_fn rule_arg arg = match renv emptyRuleSubst rule_arg arg MRefl where - in_scope = mkInScopeSet (lhs_fvs `unionVarSet` exprFreeVars arg) renv = RV { rv_lcl = mkRnEnv2 in_scope , rv_tmpls = mkVarSet rule_bndrs , rv_fltR = mkEmptySubst in_scope ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -228,13 +228,14 @@ enterRecGroupRHSs env bndrs k (env', r) = k env{soe_rec_ids = extendUnVarSetList bndrs (soe_rec_ids env)} --------------- -simple_opt_clo :: InScopeSet +simple_opt_clo :: HasCallStack + => InScopeSet -> SimpleClo -> OutExpr simple_opt_clo in_scope (e_env, e) = simple_opt_expr (soeSetInScope in_scope e_env) e -simple_opt_expr :: HasCallStack => SimpleOptEnv -> InExpr -> OutExpr +simple_opt_expr :: HasDebugCallStack => SimpleOptEnv -> InExpr -> OutExpr simple_opt_expr env expr = go expr where @@ -397,7 +398,8 @@ simple_app env (Let bind body) args simple_app env e as = finish_app env (simple_opt_expr env e) as -finish_app :: SimpleOptEnv -> OutExpr -> [SimpleClo] -> OutExpr +finish_app :: HasCallStack + => SimpleOptEnv -> OutExpr -> [SimpleClo] -> OutExpr -- See Note [Eliminate casts in function position] finish_app env (Cast (Lam x e) co) as@(_:_) | not (isTyVar x) && not (isCoVar x) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1612,7 +1612,7 @@ tyConAppArgs_maybe ty = case splitTyConApp_maybe ty of Just (_, tys) -> Just tys Nothing -> Nothing -tyConAppArgs :: HasCallStack => Type -> [Type] +tyConAppArgs :: HasDebugCallStack => Type -> [Type] tyConAppArgs ty = tyConAppArgs_maybe ty `orElse` pprPanic "tyConAppArgs" (ppr ty) -- | Attempts to tease a type apart into a type constructor and the application @@ -1652,7 +1652,7 @@ splitTyConAppNoView_maybe ty -- -- Consequently, you may need to zonk your type before -- using this function. -tcSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type]) +tcSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type]) -- Defined here to avoid module loops between Unify and TcType. tcSplitTyConApp_maybe ty = case coreFullView ty of ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2354,45 +2354,49 @@ we are optimizing away 'lazy' (see Note [lazyId magic], and also 'cpeRhsE'.) Then, we could have started with: let x :: () - x = lazy @ () y + x = lazy @() y -which is a perfectly fine, non-trivial thunk, but then CorePrep will -drop 'lazy', giving us 'x = y' which is trivial and impermissible. -The solution is CorePrep to have a miniature inlining pass which deals -with cases like this. We can then drop the let-binding altogether. +which is a perfectly fine, non-trivial thunk, but then CorePrep will drop +'lazy', giving us 'x = y' which is trivial and impermissible. The solution is +CorePrep to have a miniature inlining pass which deals with cases like this. +We can then drop the let-binding altogether. -Why does the removal of 'lazy' have to occur in CorePrep? -The gory details are in Note [lazyId magic] in GHC.Types.Id.Make, but the -main reason is that lazy must appear in unfoldings (optimizer -output) and it must prevent call-by-value for catch# (which -is implemented by CorePrep.) +Why does the removal of 'lazy' have to occur in CorePrep? The gory details +are in Note [lazyId magic] in GHC.Types.Id.Make, but the main reason is that +lazy must appear in unfoldings (optimizer output) and it must prevent +call-by-value for catch# (which is implemented by CorePrep.) -An alternate strategy for solving this problem is to have the -inliner treat 'lazy e' as a trivial expression if 'e' is trivial. -We decided not to adopt this solution to keep the definition -of 'exprIsTrivial' simple. +An alternate strategy for solving this problem is to have the inliner treat +'lazy e' as a trivial expression if 'e' is trivial. We decided not to adopt +this solution to keep the definition of 'exprIsTrivial' simple. There is ONE caveat however: for top-level bindings we have to preserve the binding so that we float the (hacky) non-recursive binding for data constructors; see Note [Data constructor workers]. -Note [CorePrep inlines trivial CoreExpr not Id] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -TODO -Why does cpe_env need to be an IdEnv CoreExpr, as opposed to an -IdEnv Id? Naively, we might conjecture that trivial updatable thunks -as per Note [Inlining in CorePrep] always have the form -'lazy @ SomeType gbl_id'. But this is not true: the following is -perfectly reasonable Core: +Note [CorePrepEnv: cpe_subst] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CorePrepEnv carries a substitution `Subst` in the `cpe_subst1 field, +for these reasons: - let x :: () - x = lazy @ (forall a. a) y @ Bool +1. To support cloning of local Ids so that they are + all unique (see Note [Cloning in CorePrep]) + +2. To support beta-reduction of runRW, see Note [runRW magic] and + Note [runRW arg]. + +3. To let us inline trivial RHSs of non top-level let-bindings, + see Note [lazyId magic], Note [Inlining in CorePrep] (#12076) -When we inline 'x' after eliminating 'lazy', we need to replace -occurrences of 'x' with 'y @ bool', not just 'y'. Situations like -this can easily arise with higher-rank types; thus, cpe_env must -map to CoreExprs, not Ids. + Note that, if (y::forall a. a->a), we could get + x = lazy @(forall a.a) y @Bool + so after eliminating `lazy`, we need to replace occurrences of `x` with + `y @Bool`, not just `y`. Situations like this can easily arise with + higher-rank types; thus, `cpe_subst` must map to CoreExprs, not Ids, which + oc course it does +4. The TyCoVar part of the substitution is used only for + Note [Cloning CoVars and TyVars] -} data CorePrepConfig = CorePrepConfig @@ -2418,23 +2422,9 @@ data CorePrepEnv -- the case where a function we think should bottom -- unexpectedly returns. - , cpe_subst :: Subst - -- ^ The IdEnv part of the substitution is used for three operations: - -- - -- 1. To support cloning of local Ids so that they are - -- all unique (see Note [Cloning in CorePrep]) - -- - -- 2. To support beta-reduction of runRW, see - -- Note [runRW magic] and Note [runRW arg]. - -- - -- 3. To let us inline trivial RHSs of non top-level let-bindings, - -- see Note [lazyId magic], Note [Inlining in CorePrep] - -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) - -- - -- The TyCoVar part of the substitution is used only for - -- Note [Cloning CoVars and TyVars] + , cpe_subst :: Subst -- ^ See Note [CorePrepEnv: cpe_subst] - , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] + , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv ===================================== compiler/GHC/Data/Maybe.hs ===================================== @@ -33,7 +33,7 @@ import Control.Monad.Trans.Maybe import Control.Exception (SomeException(..)) import Data.Maybe import Data.Foldable ( foldlM, for_ ) -import GHC.Utils.Misc (HasCallStack) +import GHC.Utils.Misc (HasDebugCallStack) import Data.List.NonEmpty ( NonEmpty ) import Control.Applicative( Alternative( (<|>) ) ) @@ -66,7 +66,7 @@ firstJustsM = foldlM go Nothing where go Nothing action = action go result@(Just _) _action = return result -expectJust :: HasCallStack => String -> Maybe a -> a +expectJust :: HasDebugCallStack => String -> Maybe a -> a {-# INLINE expectJust #-} expectJust _ (Just x) = x expectJust err Nothing = error ("expectJust " ++ err) ===================================== compiler/GHC/Stg/Subst.hs ===================================== @@ -55,7 +55,7 @@ substBndrs = runState . traverse (state . substBndr) -- | Substitutes an occurrence of an identifier for its counterpart recorded -- in the 'Subst'. -lookupIdSubst :: HasCallStack => Id -> Subst -> Id +lookupIdSubst :: HasDebugCallStack => Id -> Subst -> Id lookupIdSubst id (Subst in_scope env) | not (isLocalId id) = id | Just id' <- lookupVarEnv env id = id' @@ -65,7 +65,7 @@ lookupIdSubst id (Subst in_scope env) -- | Substitutes an occurrence of an identifier for its counterpart recorded -- in the 'Subst'. Does not generate a debug warning if the identifier to -- to substitute wasn't in scope. -noWarnLookupIdSubst :: HasCallStack => Id -> Subst -> Id +noWarnLookupIdSubst :: HasDebugCallStack => Id -> Subst -> Id noWarnLookupIdSubst id (Subst in_scope env) | not (isLocalId id) = id | Just id' <- lookupVarEnv env id = id' ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -2445,7 +2445,7 @@ postfixModTbl ] -- | Lookup `Type` in an association list. -assoc_ty_id :: HasCallStack => String -- The class involved +assoc_ty_id :: HasDebugCallStack => String -- The class involved -> [(Type,a)] -- The table -> Type -- The type -> a -- The result of the lookup ===================================== compiler/GHC/Tc/Deriv/Utils.hs ===================================== @@ -649,7 +649,7 @@ mkDirectThetaSpec origin t_or_k = , sps_type_or_kind = t_or_k }) -substPredSpec :: HasCallStack => Subst -> PredSpec -> PredSpec +substPredSpec :: HasDebugCallStack => Subst -> PredSpec -> PredSpec substPredSpec subst ps = case ps of SimplePredSpec { sps_pred = pred ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -3589,7 +3589,7 @@ data SkolemModeDetails | SMDSkolemTv SkolemInfo -smVanilla :: HasCallStack => SkolemMode +smVanilla :: HasDebugCallStack => SkolemMode smVanilla = SM { sm_clone = panic "sm_clone" -- We always override this , sm_parent = False , sm_tvtv = pprPanic "sm_tvtv" callStackDoc -- We always override this ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -77,6 +77,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Stack import GHC.Utils.Monad +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Types.Unique import GHC.Types.Unique.Supply @@ -327,10 +328,10 @@ data SkolemInfoAnon -- -- We're hoping to be able to get rid of this entirely, but for the moment -- it's still needed. -unkSkol :: HasCallStack => SkolemInfo +unkSkol :: HasDebugCallStack => SkolemInfo unkSkol = SkolemInfo (mkUniqueGrimily 0) unkSkolAnon -unkSkolAnon :: HasCallStack => SkolemInfoAnon +unkSkolAnon :: HasDebugCallStack => SkolemInfoAnon unkSkolAnon = UnkSkol callStack -- | Wrap up the origin of a skolem type variable with a new 'Unique', @@ -895,7 +896,7 @@ pprCtOrigin simple_origin = ctoHerald <+> pprCtO simple_origin -- | Short one-liners -pprCtO :: HasCallStack => CtOrigin -> SDoc +pprCtO :: HasDebugCallStack => CtOrigin -> SDoc pprCtO (OccurrenceOf name) = hsep [text "a use of", quotes (ppr name)] pprCtO (OccurrenceOfRecSel name) = hsep [text "a use of", quotes (ppr name)] pprCtO AppOrigin = text "an application" @@ -960,7 +961,7 @@ pprCtO (AmbiguityCheckOrigin {}) = text "a type ambiguity check" pprCtO (ImpedanceMatching {}) = text "combining required constraints" pprCtO (NonLinearPatternOrigin _ pat) = hsep [text "a non-linear pattern" <+> quotes (ppr pat)] -pprNonLinearPatternReason :: HasCallStack => NonLinearPatternReason -> SDoc +pprNonLinearPatternReason :: HasDebugCallStack => NonLinearPatternReason -> SDoc pprNonLinearPatternReason LazyPatternReason = parens (text "non-variable lazy pattern aren't linear") pprNonLinearPatternReason GeneralisedPatternReason = parens (text "non-variable pattern bindings that have been generalised aren't linear") pprNonLinearPatternReason PatternSynonymReason = parens (text "pattern synonyms aren't linear") ===================================== compiler/GHC/Tc/Types/Origin.hs-boot ===================================== @@ -1,7 +1,7 @@ module GHC.Tc.Types.Origin where import GHC.Prelude.Basic ( Int, Maybe ) -import GHC.Stack ( HasCallStack ) +import GHC.Utils.Misc ( HasDebugCallStack ) import {-# SOURCE #-} GHC.Core.TyCo.Rep ( Type ) data SkolemInfoAnon @@ -16,4 +16,4 @@ data FixedRuntimeRepOrigin mkFRRUnboxedTuple :: Int -> FixedRuntimeRepContext mkFRRUnboxedSum :: Maybe Int -> FixedRuntimeRepContext -unkSkol :: HasCallStack => SkolemInfo +unkSkol :: HasDebugCallStack => SkolemInfo ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -609,7 +609,7 @@ data TcTyVarDetails , mtv_ref :: IORef MetaDetails , mtv_tclvl :: TcLevel } -- See Note [TcLevel invariants] -vanillaSkolemTvUnk :: HasCallStack => TcTyVarDetails +vanillaSkolemTvUnk :: HasDebugCallStack => TcTyVarDetails vanillaSkolemTvUnk = SkolemTv unkSkol topTcLevel False instance Outputable TcTyVarDetails where ===================================== compiler/GHC/Tc/Utils/TcType.hs-boot ===================================== @@ -1,16 +1,16 @@ module GHC.Tc.Utils.TcType where import GHC.Utils.Outputable( SDoc ) +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Prelude ( Bool ) import {-# SOURCE #-} GHC.Types.Var ( TcTyVar ) import {-# SOURCE #-} GHC.Tc.Types.Origin ( FixedRuntimeRepOrigin ) import GHC.Types.Name.Env ( NameEnv ) -import GHC.Stack data MetaDetails data TcTyVarDetails pprTcTyVarDetails :: TcTyVarDetails -> SDoc -vanillaSkolemTvUnk :: HasCallStack => TcTyVarDetails +vanillaSkolemTvUnk :: HasDebugCallStack => TcTyVarDetails isMetaTyVar :: TcTyVar -> Bool isTyConableTyVar :: TcTyVar -> Bool ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -488,7 +488,7 @@ only _ = panic "Util: only" -- | Extract the single element of a list and panic with the given message if -- there are more elements or the list was empty. -- Like 'expectJust', but for lists. -expectOnly :: HasCallStack => String -> [a] -> a +expectOnly :: HasDebugCallStack => String -> [a] -> a {-# INLINE expectOnly #-} #if defined(DEBUG) expectOnly _ [a] = a @@ -511,7 +511,7 @@ changeLast [_] x = [x] changeLast (x:xs) x' = x : changeLast xs x' -- | Like @expectJust msg . nonEmpty@; a better alternative to 'NE.fromList'. -expectNonEmpty :: HasCallStack => String -> [a] -> NonEmpty a +expectNonEmpty :: HasDebugCallStack => String -> [a] -> NonEmpty a {-# INLINE expectNonEmpty #-} expectNonEmpty _ (x:xs) = x:|xs expectNonEmpty msg [] = expectNonEmptyPanic msg ===================================== compiler/GHC/Utils/Word64.hs ===================================== @@ -6,15 +6,16 @@ module GHC.Utils.Word64 ( import GHC.Prelude import GHC.Utils.Panic.Plain (assert) +import GHC.Utils.Misc (HasDebugCallStack) import Data.Word import GHC.Stack -intToWord64 :: HasCallStack => Int -> Word64 +intToWord64 :: HasDebugCallStack => Int -> Word64 intToWord64 x = assert (0 <= x) (fromIntegral x) -word64ToInt :: HasCallStack => Word64 -> Int +word64ToInt :: HasDebugCallStack => Word64 -> Int word64ToInt x = assert (x <= fromIntegral (maxBound :: Int)) (fromIntegral x) truncateWord64ToWord32 :: Word64 -> Word32 -truncateWord64ToWord32 = fromIntegral \ No newline at end of file +truncateWord64ToWord32 = fromIntegral ===================================== config.guess ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-05-25' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +910,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +972,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1068,16 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1191,7 +1232,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1373,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1554,6 +1595,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? ===================================== config.sub ===================================== @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1190,7 +1191,7 @@ case $cpu-$vendor in | arc | arceb | arc32 | arc64 \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ - | asmjs | javascript \ + | asmjs \ | ba \ | be32 | be64 \ | bfin | bpf | bs2000 \ @@ -1199,50 +1200,29 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64eb | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r3 | mipsisa32r3el \ - | mipsisa32r5 | mipsisa32r5el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r3 | mipsisa64r3el \ - | mipsisa64r5 | mipsisa64r5el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ + | nanomips* \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ @@ -1274,6 +1254,7 @@ case $cpu-$vendor in | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ + | vc4 \ | visium \ | w65 \ | wasm32 | wasm64 \ @@ -1285,7 +1266,7 @@ case $cpu-$vendor in ;; *) - echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1287,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1323,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1492,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; esac ;; + aout* | coff* | elf* | pe*) + # These are machine code file formats, not OSes + obj=$os + os= + ;; *) # No normalization, but not necessarily accepted, that comes below. ;; @@ -1528,12 +1520,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1538,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1588,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; - mips*-*) - os=elf + mips*-*|nanomips*-*) + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1614,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1696,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,14 +1719,11 @@ esac fi -# Now, validate our (potentially fixed-up) OS. -case $os in - # GHC specific: added for JS backend support - js | ghcjs) - ;; +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). - # Sometimes we do "kernel-abi", so those need to count as OSes. - musl* | newlib* | relibc* | uclibc*) +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + llvm* | musl* | newlib* | relibc* | uclibc*) ;; # Likewise for "kernel-abi" eabi* | gnueabi*) @@ -1724,6 +1731,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. @@ -1732,7 +1742,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1741,11 +1751,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1758,49 +1768,116 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* | ironclad* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; + # This refers to builds using the UEFI calling convention + # (which depends on the architecture) and PE file format. + # Note that this is both a different calling convention and + # different file format than that of GNU-EFI + # (x86_64-w64-mingw32). + uefi) + ;; none) ;; + kernel* | msvc* ) + # Restricted further below + ;; + '') + if test x"$obj" = x + then + echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) ;; - *-eabi* | *-gnueabi*) + *-eabi*- | *-gnueabi*-) ;; - -*) + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1883,7 +1960,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: ===================================== testsuite/tests/simplCore/should_compile/T24726.hs ===================================== @@ -0,0 +1,26 @@ +{-# OPTIONS_GHC -drule-check concatMap #-} + -- This rule-check thing crashed #24726 + +module T24726 where + +data Stream a = forall s. Stream (s -> ()) s + +concatMapS :: (a -> Stream b) -> Stream a -> Stream b +concatMapS f (Stream next0 s0) = Stream undefined undefined +{-# INLINE [1] concatMapS #-} + +concatMapS' :: (s -> ()) -> (a -> s) -> Stream a -> Stream b +concatMapS' = undefined + +{-# RULES "concatMap" forall step f. concatMapS (\x -> Stream step (f x)) = concatMapS' step f #-} + +replicateStep :: a -> b +replicateStep _ = undefined +{-# INLINE replicateStep #-} + +replicateS :: Int -> a -> Stream a +replicateS n x0 = Stream replicateStep undefined +{-# INLINE replicateS #-} + +foo1 :: Stream Int -> Stream Int +foo1 = concatMapS (replicateS 2) ===================================== testsuite/tests/simplCore/should_compile/T24726.stderr ===================================== @@ -0,0 +1,36 @@ + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + + +==================== Rule check ==================== +Rule check results: +-------------------- +Expression: concatMapS @(*) @Int @Int foo1 +Rule "concatMap": all arguments match (considered individually), but rule as a whole does not +-------------------- + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -514,3 +514,4 @@ test('T24229a', [ grep_errmsg(r'wfoo') ], compile, ['-O2 -ddump-simpl -dno-typea test('T24229b', [ grep_errmsg(r'wfoo') ], compile, ['-O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques -dppr-cols=99999']) test('T24370', normal, compile, ['-O']) test('T24551', normal, compile, ['-O -dcore-lint']) +test('T24726', normal, compile, ['-dcore-lint -dsuppress-uniques']) ===================================== utils/vagrant/bootstrap-deb.sh deleted ===================================== @@ -1,3 +0,0 @@ -#!/bin/sh -apt-get update -apt-get build-dep -y ghc ===================================== utils/vagrant/bootstrap-rhel.sh deleted ===================================== @@ -1,4 +0,0 @@ -#!/bin/sh -yum update -y -yum install -y glibc-devel ncurses-devel gmp-devel autoconf automake libtool \ - gcc make python ghc git View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d5d664bd5ad70c26d169c8df8389d9f8c547ddb6...db5176aeb21438dc53d2ad4684fb4fb1ce3c3a77 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d5d664bd5ad70c26d169c8df8389d9f8c547ddb6...db5176aeb21438dc53d2ad4684fb4fb1ce3c3a77 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 20:34:34 2024 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 30 Apr 2024 16:34:34 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/T24736-epa-prefixcon-comments Message-ID: <663155da41773_2d9bfc4080cb02402ab@gitlab.mail> Alan Zimmerman pushed new branch wip/az/T24736-epa-prefixcon-comments at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/T24736-epa-prefixcon-comments You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 30 21:23:24 2024 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 30 Apr 2024 17:23:24 -0400 Subject: [Git][ghc/ghc][wip/T24726] Use HasDebugCallStack, rather than HasCallStack Message-ID: <6631614c98c20_2d9bfc478cc34249124@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24726 at Glasgow Haskell Compiler / GHC Commits: 023ffbb9 by Simon Peyton Jones at 2024-04-30T22:23:00+01:00 Use HasDebugCallStack, rather than HasCallStack - - - - - 16 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Stg/Subst.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Utils.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Types/Origin.hs-boot - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/TcType.hs-boot - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Word64.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -483,7 +483,7 @@ isOffsetImm off w -- TODO OPT: we might be able give getRegister -- a hint, what kind of register we want. -getFloatReg :: HasCallStack => CmmExpr -> NatM (Reg, Format, InstrBlock) +getFloatReg :: HasDebugCallStack => CmmExpr -> NatM (Reg, Format, InstrBlock) getFloatReg expr = do r <- getRegister expr case r of ===================================== compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs ===================================== @@ -8,11 +8,11 @@ import GHC.Platform.Reg import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Platform import Data.Word -import GHC.Stack -- AArch64 has 32 64bit general purpose register r0..r30, and zr/sp -- AArch64 has 32 128bit floating point registers v0..v31 as part of the NEON -- extension in Armv8-A. @@ -65,7 +65,7 @@ showBits :: Word32 -> String showBits w = map (\i -> if testBit w i then '1' else '0') [0..31] -- FR instance implementation (See Linear.FreeRegs) -allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +allocateReg :: HasDebugCallStack => RealReg -> FreeRegs -> FreeRegs allocateReg (RealRegSingle r) (FreeRegs g f) | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32)) | r < 32 && testBit g r = FreeRegs (clearBit g r) f @@ -127,7 +127,7 @@ getFreeRegs cls (FreeRegs g f) initFreeRegs :: Platform -> FreeRegs initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs platform) -releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +releaseReg :: HasDebugCallStack => RealReg -> FreeRegs -> FreeRegs releaseReg (RealRegSingle r) (FreeRegs g f) | r > 31 && testBit f (r - 32) = pprPanic "Linear.AArch64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32)) | r < 32 && testBit g r = pprPanic "Linear.AArch64.releaseReg" (text "can't release non-allocated reg x" <> int r) ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -2360,7 +2360,7 @@ addWeakFVs dmd_ty weak_fvs -- L demand doesn't get both'd with the Bot coming up from the inner -- call to f. So we just get an L demand for x for g. -setBndrsDemandInfo :: HasCallStack => [Var] -> [Demand] -> [Var] +setBndrsDemandInfo :: HasDebugCallStack => [Var] -> [Demand] -> [Var] setBndrsDemandInfo (b:bs) ds | isTyVar b = b : setBndrsDemandInfo bs ds setBndrsDemandInfo (b:bs) (d:ds) = ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -235,7 +235,7 @@ simple_opt_clo :: HasCallStack simple_opt_clo in_scope (e_env, e) = simple_opt_expr (soeSetInScope in_scope e_env) e -simple_opt_expr :: HasCallStack => SimpleOptEnv -> InExpr -> OutExpr +simple_opt_expr :: HasDebugCallStack => SimpleOptEnv -> InExpr -> OutExpr simple_opt_expr env expr = go expr where ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1612,7 +1612,7 @@ tyConAppArgs_maybe ty = case splitTyConApp_maybe ty of Just (_, tys) -> Just tys Nothing -> Nothing -tyConAppArgs :: HasCallStack => Type -> [Type] +tyConAppArgs :: HasDebugCallStack => Type -> [Type] tyConAppArgs ty = tyConAppArgs_maybe ty `orElse` pprPanic "tyConAppArgs" (ppr ty) -- | Attempts to tease a type apart into a type constructor and the application @@ -1652,7 +1652,7 @@ splitTyConAppNoView_maybe ty -- -- Consequently, you may need to zonk your type before -- using this function. -tcSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type]) +tcSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type]) -- Defined here to avoid module loops between Unify and TcType. tcSplitTyConApp_maybe ty = case coreFullView ty of ===================================== compiler/GHC/Data/Maybe.hs ===================================== @@ -33,7 +33,7 @@ import Control.Monad.Trans.Maybe import Control.Exception (SomeException(..)) import Data.Maybe import Data.Foldable ( foldlM, for_ ) -import GHC.Utils.Misc (HasCallStack) +import GHC.Utils.Misc (HasDebugCallStack) import Data.List.NonEmpty ( NonEmpty ) import Control.Applicative( Alternative( (<|>) ) ) @@ -66,7 +66,7 @@ firstJustsM = foldlM go Nothing where go Nothing action = action go result@(Just _) _action = return result -expectJust :: HasCallStack => String -> Maybe a -> a +expectJust :: HasDebugCallStack => String -> Maybe a -> a {-# INLINE expectJust #-} expectJust _ (Just x) = x expectJust err Nothing = error ("expectJust " ++ err) ===================================== compiler/GHC/Stg/Subst.hs ===================================== @@ -55,7 +55,7 @@ substBndrs = runState . traverse (state . substBndr) -- | Substitutes an occurrence of an identifier for its counterpart recorded -- in the 'Subst'. -lookupIdSubst :: HasCallStack => Id -> Subst -> Id +lookupIdSubst :: HasDebugCallStack => Id -> Subst -> Id lookupIdSubst id (Subst in_scope env) | not (isLocalId id) = id | Just id' <- lookupVarEnv env id = id' @@ -65,7 +65,7 @@ lookupIdSubst id (Subst in_scope env) -- | Substitutes an occurrence of an identifier for its counterpart recorded -- in the 'Subst'. Does not generate a debug warning if the identifier to -- to substitute wasn't in scope. -noWarnLookupIdSubst :: HasCallStack => Id -> Subst -> Id +noWarnLookupIdSubst :: HasDebugCallStack => Id -> Subst -> Id noWarnLookupIdSubst id (Subst in_scope env) | not (isLocalId id) = id | Just id' <- lookupVarEnv env id = id' ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -2445,7 +2445,7 @@ postfixModTbl ] -- | Lookup `Type` in an association list. -assoc_ty_id :: HasCallStack => String -- The class involved +assoc_ty_id :: HasDebugCallStack => String -- The class involved -> [(Type,a)] -- The table -> Type -- The type -> a -- The result of the lookup ===================================== compiler/GHC/Tc/Deriv/Utils.hs ===================================== @@ -649,7 +649,7 @@ mkDirectThetaSpec origin t_or_k = , sps_type_or_kind = t_or_k }) -substPredSpec :: HasCallStack => Subst -> PredSpec -> PredSpec +substPredSpec :: HasDebugCallStack => Subst -> PredSpec -> PredSpec substPredSpec subst ps = case ps of SimplePredSpec { sps_pred = pred ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -3589,7 +3589,7 @@ data SkolemModeDetails | SMDSkolemTv SkolemInfo -smVanilla :: HasCallStack => SkolemMode +smVanilla :: HasDebugCallStack => SkolemMode smVanilla = SM { sm_clone = panic "sm_clone" -- We always override this , sm_parent = False , sm_tvtv = pprPanic "sm_tvtv" callStackDoc -- We always override this ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -77,6 +77,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Stack import GHC.Utils.Monad +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Types.Unique import GHC.Types.Unique.Supply @@ -327,10 +328,10 @@ data SkolemInfoAnon -- -- We're hoping to be able to get rid of this entirely, but for the moment -- it's still needed. -unkSkol :: HasCallStack => SkolemInfo +unkSkol :: HasDebugCallStack => SkolemInfo unkSkol = SkolemInfo (mkUniqueGrimily 0) unkSkolAnon -unkSkolAnon :: HasCallStack => SkolemInfoAnon +unkSkolAnon :: HasDebugCallStack => SkolemInfoAnon unkSkolAnon = UnkSkol callStack -- | Wrap up the origin of a skolem type variable with a new 'Unique', @@ -895,7 +896,7 @@ pprCtOrigin simple_origin = ctoHerald <+> pprCtO simple_origin -- | Short one-liners -pprCtO :: HasCallStack => CtOrigin -> SDoc +pprCtO :: HasDebugCallStack => CtOrigin -> SDoc pprCtO (OccurrenceOf name) = hsep [text "a use of", quotes (ppr name)] pprCtO (OccurrenceOfRecSel name) = hsep [text "a use of", quotes (ppr name)] pprCtO AppOrigin = text "an application" @@ -960,7 +961,7 @@ pprCtO (AmbiguityCheckOrigin {}) = text "a type ambiguity check" pprCtO (ImpedanceMatching {}) = text "combining required constraints" pprCtO (NonLinearPatternOrigin _ pat) = hsep [text "a non-linear pattern" <+> quotes (ppr pat)] -pprNonLinearPatternReason :: HasCallStack => NonLinearPatternReason -> SDoc +pprNonLinearPatternReason :: HasDebugCallStack => NonLinearPatternReason -> SDoc pprNonLinearPatternReason LazyPatternReason = parens (text "non-variable lazy pattern aren't linear") pprNonLinearPatternReason GeneralisedPatternReason = parens (text "non-variable pattern bindings that have been generalised aren't linear") pprNonLinearPatternReason PatternSynonymReason = parens (text "pattern synonyms aren't linear") ===================================== compiler/GHC/Tc/Types/Origin.hs-boot ===================================== @@ -1,7 +1,7 @@ module GHC.Tc.Types.Origin where import GHC.Prelude.Basic ( Int, Maybe ) -import GHC.Stack ( HasCallStack ) +import GHC.Utils.Misc ( HasDebugCallStack ) import {-# SOURCE #-} GHC.Core.TyCo.Rep ( Type ) data SkolemInfoAnon @@ -16,4 +16,4 @@ data FixedRuntimeRepOrigin mkFRRUnboxedTuple :: Int -> FixedRuntimeRepContext mkFRRUnboxedSum :: Maybe Int -> FixedRuntimeRepContext -unkSkol :: HasCallStack => SkolemInfo +unkSkol :: HasDebugCallStack => SkolemInfo ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -609,7 +609,7 @@ data TcTyVarDetails , mtv_ref :: IORef MetaDetails , mtv_tclvl :: TcLevel } -- See Note [TcLevel invariants] -vanillaSkolemTvUnk :: HasCallStack => TcTyVarDetails +vanillaSkolemTvUnk :: HasDebugCallStack => TcTyVarDetails vanillaSkolemTvUnk = SkolemTv unkSkol topTcLevel False instance Outputable TcTyVarDetails where ===================================== compiler/GHC/Tc/Utils/TcType.hs-boot ===================================== @@ -1,16 +1,16 @@ module GHC.Tc.Utils.TcType where import GHC.Utils.Outputable( SDoc ) +import GHC.Utils.Misc( HasDebugCallStack ) import GHC.Prelude ( Bool ) import {-# SOURCE #-} GHC.Types.Var ( TcTyVar ) import {-# SOURCE #-} GHC.Tc.Types.Origin ( FixedRuntimeRepOrigin ) import GHC.Types.Name.Env ( NameEnv ) -import GHC.Stack data MetaDetails data TcTyVarDetails pprTcTyVarDetails :: TcTyVarDetails -> SDoc -vanillaSkolemTvUnk :: HasCallStack => TcTyVarDetails +vanillaSkolemTvUnk :: HasDebugCallStack => TcTyVarDetails isMetaTyVar :: TcTyVar -> Bool isTyConableTyVar :: TcTyVar -> Bool ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -488,7 +488,7 @@ only _ = panic "Util: only" -- | Extract the single element of a list and panic with the given message if -- there are more elements or the list was empty. -- Like 'expectJust', but for lists. -expectOnly :: HasCallStack => String -> [a] -> a +expectOnly :: HasDebugCallStack => String -> [a] -> a {-# INLINE expectOnly #-} #if defined(DEBUG) expectOnly _ [a] = a @@ -511,7 +511,7 @@ changeLast [_] x = [x] changeLast (x:xs) x' = x : changeLast xs x' -- | Like @expectJust msg . nonEmpty@; a better alternative to 'NE.fromList'. -expectNonEmpty :: HasCallStack => String -> [a] -> NonEmpty a +expectNonEmpty :: HasDebugCallStack => String -> [a] -> NonEmpty a {-# INLINE expectNonEmpty #-} expectNonEmpty _ (x:xs) = x:|xs expectNonEmpty msg [] = expectNonEmptyPanic msg ===================================== compiler/GHC/Utils/Word64.hs ===================================== @@ -6,15 +6,15 @@ module GHC.Utils.Word64 ( import GHC.Prelude import GHC.Utils.Panic.Plain (assert) +import GHC.Utils.Misc (HasDebugCallStack) import Data.Word -import GHC.Stack -intToWord64 :: HasCallStack => Int -> Word64 +intToWord64 :: HasDebugCallStack => Int -> Word64 intToWord64 x = assert (0 <= x) (fromIntegral x) -word64ToInt :: HasCallStack => Word64 -> Int +word64ToInt :: HasDebugCallStack => Word64 -> Int word64ToInt x = assert (x <= fromIntegral (maxBound :: Int)) (fromIntegral x) truncateWord64ToWord32 :: Word64 -> Word32 -truncateWord64ToWord32 = fromIntegral \ No newline at end of file +truncateWord64ToWord32 = fromIntegral View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/023ffbb9bb303c7b90219a96b13512b3736c39a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/023ffbb9bb303c7b90219a96b13512b3736c39a1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: